Exploiting 0-click Android Bluetooth vulnerability to inject keystrokes without pairing

Exploiting 0-click Android Bluetooth vulnerability to inject keystrokes without pairing

Loading

[update 2024-02-19]

This vulnerability can be even used to remotely wipe data of targeted Android smartphone. Using this vulnerability it is possible to guess user lock screen PIN. After five incorrect PINs device is locked out for 30 seconds. This operation results in locking user out of its device in a loop. If Auto factory reset is enabled, then the attack ends in erasing all user data after 20 incorrect attempts to unlock phone.
Auto factory reset setting will reset to factory default settings and all data will be erased, including files and downloaded apps after 20 incorrect attempts to unlock phone.

[update 2024-01-29]

CVE-2023-45866 vulnerability also affects unpatched Android and Linux based Smart TVs that have Bluetooth interface. This applies for devices running Linux based webOS or Google Chromecast TV version 3. By exploiting unpatched Chromecast, it is possible to turn on the TV via Chromecast dongle and inject keystrokes. Smart TV running webOS after running PoC exploit displayed pop-up with the name of connected device and allowed keystroke injection. Most likely there are also affected outdated Fire TVs running Android and other Android TV boxes. Based on my tests, if the PoC script wont crash, then target is vulnerable.

It is also important to note that an attacker needs to know Bluetooth MAC address to perform exploitation. Chromecast broadcasts Bluetooth MAC address only if it is in paring mode. Television running webOS broadcasts Bluetooth MAC address all the time when TV is turned on, so it isn’t necessary to be in pairing mode. This means it is easier to obtain the MAC and take over TV in the vicinity. You can see the demonstration in the video below.

A recently discovered critical vulnerabilities (CVE-2023-45866, CVE-2024-21306) in Bluetooth can be exploited to inject keystrokes without user confirmation – by accepting any Bluetooth pairing request. These vulnerabilities affect Android, Linux, macOS, iOS, and Windows operating systems, making it a serious threat to users across different platforms. The vulnerabilities were discovered by Marc Newlin, that also published prove-of-concept exploitation scripts. Using these scripts, it is possible to inject keystrokes to any unpatched Android and Linux device in Bluetooth proximity by impersonating Bluetooth keyboard. Such Bluetooth keyboard will force pairing a targeted device without any user interaction or notification, making this 0-click exploit. In this blog, I will focus on exploiting unpatched Android device using Android smartphone. I will not cover another mobile platform – iOS – since exploitation scenario is difficult and requires Magic Keyboard and exact timing. In this case, timing is a specific moment when an attacker needs to connect to iOS at the time when iOS user tries to connect to Magic Keyboard. Attacker can also connect to iOS by spoofing Magic Keyboard, however keyboard needs to be out of Bluetooth range and attacker still needs to know MAC address of Bluetooth Magic Keyboard, which in real case scenario will be challenging. If you are interested in more details of this vulnerabilities that target Linux, macOS, iOS and Windows, I advise you to read the original blog.

Vulnerable devices

The list of all known affected operating systems is Table 1 below.

