# Part I: Triaging Blueborne From Stripped Binary

I remember back when I was working with a major Infotainment supplier in a very then recently formed security team, one of the agenda for us was to check if something that comes up online as a security blog/vulnerability/hack/talk etc and map that to our existing portfolio of devices and the software stacks they might use. It was easier said than done, as most of the companies including ours did not have a detailed centralized inventory of what our products were using in software stacks or hardware so that we can run a couple of search queries and find which product in development and field were affected, so stuff had to be done manually. And then we got a signal for a set of vulnerabilities affecting the Bluetooth Stack and Kernel probably used by millions if not billions  
[Blueborne](https://info.armis.com/rs/645-PDC-047/images/BlueBorne%20Technical%20White%20Paper_20171130.pdf) vulnerabilities and Exploits from [Armis](https://www.armis.com/) are really cool and probably they were found out by years of source code audit and experimentation and there were several vulnerabilities, 8 to be precise ! According to Armis, around [8.2 billion devices](https://www.allaboutcircuits.com/news/blueborne-bluetooth-attack-puts-over-8-million-devices-at-risk/) would be affected !!

* 1\. Linux​ ​kernel​ ​RCE​ ​vulnerability​ ​-​ ​CVE-2017-1000251
    
* 2\. Linux​ ​Bluetooth​ ​stack​ ​(BlueZ)​ ​information​ ​Leak​ ​vulnerability​ ​-​ ​CVE-2017-1000250
    
* 3\. Android​ ​information​ ​Leak​ ​vulnerability​ ​-​ ​CVE-2017-0785
    
* 4\. Android​ ​RCE​ ​vulnerability​ ​#1​ ​-​ ​CVE-2017-0781
    
* 5\. Android​ ​RCE​ ​vulnerability​ ​#2​ ​-​ ​CVE-2017-0782
    
* 6\. The​ ​Bluetooth​ ​Pineapple​ ​in​ ​Android​ ​-​ ​Logical​ ​Flaw​ ​CVE-2017-0783
    
* 7\. The​ ​Bluetooth​ ​Pineapple​ ​in​ ​Windows​ ​-​ ​Logical​ ​Flaw​ ​CVE-2017-8628
    
* 8\. Apple​ ​Low​ ​Energy​ ​Audio​ ​Protocol​ ​RCE​ ​vulnerability​ ​-​ ​CVE-2017-14315
    

In this article/series we will focus on the first two -​ CVE-2017-100025 and ​CVE-2017-1000251

​CVE-2017-1000251 is a information leak vulnerability so i thought it should be relatively possible to find in the binary where the vulnerability is present as we have all the details related to the code, the patch and exact versions of the software, namely [Bluez](https://www.bluez.org/release-of-bluez-5-46/) [version 5.46](http://www.kernel.org/pub/linux/bluetooth/bluez-5.46.tar.xz). The source code patch is available here in version 5.46  
With that being said, generally there are two ways to find out if this affects you -

1. You have an inventory or SBOM of the products with the software’s used inside it with versions of all the libraries, stacks, vendor stacks (generally no) etc
    
2. Find out from the binary blog? What?
    

In the first case, if you have this then you are a pro otherwise you are in the same queue as majority of vendors.  
In the second one, when people build stuff, its generally good to optimize the code and remove the symbols from the builds to ensure less size, as the processor don’t care if you have symbols or not, all it care is binary code and stripping a binary or library from its symbols and debug information for production devices that are shipped is a good practice. When you want some debug ability let’s say during development you need to know where your shit crashed and with some logs would be good. But this causes a problem to track something that is in the field if it’s pure binary data -  
Now to identify if Blue Borne is part of your device stack or not is based on the above two approaches. Therefore, for an investigation team like a Product Security Team, it would be important that they analyse all the assets to look for something that looks like Blue borne purely from stripped binary data and this is how it looks.

![Stripped-Binary-Decompilation](https://cdn.hashnode.com/res/hashnode/image/upload/v1763030343818/3cf40d8c-c556-43a6-8810-f2c442e91277.png align="center")

Now, what the flying fuck is this, said Tyson Benson one day.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1763280072193/23cb0ded-65e4-42e1-aaa1-3e15c3ea6b19.png align="center")

How can someone not so experienced with reverse engineering look for something like this a multitude of stripped and packed code throughout a set of products portfolios?

Now here is a sane compiled from source with symbols versions of the same stub

![Decompilation-When-We-Have-Symbols](https://cdn.hashnode.com/res/hashnode/image/upload/v1763030511702/e5129461-4109-4ee1-9e29-10875117443d.png align="center")

Imagine how much easier would it be triage this if only we had debug symbols - In some cases, you took this from someone else, and he deleted all the symbols before sending it to you and in other you might still have them if this was part of some random team from your company.

Triaging this when you are symbol blind seems like a mission for the IMF !!

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1763030800722/afe6a811-b7a4-47ad-82fc-822f5ba93f76.gif align="center")

But wait - then how do you actually triage this ?

Let me take a diversion here to show you how compiler plays tricks on you when you want to load some binaries in Ghidra and try to find it where the hell is that stub function ?

I started to build out an environment to compile Bluez 5.46 from source code and after running into some compiler warnings and error of the kind like redefinition of function in some files on the newest ubuntu, i found the newest include files from Libc defined some functions differently that were used in this version of BlueZ - idk whatever , so i decided to use [Ubuntu 16.04](https://imgur.com/a/blueborne-exploit-zcvLb) as some guy used this to build an [exploit](https://github.com/sgxgsx/blueborne-CVE-2017-1000251/tree/main) for these vulnerabilities, hence i switched to a server version of Ubuntu 16.04 and the shit compiled out of the box.  
Cool, who really configures the codebase when you are just playing around, so i let it build with default options. Then loaded the built object code for the src/bluetoothd-sdpd-request.o in ghidra and to my surprise the function(service\_search\_attr\_req) where the vulnerability exists would’t show up in the function listing — why ? I had no idea. This is probably should have been intuitive for me but not one of my best days. So i went a little deeper.  
The actual code where the vulnerability resides according to Armis’s documentation looks something like this so the function service\_search\_attr\_req must be there in the file src/sdpd-request.c

![Actual-Code - Can you spot/guess the vulnerability ?](https://cdn.hashnode.com/res/hashnode/image/upload/v1763053717324/29e54fd7-60c0-4ba5-8a3a-a0878d1d4524.png align="center")

The function after compiling matched on below files as one would expect, specifically the object file src/bluetoothd-sdpd-request.o

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1763053876550/dfdedbce-7035-4aa6-9d69-090988b61e3d.png align="center")

But it does’’t show up in readelf symbols, nm or any other tools including Ghidra.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1763054020811/745502af-f6b2-4e26-b4f8-18b35a50ae19.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1763054547358/e1473fcc-0c4f-4f4d-934b-58bd9e44334a.png align="center")

After seeing this i was like wow - generally, this function is part of the compiler optimization hence the function got removed or something else happened ?

> Ghost Input: Compiler optimizations have killed more RE’s in an hour than titanic !

The solution is simple, the compiler optimized this and in-lined this function within the same file from where this is called depending on level of optimization, this is completely terrible when reverse engineering as it is hard to understand where is what and is a point of confusion and this is most probably how it will be in production release version, in-lined, optimized, and stripped of any debug info to give you a hint. As this is an exercise, lets simplify this a little bit.  
We recompile the code but with no optimization so that the service\_search\_attr\_req is visible as a separate function and we can create a call graph.

```bash
./configure CFLAGS="-O0 -fno-inline -g"
```

Once we have the object file with no compiler optimizations, things look a little better and we can find the function now because we told the compiler to ignore optimization. This should have been picked up by me earlier.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1763057643672/5a520206-008e-4c89-a30e-40010ce08780.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1763060172009/1d58ced5-a3ca-4b8b-becd-f48ef63bb965.png align="center")

So based on the data from Armis, lets try to prepare a Path to reach this function purely initially from the debug version binary file and then with stripped binary file as it will be in production - good for you if it has debug (some)symbols in production.

If with debug symbols a small call tree would look like this -

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1763062581098/f913be18-d853-4372-a3c3-fd3e81b75d2e.png align="center")

