Giter Site home page Giter Site logo

ble_ctf's Introduction

Follow Hackgnar

BLE Capture the Flag

The purpose of BLE CTF is to teach the core concepts of Bluetooth Low Energy client and server interactions. While it has also been built to be fun, it was built with the intent to teach and reinforce core concepts that are needed to plunge into the world of Bluetooth hacking. After completing this CTF, you should have everything you need to start fiddling with any BLE GATT device you can find.

Setting Up the CTF

In order to set up the CTF you will need the following:

  1. The pre-compiled firmware or source code in this repository to build and flash an ESP32 with the CTF GATT server.
  2. An esp32 microcontroller (I sell overpriced pre-flashed ones here)
  3. A Linux box (OSX/Win + Linux VM works) with a bluetooth controller or a bluetooth usb dongle
  4. Bluetooth tools such as Bluez tools (hcitool, gatttool, etc) or bleah

For instructions to compile/flash your own firmware or flash the provided pre-compiled firmware read this documentation

Flags

How to Submit Flags

Before you can submit flags, you have to discover the Bluetooth MAC address of your device. Here are a couple example commands to help you find your device:

Discover MAC using hcitool:
sudo hcitool lescan

Discover MAC using bleah:
sudo bleah

Now that you have found your device’s MAC address, you can now communicate with it. Before we get started with flags, let’s check out how we can see our current score. In order to see where you are in the CTF, you can read from handle 42 on the device to see how many flags you have. The following are example commands of how to view your current score. Make sure you replace the MAC address in the example commands with the MAC address of your device.

Show score with gatttool:
gatttool -b de:ad:be:ef:be:f1 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'

Show score with bleah:
sudo bleah -b "30:ae:a4:20:79:da" -e

Ok, ok, ok, on to the flags! All flags are md5 sums truncated to 20 characters to avoid MTU limits by some hardware. They can be submitted to the gatt server on handle 44. The following are examples of how to submit a flag. Make sure you replace the MAC address in the example commands with the MAC address of your device:

Submit using gatttool:
gatttool -b de:ad:be:ef:be:f1 --char-write-req -a 0x002c -n $(echo -n "some flag value"|xxd -ps)

Submit using bleah:
sudo bleah -b "30:ae:a4:20:79:da" -n 0x002c -d "some flag value"

Flag Hints

Flag Description Hint
Flag 1 This flag is a gift and can only be obtained from reading the hint! Read Me!
Flag 0x002e Learn how to read handles More
Flag 0x0030 Read handle puzzle fun More
Flag 0x0016 Learn about discoverable device attributes More
Flag 0x0032 Learn about reading and writing to handles More
Flag 0x0034 Learn about reading and writing ascii to handles More
Flag 0x0036 Learn about reading and writing hex to handles More
Flag 0x0038 Learn about reading and writing to handles differently More
Flag 0x003c Learn about write fuzzing More
Flag 0x003e Learn about read and write speeds More
Flag 0x0040 Learn about single response notifications More
Flag 0x0042 Learn about single response indicate More
Flag 0x0046 Learn about multi response notifications More
Flag 0x0048 Learn about multi response indicate More
Flag 0x004c Learn about BT client device attributes More
Flag 0x004e Learn about message sizes MTU More
Flag 0x0050 Learn about write responses More
Flag 0x0052 Hidden notify property More
Flag 0x0054 Use multiple handle properties More
Flag 0x0056 OSINT the author! More

ble_ctf's People

Contributors

bostrt avatar hackgnar avatar mtausig avatar timgates42 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ble_ctf's Issues

What is the purpose of BLE CTF?

YOUR README SAYS:

The purpose of BLE CTF is to teach the core concepts of Bluetooth Low Energy client and server interactions.

Do you think this is true? I think it might be different.

Flag 10 Problem

When i got up to Flag 10, the flag is already there without me solving anything. Is that an intended event or a side effect of completing flags 1-9?

hcitool blescan command is incorrect

In the Flags section, the initial command for obtaining the target MAC address is incorrect, not sure if its changed between hcitool versions. Instead of sudo hcitool blescan it should read sudo hcitool lescan

Modern Bluetooth (>=5.0) doesn't work with hcitools

The instructions about hcitools don't work with Bluetooth versions 5.0 and greater, which is what's included in newer hardware. The bluetoothctl tool can do most of it, and supports Bluetooth 4.0 (the minimum hardware version for the lab).

Suggested improvements