Android4.2, 5, 6, 7, 8, 9, 10CVE-2023-45866no fix availableAndroid 3 and earlier were not tested
Android11, 12, 13, 14CVE-2023-45866fixed in 2023-12-05 security patch level
Linux (BlueZ)Affected DistrosCVE-2023-45866BlueZ patch available
macOS12, 13CVE-2023-45866no fix availablemacOS 11 and earlier were not tested
macOS14CVE-2023-45866fixed in macOS 14.2
iOS16CVE-2023-45866no fix availableiOS 15 and earlier were not tested
iOS17CVE-2023-45866fixed in iOS 17.2
Windows10, 11, Server 2022CVE-2024-21306fixed in January 2024 Patch Tuesdayearlier versions of Windows were not tested
Table 1. Known affected versions (source: https://github.com/skysafe/reblog/blob/main/cve-2024-0230/README.md)

From Android point of view, the above table illustrates that Android up to version 10 is vulnerable and fix is not available. If you are running Android 11 and higher, you might be still vulnerable without 2023-12-05 security patch.

Exploitation prerequisites

I will use rooted Android smartphone (OnePlus 7 Pro) flashed with custom NetHunter Kernel that supports Bluetooth scanning using built-in Bluetooth chipset. It is also possible to use external Bluetooth dongle connected to Android using OTG adapter, however, Kernel support is essential.

How to discover Android devices

The Android vulnerability is 0-click, and unpatched devices can be exploited whenever Bluetooth is enabled. This vulnerability is in classic Bluetooth technology, not in Bluetooth Low Energy (BLE) protocol. This means, that if we want to exploit Android device, we first need to discover it to obtain its Bluetooth MAC address. BLE devices periodically broadcast advertisement packets, so other devices are aware of them. To discover Android device with classic Bluetooth, device needs to be in discoverable mode, otherwise devices in vicinity can’t detect it. To enable discoverable mode, user needs to open Bluetooth options in Settings, so its Bluetooth MAC address can be disclosed to other devices and, in our case, to an attacker. With MAC address of targeted vulnerable device, it is then possible to inject any keystrokes to take over target, which makes this a Bluetooth HID attack scenario. If you want to know more about HID attacks, feel free to read ultimate guide to HID attacks using Rubber Ducky scripts and Bad USB MITM attack.

Exploitation

To find Bluetooth devices and their MAC address, I will use Kali NetHunter Bluetooth Arsenal menu, as visible in Figure 1. If you are interested in more details and usage of Bluetooth Arsenal, check my previous blog on this topic.

Figure 1. Scanning for Bluetooth devices

Once we have MAC address of our tested target, we can proceed by cloning exploitation scripts from GitHub using command:

git clone https://github.com/marcnewlin/hi_my_name_is_keyboard.git

You also need to install pydbus library using command:

pip3 install pydbus

Enter newly cloned directory and run the keystroke-injection-android-linux.py script. As an input, you need to specify Bluetooth interface (-i). I am using internal (hci0) chipset, or you can use external (hci1) adapter. As a target (-t) enter MAC address of aimed testing device. By default, the script will inject set of Tabulator key presses.

./keystroke-injection-android-linux.py -i hci0 -t 22:22:42:E6:DD:A8

The console output might look something like in Figure 2.

Figure 2. Console output after successful keypress injection

You can watch the whole attack scenario in the video below, where I will find targeted smartphone and rickroll it.

Takeover device with Metasploit payload

This critical vulnerability can be more dangerous where the attacker could take over targeted device by remotely installing spyware application. What I mean is to open browser, download, install and execute payload that would backdoor the smartphone over Bluetooth without any user interaction. In the video below you can see demonstration of installing Metasploit payload that is for simplicity hosted on local network.

This case scenario can happen only if device is unlocked or doesn’t have any lock screen protection.

Restrict access to targeted device

Both previous cases required device to be unlocked or without any lock screen protection such as PIN, password, or pattern. What could be done if device has enabled PIN? Well, attacker can remotely try to brute-force the PIN until device gets locked. This is under assumption that correct PIN will not be guessed. By default, after five wrong PINs, Android device is locked for 30 seconds. Following five more wrong attempts device is locked for another 30 seconds. Then it gets worse, because after each wrong PIN is 30 seconds timeout. After altogether 41 bad attempts, timeout increases to 60 seconds for each incorrect try. This brute-forcing can be repeated in a loop to make the device unusable, since injected keypresses are typed faster then user taps to unlock device. In the video below I was able to lock user out of device for 30 seconds.

Stay safe       

If you are running Android 11 and above, the best course of action is to patch your device, of course if the OEM has already pushed Android’s 2023-12-05 security patch. If not, you will have to wait.

If you have Android 10 and below, the security patch is unfortunately not available, and based on the original Marc Newlin post, it will not be patched.

The good news is that an attacker in the vicinity cannot automatically receive the Bluetooth MAC address of Android devices. It is possible only if the device is in discoverable mode. In case the attacker already has the MAC address and the device is not patched, the safest thing to do is to turn off Bluetooth.

Conclusion

This recent discovery of a Bluetooth vulnerability that can be exploited to inject keystrokes without user confirmation is a serious threat to users across different platforms. The Android vulnerability is zero-click, and unpatched devices can be exploited whenever Bluetooth is enabled. To mitigate the risk of Bluetooth attacks, it is important to keep your devices updated, disable Bluetooth when not in use, avoid pairing with unknown devices, and don’t turn on discoverable mode if not necessary.  

10 thoughts on “Exploiting 0-click Android Bluetooth vulnerability to inject keystrokes without pairing

  1. docker

    Hi hello Can you give me the script for poc_msf.sh?

  2. Joshua Thomas Ipock

    Thank you for the information.

  3. mbithi

    where did you get your kernel from? i use the magisk version of nethunter but bluetooth arsenal doesnt work, terminal says couldnt find bluetooth.h guessing this is from the kernel

    1. Without custom NetHunter kernel Bluetooth Arsenal won’t work. You can download the kernel from nethunter website or build your own.

      1. mbithi

        only the hci0 interface is required for the exploit??

        1. Yes, either hci0 (internal Bluetooth chip) or hci1 (external Bluetooth adapter)

          1. mbithi

            bluetooth interface hci0 is available but cant bring it up, nethunter crashes when i try

          2. mbithi

            oh, enabled all the drivers listed on the main page description, up top

  4. How did you modify the payload for the instructions after the connection?

  5. gabs

    Master I get this error when executing, please help me understand it

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
    File “/root/pentester/blue/hi_my_name_is_keyboard/./keystroke-injection-android-linux.py”, line 88, in
    client.send_keypress(Key.Home, Key.Enter)
    File “/root/pentester/blue/hi_my_name_is_keyboard/injector/client.py”, line 122, in send_keypress
    self.send_keyboard_report(*args)
    File “/root/pentester/blue/hi_my_name_is_keyboard/injector/client.py”, line 119, in send_keyboard_report
    self.c19.send(keyboard_report(*args))
    File “/root/pentester/blue/hi_my_name_is_keyboard/injector/client.py”, line 32, in send
    raise ex
    File “/root/pentester/blue/hi_my_name_is_keyboard/injector/client.py”, line 27, in send
    self.sock.send(data)
    File “”, line 5, in send
    bluetooth.btcommon.BluetoothError: [Errno 104] Connection reset by peer
    ^CException ignored in atexit callback:
    Traceback (most recent call last):
    File “/usr/lib/python3.11/multiprocessing/util.py”, line 357, in _exit_function
    p.join()
    File “/usr/lib/python3.11/multiprocessing/process.py”, line 149, in join
    [2024-02-23 06:20:56.168] calling UnregisterProfile
    res = self._popen.wait(timeout)
    ^^^^^^^^^^^^^^^^^^^^^^^^^
    File “/usr/lib/python3.11/multiprocessing/popen_fork.py”, line 43, in wait
    return self.poll(os.WNOHANG if timeout == 0.0 else 0)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File “/usr/lib/python3.11/multiprocessing/popen_fork.py”, line 27, in poll
    pid, sts = os.waitpid(self.pid, flag)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
    KeyboardInterrupt:

Leave a Reply

Your email address will not be published. Required fields are marked *