The start of Process request with its address - 0×00101a7a

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1763063186656/5ad84a97-01ed-4b78-af4b-9bb4df41606c.png align="center")

Similarly for handle internal request at 0×101d56

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1763063280425/d554349d-57af-496c-9348-18fd6a3c09f7.png align="center")

and also for handle\_request at 0×101e1f

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1763063353150/17cde584-e95e-49d3-ba03-1e8f6dc883be.png align="center")

Therefore taking stuff from debug versions to compare the symbols and functions from the not optimsed compiled object file refer to the same function calling tree - Yay ! as seen from below

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1763063127796/e186f518-cfd1-408f-8b32-987ca61b7fc7.png align="center")

Could this mean there is a way to do this ? Probably yes, here we recompiled our codebase to show us independent functions stub so we can better trace in Ghidra. May be using this method, you can probably pin point if your older compiled binary based shit is valid or not for a given vulnerability.  
Knowing a vulnerability and the path it takes can be used effectively to somehow counter “Are we affected with this godforsaken bug ?”, the above method is very trivial when done manually and only takes an hour or so for an experienced researcher doing stuff manually.

Relying on addresses is not a good way, as a small change will change these offsets.

It is totally possible that other methods to do this exists and are much better, maybe someone would have made a plugin for Ghidra or Binja for this idk. Please note we have not covered how to trace when the compiler optimizations are in place and functions are in-lined, perhaps we will do it in the next article.  
The lingering question still remains, will this help the not-so-reverse-engineery analyst Tyson B pinpoint, confirm and triage this purely from a binary.

Stay Tuned for Part II.

Note: For professional queries and projects, reach out to me at [**abhijit.lamsoge@outlook.com**](mailto:abhijit.lamsoge@outlook.com)

Title image and Tyson’s(He looks much better than this guy) image is generated by AI.
