Mechanism
Bluetooth Classic exposes its application surface through profiles, and every profile is advertised in the Service Discovery Protocol (SDP) directory. Querying SDP returns the device’s service records — each naming a profile (Serial Port / RFCOMM, HID, A2DP, HFP/HSP, OBEX Object Push, PBAP, and so on) and the L2CAP PSM or RFCOMM channel behind it. SDP is therefore the map of what the device trusts above the link, and enumerating it is the first move at this layer. The standard driver is a Linux host’s BlueZ stack over a commodity USB adapter — the same host workflow BSAM’s Bluetooth controls assume — so RFSAM owns only the RF prerequisite (reaching the device’s host stack over the air) and defers the service-access-control judgement (which of those profiles may be reached without authentication) to BSAM-SE-03 (bluez-project).
The reason this layer matters is that the SDP directory is not merely descriptive — it is reachable, and so is everything behind it. BlueBorne is the canonical demonstration: a family of host-stack vulnerabilities reached over Bluetooth without pairing and without the target being discoverable (armis2017blueborne). On Linux the SDP server itself leaks bluetoothd process memory through crafted search-attribute requests (CVE-2017-1000250), and the kernel L2CAP layer that every profile rides on can be driven to remote code execution (CVE-2017-1000251) (cve-2017-1000250, cve-2017-1000251). The Android arm of the same family adds RCE (CVE-2017-0781) and an information leak in the Android Bluetooth SDP server (CVE-2017-0785), with proof-of-concept code published by Armis (armis2017blueborne-poc, cve-2017-0781, cve-2017-0785). The SDP framing of CVE-2017-0785 is Armis’s own: NVD records it simply as an Android Bluetooth information-disclosure issue, while the Armis PoC android/ exploit uses it explicitly as “the SDP Information leak vulnerability (CVE-2017-0785) to bypass ASLR” ahead of the CVE-2017-0781 RCE (armis2017blueborne-poc). Treat this CVE set as representative of the above-the-link/host-stack class, not as a current advisory list — check vendor advisories for the target’s controller SoC and host OS before testing.
Procedure
Authorised testing only — enumerate and exercise profiles solely on devices you own or are explicitly contracted to assess. SDP browsing is passive, but pairing, RFCOMM connection and OBEX transfer are active interactions with the target’s host stack.
-
Bring up the local adapter and confirm it is a BR/EDR controller:
sudo hciconfig hci0 up hciconfig hci0 version # check "BR/EDR" and the HCI/LMP versionYou want a controller that reports BR/EDR (not an LE-only dongle).
-
Discover the target and record its BD_ADDR and Class of Device (the IG/SP work feeds this — you may already have the address):
bluetoothctl [bluetooth]# scan on # note the BD_ADDR (e.g. AA:BB:CC:DD:EE:FF), name and CoD, then: [bluetooth]# scan off -
Confirm L2CAP reachability of the host stack (works even against a non-discoverable device whose BD_ADDR you already know):
sudo l2ping -c 5 AA:BB:CC:DD:EE:FFReplies confirm the BR/EDR host is up and answering — the prerequisite for everything below.
-
Enumerate the SDP service directory — the core of this control:
sdptool browse AA:BB:CC:DD:EE:FFRead the output for service records: each lists a
Service Name, the profile (Serial Port,Human Interface Device,Advanced Audio,Handsfree,OBEX Object Push, …), and theRFCOMMchannel or L2CAPPSMbehind it. This is the inventory of what the device exposes above the link. -
For each interesting profile, exercise what the device trusts. Examples:
- RFCOMM serial / AT command channel (common on hands-free and car/OBD units): bind the channel SDP reported and probe it.
sudo rfcomm connect /dev/rfcomm0 AA:BB:CC:DD:EE:FF 1 # channel from sdptool # in another terminal: screen /dev/rfcomm0 115200 AT # does the unit answer AT commands? - OBEX Object Push (does it accept files without authorisation?):
obexftp -b AA:BB:CC:DD:EE:FF -B <obex-channel> -p ./test.txt - HID / audio (A2DP/HFP): note whether
bluetoothctl pair/connectsucceeds with no PIN or with a fixed/known PIN, and whether the profile activates without confirmation on the device.
- RFCOMM serial / AT command channel (common on hands-free and car/OBD units): bind the channel SDP reported and probe it.
-
Record, per profile: the channel/PSM, whether it required authentication, and what it did when reached without it. That table — which services answer unauthenticated — is the finding handed to BSAM-SE-03 for the service-access-control judgement.
Field case
Illustrative walkthrough — substitute the values you capture. Against a generic Bluetooth hands-free car kit on the bench, the pattern looks like this: sdptool browse returns a Serial Port (RFCOMM) record on channel 1 and a Handsfree Gateway record, alongside the expected A2DP sink. l2ping answers immediately even though the unit is not in pairing mode, confirming the host stack is reachable from its BD_ADDR alone. Binding RFCOMM channel 1 with rfcomm connect /dev/rfcomm0 <addr> 1 and sending AT over screen /dev/rfcomm0 115200 produces an OK — the serial channel answering AT commands before any pairing completed, which is exactly the unauthenticated-service condition BSAM-SE-03 exists to flag. A harmless car kit is the demonstrator; the same enumeration step against an OBD-II dongle or a point-of-sale terminal is where an exposed RFCOMM/AT or OBEX channel becomes consequential. Record the real values from your own engagement: [FILL: real device model, BD_ADDR OUI, exact sdptool record and channel].
Remediation
- Developer (device firmware): Publish only the profiles the product actually needs in SDP, and require authentication and authorisation on every channel that carries data or commands — never leave an RFCOMM/AT or OBEX channel reachable pre-pairing. Reject legacy PIN pairing and “Just Works” where the profile handles anything sensitive. Keep the controller SoC and host Bluetooth stack patched against the host-stack class (BlueBorne and its successors); treat the cited CVE set as representative and track current advisories for your specific stack (armis2017blueborne).
- Integrator: Choose modules and host stacks with maintained security updates; verify, by running the enumeration above on the assembled product, that no profile answers unauthenticated. Disable unused profiles at integration time rather than trusting defaults.
- Operator: Keep the device non-discoverable when not actively pairing, apply firmware updates promptly, and unpair stale bondings. Recognise that non-discoverable is not unreachable — a known BD_ADDR still reaches the host stack — so patching the stack, not hiding it, is the durable control. The which-services-must-be-locked judgement is owned by BSAM-SE-03.