seemoo-lab / nexmon

The C-based Firmware Patching Framework for Broadcom/Cypress WiFi Chips that enables Monitor Mode, Frame Injection and much more
GNU General Public License v3.0
2.43k stars 454 forks source link

Possible to patch against Broadpwn? #108

Open donnm opened 7 years ago

donnm commented 7 years ago

The Nexus 5 uses the bcm4339 chipset, and there are no Broadcom/Google patches or updates expected to fix the Broadpwn vulnerability. Is it possible to use the patching framework to fix this bug in the latest provided firmware binary?

matthiasseemoo commented 7 years ago

if nexmon allows you to change everything the firmware does, do you think it will stop working, when it comes to fixing simple firmware bugs?

in other words, we already thought about doing it, but did not have the time to work on it.

Am 13.08.2017 12:39 vorm. schrieb "donnm" notifications@github.com:

The Nexus 5 uses the bcm4339 chipset, and there are no Broadcom/Google patches or updates expected to fix the Broadpwn vulnerability. Is it possible to use the patching framework to fix this bug in the latest provided firmware binary?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/seemoo-lab/nexmon/issues/108, or mute the thread https://github.com/notifications/unsubscribe-auth/ALP_7k-uUG-DFG4yZND_QC4eyPEnf1q4ks5sXimZgaJpZM4O1iYG .

donnm commented 7 years ago

if nexmon allows you to change everything the firmware does, do you think it will stop working, when it comes to fixing simple firmware bugs?

I don't know what you mean by "stop working" here.

in other words, we already thought about doing it, but did not have the time to work on it.

The page https://blog.exodusintel.com/2017/07/26/broadpwn/ has a good description of where the bug is. I can try to patch this myself, but maybe you could offer some hints about where to start?

donnm commented 7 years ago

In the function wlc_bsscfg_malloc on that page, the exploit assumes an allocated destination buffer of size 0x2C for the station name, when it should be 0xFF. It seems to me that this could be particularly easy to patch by simply changing the byte corresponding to this size in the firmware binary.

matthiasseemoo commented 7 years ago

So I created a patch that increases the size of the wlc_wme_t struct from 0x2c to 0xff during allocation as you proposed. However, I do not know if this is sufficient to completely fix the flaw and I currently do not have a working setup to test if the exploit still works. Please, try it out and let me know, if it works. The patch only patches the one byte required to change the size during memory allocation, flashpatching and ucode compression is not used.

Here is the patching project: https://github.com/seemoo-lab/nexmon/tree/master/patches/bcm4339/6_37_34_43/anti_broadpwn

donnm commented 7 years ago

That's great, thanks! I'll try to hunt down the PoC and get an exploit working.

NoobieDog commented 7 years ago

The only PoC i have seen are for the Nintendo U and Switch... it WOULDNT be difficult for you to alter these for the Nexus 5

kimocoder commented 7 years ago

A good explain & PoC may be found here

NoobieDog commented 7 years ago

https://github.com/ReversingSwitch/BroadPWN

dariotrombello commented 7 years ago

Raspbian has fixed this issue with the latest update

atx commented 7 years ago

There is a crash-PoC here , but I was unable to get it work on my Nexus 5. Searching through the ram dump, it just doesn't seem like the malformed packet gets copied anywhere (it should appear somewhere without the Type-Length header, if I understand the original writeup correctly).

Could it be that the Nexus 5 was never vulnerable in the first place? Doesn't seem very likely to me.

Nephiel commented 7 years ago

The PoC was made for the Nexus 6P. I guess the values of assocresp_elements and vendor_elements would have to be modified to target the BCM4339 of the Nexus 5.

atx commented 7 years ago

I might be doing this completely wrong, but:

Assuming the code is the same as in the writeup, I think that after associating with the AP, I should be able to find something like length(0x2c)-zero-packetvalue... somewhere in the RAM dump. This does not happen. There is a bunch of allocated 0x2c-long chunks, but none contain the packet sent by the AP.

Notably there is a 0x2c long chunk, which contains what looks like a valid WME packet, but it is there right after powerup (wtf?) and it does not get overwritten after association:

0xb96a0 0000000000000000 2c00000000000000 0050f2020101000003a4000027a4000042435e0062322f00000000000000

Note that the entire packet (with the 0xdd 0xff type-length prefix) is on several places in the memory in what possibly looks like ring buffers of some sort (?).

Rdlgrmpf commented 7 years ago

@atalax It should be at address 0x1f3518 for the 7_112_200_17_sta firmware on N6p.

This is for an unpatched firmware! If you patch some functions and hooks, this might change location.

em77 commented 7 years ago

Any update on this?

donnm commented 6 years ago

Sorry for the long silence. I tried but could not get this working. If I recall correctly I had trouble patching the firmware.

joeminicucci commented 6 years ago

Although the fix is clever, I'd assume it won't correct the underlying problem, which is the overflow itself. While this might mitigate the potential for a pure RCE, an overflow is still possible into the wlc->pm struct section as noted in the PoC. While the 211 extra bytes was originally intended to be utilized for a payload:

We can write the shellcode to the wlc->pm struct that we are overflowing, but this poses two difficulties: first, our space is limited by the fact that we only have an overwrite of 211 bytes. Second, the wlc->pm struct is constantly in use by other parts of the HNDRTE code, so placing our shellcode at the wrong place within the structure will cause the whole system to crash.

The author realized that there was little room for meaningful shellcode, so following his logic he decided to inject a rather small amount of shellcode which points jumps to the real payload which he loaded onto the D11 ring buffer:

After some trial and error, we realized that we had a tiny amount of space for our code: 12 bytes within the wlc->pm struct (the only place where overwriting data in the struct would not crash the system), and 32 bytes in an adjacent struct which held an SSID string (which we could freely overwrite). ...

What we’ll do, therefore, is this: write a small stub of shellcode within wlc->pm, which saves the stack frame (so we can restore normal execution afterwards) and jumps to the next 32 bytes of shellcode which we store in the unused SSID string. This compact shellcode is nothing else than classic egghunting shellcode, which searches the ring buffer for a magic number which indicates the beginning of our payload, then jumps to it.

This means that the overflow of the current_wmm_ie struct which is allocated in this proposed patch can still be overflown, and the wlc->pm struct is used as a compact shellcode method to re-direct the stack pointer to the malicious payload contained in the D11 ring buffer. As he said in his presentation, "game over".

Suggestion: Perhaps we could find a way to hook the IE packet data append method where the overflow occurs, and mitigate the vulnerable memcpy with a classic length check? i.e. void wlc_bss_parse_wme_ie(wlc_info wlc, ie_parser_arg arg) ->memcpy(current_wmm_ie, ie->data, ie->len);

Karafare commented 5 years ago

Was there any further development regarding this issue? Maybe reusing the code from phones that where patched (like the nexus 6 if I'm not mistaken) could do the trick.