Paint it blue: Attacking the Bluetooth stack (2025)

D4Ha1 pts0 comments

Paint it blue: Attacking the bluetooth stack

Security incident? Suspected breach?<br>09 71 18 27 69csirt@synacktiv.com

Skip to main content

Search

Switch Language

EnglishToggle Dropdown<br>English<br>French

RSS<br>Github<br>Twitter<br>Linkedin

Our offerPenetration Test / Red Team<br>Incident response<br>Reverse-engineering<br>Development<br>Products<br>CSIRT

Trainings<br>Join us<br>PublicationsPosts<br>Advisories<br>Resources

The company<br>Contact

RSS<br>Github<br>Twitter<br>Linkedin

Paint it blue: Attacking the bluetooth stack

Written by<br>Mehdi Talbi, Etienne Helluy-Lafont - 27/10/2025 - in

Exploit

- Download

Bluetooth has always been an attractive target to attackers since it is present almost everywhere (TV, automotive charger, connected fridge, etc.). This is especially true on mobile devices, as it runs as a privileged process with a potential access to microphone, address book, etc.

In September and October 2023, Android published security bulletins addressing critical vulnerabilities in their Bluetooth stack (Fluoride), which could lead to remote code execution. CVE-2023-40129 is an integer underflow in the GATT protocol, which is accessible without authentication or user interaction. It was very challenging to exploit as it was causing a 64 KB heap overflow, acting like a tsunami devastating everything in its path, leading the Bluetooth process to an almost certain death.

In this blogpost, we detail how we exploited this vulnerability on both Android native allocators: Scudo and Jemalloc.

Looking to improve your skills? Discover our trainings sessions! Learn more.

The Bluetooth Stack

The diagram above illustrates the Bluetooth stack. It is divided in two main parts: the Controller stack resides in the Bluetooth chip, while the Host stack is implemented by the operating system. The Host Controller Interface (HCI) enables communication between the two components. The controller mostly manages the physical and logical transports. Our exploit relies on ACL, the asynchronous transport that carries data frames. On Android, the Host stack - called Fluoride - runs as a userland daemon. After the ACL link is established, L2CAP (Logical Link Control and Adaptation Protocol) connections can be initiated to access various Bluetooth services (BNEP, HID, AVCTP, etc.), which provide well-known features such as networking sharing, video streaming, etc. Each service is identified by a unique Protocol Service Multiplexer (PSM):

Service

PSM

SDP (Service Discovery Protocol)

0x0001

RFCOMM (Radio Frequency Communication)

0x0003

BNEP (Bluetooth Network Encapsulation Protocol)

0x000F

HID (Human Interface Device)

0x0011 (Control), 0x0013 (Interrupt)

AVCTP (Audio/Video Control Transport Protocol)

0x0017 (Control), 0x001B (Browsing)

AVDTP (Audio/Video Data Transport Protocol)

0x0019

GATT (Generic Attribute Protocol)

0x001F

GAP (Generic Access Profile)

0x01001, 0x1003, 0x1005, 0x1007

The code related to each service is located under the system/stack/ directory. Each service is registered via the following API:

uint16_t L2CA_Register2(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,<br>bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,<br>uint16_t my_mtu, uint16_t required_remote_mtu,<br>uint16_t sec_level)

The sec_level parameter defines the security level for accessing the service. Most services require the connection to be authenticated and encrypted.

Very few services can be accessed without authentication - namely SDP, RFCOMM, and GATT. But even when a connection starts unauthenticated, certain operations (like writing GATT attributes) may later require it - further reducing the attack surface.

The BlueBlue framework

Building upon the L2CAP testing framework of the BlueBorne project, we developed our own framework named BlueBlue. It conveniently uses Scapy to build and parse HCI frames. The framework allows to establish an ACL link with a peer device and to open L2CAP connections.

It also supports multiple features of the Bluetooth specification such as LCAP fragmentation and the ERTM transmission mode. It implements all the features of the Host stack that we are using, giving us a plenty of freedom to explore new ideas.

With just a few lines of codes, we can establish an ACL connection, connect to a L2CAP service, send a command and receive the reply:

acl = ACLConnection(src_bdaddr, dst_bdaddr, auth_mode = 'justworks')<br>gatt = acl.l2cap_connect(psm=PSM_ATT, mtu=672)<br>gatt.send_frag(p8(GATT_READ)+p16(1234))<br>print(gatt.recv())

The Bug

CVE-2023-40129 is a vulnerability present in the GATT server. The GATT protocol is used to expose simple key-value attributes. Keys are 16-bits handles, while values are simple raw data. The opcode GATT_REQ_READ_MULTI_VAR allows to read multiple attributes at once.

The request is made of the opcode GATT_REQ_READ_MULTI_VAR followed by the list of GATT handles:

The response is made of the opcode GATT_RSP_READ_MULTI_VAR followed by the length and the value of each requested attributes:

The request is handled in...

bluetooth stack gatt protocol service uint16_t

Related Articles