LIGHTBLUE: Automatic Profile-Aware Debloating of Bluetooth Stacks (USENIX Security’21)¶
Source¶
Paper & Presentation: https://www.usenix.org/conference/usenixsecurity21/presentation/wu-jianliang
Problem to Solve¶
Bluetooth standards and their implementations are diverse and complex, which contains many functionalities that never be required in the common scenarios. Those useless parts actually extend the attack surface.
LIGHTBLUE
is a framework that performs automatic, profile-aware debloating of Bluetooth stacks. It allows users to automatically minimize their Bluetooth attack surface by removing unneeded Bluetooth features and introduce no performance overhead or effect on the behaviors.
Methodology¶
The workflow of LIGHTBLUE
:
LIGHTBLUE
takes an application and a Bluetooth stack implementation (host code + firmware) as inputs. LIGHTBLUE
has three parts: 1. profile identification 2. host code analysis 3. firmware analysis
Profile Identification¶
Purpose
In step 1, LIGHTBLUE first identifies what profile is used by the application.
As that the host code provides fixed interfaces to the application so that the application can use the functionalities provided by the profile. For example:
In Android, the call of
getProfileProxy
API can return the interfaces of a specific profile.On Linux, the application can access the profile provided by the Bluetooth stack by accessing the relevant D-Bus services.
To identify those profiles, LIGHTBLUE
scans for these interfaces in app’s code.
Host Code Analysis¶
Purpose
In step 2-3, LIGHTBLUE
analyzes the source code of the host, performing a profile-aware dependence analysis and generates a profile-aware dependency graph. Removing the code outside this graph, a host code is successfully debloated.
Since a profile is exposed as a series of APIs/functions to the application, LIGHTBLUE
builds the call graph (including all potential reachable functions in the host code) by a conservative approach.
Note
A conservative approach means that it will add all function in all instructions to the call graph in case missing any runtime called functions. It absolutely leads to an over-approximation. For example, the host code includes some dispatching functions like:
// `service_id` represents the profile currently executed
// base on this value, only 1 of 3 function call will be actually executed
// however, the conservative way will take all three functions into the call graph
// Therefore, the number of reachable function is over-estimated for a certain profile
bt_status_t btif_in_execute_service_request(
tBTA_SERVICE_ID service_id, BOOLEAN b_enable){
switch (service_id){
case BTA_HFP_SERVICE_ID :
btif_hf_execute_service (b_enable); break;
case BTA_A2DP_SOURCE_SERVICE_ID :
btif_av_execute_service (b_enable); break;
case BTA_A2DP_SINK_SERVICE_ID :
btif_av_sink_execute_service (b_enable); break;
...}
}
LIGHTBLUE
adds a dummy function invoking the different functions exposed by a specific profile to make sure the program has a single entry point so that existing traditional data-flow analysis approach can be applied to detect the exact functions called in dispatching functions: LIGHTBLUE takes the constant values within the profile interface functions as the source, and propagates them across the host code, using an approach similar to what is proposed in TRIMMER. Finally, LIGHTBLUE
scnas each functiin for conditional jumps and check if the conditional value is known. For a known conditional value, it removes the basic blocks that are only reachable from the unsatifiable branches, which helps build a smaller and more accurate profile-aware call graph. All code outside the profile dependency graph is removed.
HCI Command Extraction¶
Purpose
In step 4, a list of HCI (Host Controller Interface) commands used by the target profile is extracted, which guide to remove the unneeded functionalities in the firmware.
As HCI send/receive interfaces are well-defined, LIGHTBLUE
can extract all HCI commands used from the dependency graph. It performs a data-flow analysis from all the functions in the profile dependency graph to the HCI interfaces. Then, it gets the used HCI commands by recovering the first two bytes used to generate the HCI packet.
Tip
The data format of HCI command:
The opcode differentiates HCI commands and has the Opcode Command Field (OCF) and the Opcode Group Field (OGF). The parameter field depends on the opcode.
These two bytes contain the OGF and OCF fields of the packet, and they determine the invoked HCI command. For instance, if the first two bytes are
0x0405
, LIGHTBLUE recoversOGF
andOCF
by extracting the upper 6 bits and lower 10 bits. Based on the value of OGF and OCF (0x1
and0x5
), the HCI command is aCreate Connection
command.
Firmware Analysis and Patching¶
Purpose
With a given firmware’s binary, in step 5, LIGHTBLUE
analyzes it to find the code to handle HCI commands; in step 6, LIGHTBLUE
can identify the interfaces for setting up different types of links based on the identified code that handles the HCI commands. In step 7. LIGHTBLUE
patches the firmware by debloating the unneed functionalities, which includes the code handling unneeded HCI commands (according to what are extracted in step 4) and the unneeded link interfaces of profile. Finally, the output is the compiled host code and the patched firmware.
Attention
How to identify HCI command dispatcher?
The HCI command dispatcher often needs to perform bitwise operations to extract the OGF
and OCF
values from opcode during parsing. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | bt_status_t bthci_cmd_dispatcher(PTR* hci_cmd_pkt){ opcode = *(hci_cmd_pkt + 9); OGF = opcode >> 10; OCF = opcode & 0x3ff; handler = error_cmd_handler; switch(OGF) { case 0x01: switch(OCF) { case 0x01: handler = handle_inquiry; break; ...} ... default: // handling error HCI command handler = error_cmd_handler; break;} handler(hci_cmd_pkt); } |