I did most of the challenges on a mobile phone using Nordic's nRF Connect. Reading the first hint, it said to send a payload to a specific handle? Which was confusing until I realsied it was specific to Linux and how gatttool works.

Instead, may I suggest you introduce the concept of UUIDs and how each characteristic on a service has incrementing numbers based on the Services' UUID?

A new flag idea wcould be to challenge the player to identify a 16bit UUID and send a payload that conforms to that standard, Like setting the time with a UUID of 0x1805 (Current Time Service)

You could use that as an opportunity to perform OSINT on GATT UUIDs.

Another idea is to set up a BLE beacon and using a tool like RamBLE to locate the beacon and read the flag from the advertised data.

Flashing issues

  • Development Kit: [ESP32-DevKitC]
  • Kit version unknown
  • Module or chip used: [ESP32-WROOM-32]
  • IDF version v3.1.2
  • Build System: [Make]
  • Compiler version // 1.22.0-80-g6c4433a
  • Operating System: [Linux]
  • Power Supply: [USB]

printenv PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/esp/xtensa-esp32-elf/bin

Problem Description

When I make flash I get
CC build/bootloader/bootloader_support/src/bootloader_flash.o
/root/esp/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/as: error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory
make[2]: *** [/root/esp/esp-idf/make/component_wrapper.mk:286: src/bootloader_flash.o] Error 1
make[1]: *** [/root/esp/esp-idf/make/project.mk:468: component-bootloader_support-build] Error 2
make: *** [/root/esp/esp-idf/components/bootloader/Makefile.projbuild:41: /root/esp/ble_ctf/build/bootloader/bootloader.bin] Error 2

!!!SPOILER!!! Flag 3 Bug?

The hint for flag 3 was:

root@kali-vm:~# gatttool -b b4:E6:2d:96:14:7F --char-read -a 0x0030
Characteristic value/descriptor: 4d 44 35 20 6f 66 20 44 65 76 69 63 65 20 4e 61 6d 6
root@kali-vm:~# echo -n "4d 44 35 20 6f 66 20 44 65 76 69 63 65 20 4e 61 6d 65" | tr -d ' ' | xxd -r -p
MD5 of Device Name

So retrieving the device name and md5sum'ing it, and submitting the first 20 characters doesn't get the flag:

root@kali-vm:~# gatttool -b b4:E6:2d:96:14:7F --char-read --handle=0x0016
Characteristic value/descriptor: 32 62 30 30 30 34 32 66 37 34 38 31 63 37 62 30 35 36 63 34 62 34 31 30 64 32 38 66 33 33 63 66
root@kali-vm:~# echo -n "32 62 30 30 30 34 32 66 37 34 38 31 63 37 62 30 35 36 63 34 62 34 31 30 64 32 38 66 33 33 63 66" | tr -d " " | xxd -r -p
2b00042f7481c7b056c4b410d28f33cf
root@kali-vm:~# echo -n 2b00042f7481c7b056c4b410d28f33cf | md5sum
8489c638085eb7b7416e682af1dd5474  -
root@kali-vm:~# gatttool -b b4:E6:2d:96:14:7F --char-write-req -a 0x002c -n $(echo -n "8489c638085eb7b7416e"|xxd -ps)
Characteristic value was written successfully
root@tuv-kali-vm:~# gatttool -b b4:E6:2d:96:14:7F --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:2 /20

However, ignoring the clue "MD5 of Device Name", and just returning exactly the hex version of the device name, not md5sum'ing anything, we get the flag:

root@kali-vm:~# gatttool -b b4:E6:2d:96:14:7F --char-write-req -a 0x002c -n $(echo -n "2b00042f7481c7b056c4"|xxd -ps)
Characteristic value was written successfully
root@kali-vm:~# gatttool -b b4:E6:2d:96:14:7F --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:3 /20

I think this is a bug? Or at the very least a misleading clue?

make error

z@ubuntu:~/esp/ble_ctf$ make 
Toolchain path: /home/z/esp/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc
Toolchain version: esp32-2019r1
Compiler version: 8.2.0
Python requirements from /home/z/esp/esp-idf/requirements.txt are satisfied.

App "gatt_server_service_table_demo" version: 1.0-3-g1e85408
CC build/main/gatts_table_creat_demo.o
/home/z/esp/ble_ctf/main/gatts_table_creat_demo.c:193:22: error: 'char_value' defined but not used [-Werror=unused-const-variable=]
 static const uint8_t char_value[4]                 = {0x11, 0x22, 0x33, 0x44};
                      ^~~~~~~~~~
/home/z/esp/ble_ctf/main/gatts_table_creat_demo.c:192:22: error: 'heart_measurement_ccc' defined but not used [-Werror=unused-const-variable=]
 static const uint8_t heart_measurement_ccc[2]      = {0x00, 0x00};
                      ^~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
/home/z/esp/esp-idf/make/component_wrapper.mk:289: recipe for target 'gatts_table_creat_demo.o' failed
make[1]: *** [gatts_table_creat_demo.o] Error 1
/home/z/esp/esp-idf/make/project.mk:582: recipe for target 'component-main-build' failed
make: *** [component-main-build] Error 2
z@ubuntu:~/esp/ble_ctf$ grep -nr char_value
main/gatts_table_creat_demo.c:193:static const uint8_t char_value[4]                 = {0x11, 0x22, 0x33, 0x44};
z@ubuntu:~/esp/ble_ctf$ grep -nr heart_measurement_ccc
main/gatts_table_creat_demo.c:192:static const uint8_t heart_measurement_ccc[2]      = {0x00, 0x00};
z@ubuntu:~/esp/ble_ctf$ xtensa-esp32-elf-gcc --version
xtensa-esp32-elf-gcc (crosstool-NG esp32-2019r1) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

we may nop this two unused-const-variable.

Configure gatttool In Kali?

I was wondering if you might know if there is anything special you have to do in order to get gatttool to play nice with Kali Linux?

I'm able to use hcitool to lescan, find my device. When I try to use gatttool I get a connection refused error:

root@kali-vm:~# gatttool -b b4:e6:2d:96:14:7F --char-read -a 0x002a
connect: Connection refused (111)
root@kali-vm:~# gatttool --adapter=hci1 -I
[                 ][LE]> connect b4:e6:2d:96:14:7F
Attempting to connect to b4:e6:2d:96:14:7F
Error: connect: Connection refused (111)

I am able to connect to the device and read GATT data using nRF Connect from an Android device, so the device itself seems to be working fine. I also made sure my Android device was disconnected and bluetooth was disabled before trying to connect from Kali.

Any pointers on getting this set up right?

gatts_table_creat_demo.c:25:29: fatal error

Encountered during make step of flashing process.

/ble_ctf# make
Toolchain path: /root/esp/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc
Toolchain version: crosstool-ng-1.22.0-80-g6c4433a
Compiler version: 5.2.0
Python requirements from /root/esp/esp-idf/requirements.txt are satisfied.

App "gatt_server_service_table_demo" version: 1.0-5-g366122b
CC build/main/gatts_table_creat_demo.o
/root/Addons/ble_ctf/main/gatts_table_creat_demo.c:25:29: fatal error: esp_gap_ble_api.h: No such file or directory
compilation terminated.
make[1]: *** [/root/esp/esp-idf/make/component_wrapper.mk:290: gatts_table_creat_demo.o] Error 1
make: *** [/root/esp/esp-idf/make/project.mk:552: component-main-build] Error 2

recipe for target 'component-main-build' failed

esp/ble_ctf/main/gatts_table_creat_demo.c:25:10: fatal error: esp_gap_ble_api.h: No such file or directory
#include "esp_gap_ble_api.h"

  1. My bluetooth device is enable
  2. and all compiled properly

Writes don't work if more than 20 bytes written

I know it says that flags are truncated to 20 characters and I see that in the source code, but I don't think it's clear that you must truncate flags to 20 characters (at least on some devices).
If I transmit the full md5 to flag 3 and view the console I see this:
I (458161) ESP_GATTS_DEMO: ESP_GATTS_WRITE_EVT
I (458161) ESP_GATTS_DEMO: PREPARE WRITE TRIGGERED
I (458161) ESP_GATTS_DEMO: prepare write, handle = 44, value len = 18
I (458241) ESP_GATTS_DEMO: ESP_GATTS_WRITE_EVT
I (458241) ESP_GATTS_DEMO: PREPARE WRITE TRIGGERED
I (458241) ESP_GATTS_DEMO: prepare write, handle = 44, value len = 14

In fact anything over 20 characters is transmitted as two writes, so 18 and 4 for 22 characters for example, meaning nothing over 20 characters gets recognised as a correct flag.
If I write exactly 20 characters then it works fine.

$ hciconfig hci0
hci0: Type: Primary Bus: USB
BD Address: xx:xx... ACL MTU: 1021:4 SCO MTU: 96:6

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.