DIR-2660 failing to flash

I have been trying (and failing) to flash dlink_dir-2660-a1-squashfs-factory.bin on a DIR-2660 A1 device, using the D-Link recovery web UI (and curl - other browsers had no success). The behavior I notice is:

[1] Router powers on (with the reset button pressed) and gets in its recovery UI - the power led is blinking and I can open its page in
[2] I send the FW using curl (tried with a couple of snapshots from the last few days and a couple of "stock" versions from D-Link)
[3] curl gets a reply from the router (that the FW is successfully uploaded and is getting flashed, with a js script counting to 100%) and the power led remains constant on
[4] In the case of the "stock" FW from D-Link, the router resets after a few seconds and eventually boots with the newly flashed FW. (flashing is successful)
[5] In the case of the factory openwrt image, the router stays with the power led on for a couple of seconds and then the led starts flashing again (in the same way as in the recovery GUI). At this stage the router seems totally inaccessible in any way and it stays there forever until manually powercycled. When powercycled it boots to the FW it had earlier.

To me, this behavior seems like the openwrt factory.bin getting uploaded, but then rejected for some reason by the router. I wonder if there is something obvious that I am missing (or doing very wrong) or if there's something else that blocks the flashing (could there be a change in the way the FW is verified by the router, resulting in rejecting openwrt?) I also wonder what other options I'd have in order to get some idea of what's happening (preferably without dismantling the router).

P.S.1: The obvious checksum test of the factory.bin to confirm that I don't have a corrupted download is successful - I have the correct binary.


I have a DIR-1960 witch I be leave is the same with only a usb port header different
but the boot loader will only let unencrypted firmware upload
witch if fine for openwrt but as the dlink firmware is encrypted it won't work
you need to get an unencrypted copy to flash from recovery
this seems to be opposite to what you have
here is an unencrypted version of the DIR-2660 firmware
if this won't flash then openwrt won't flash

First of all thanks for extracting the unencrypted stock V1.04 B03 FW and sharing it. I probably should have explicitly mentioned that the "stock" FW I tested is the dencrypted one that I have extracted from the downloads available from D-Link (using the nice reading from https://0x434b.dev/breaking-the-d-link-dir3060-firmware-encryption-recon-part-1/ and the subsequent parts of the document).

I didn't try to flash an encrypted firmware from the recovery UI and I wouldn't expect it to succeed either.

FW versions 1.11 B04 (the newest), 1.00 B14 (the oldest) 1.03 B04 (the one that the router had pre-installed) and 1.04 B03 (the one suggested in the last message) downloaded from D-Link and decrypted (using the documentation in the post above) flash without problems via the recovery UI.
Does that answer the question?

(or to ask the same question in another way: Is there something more in http://luckys.onmypc.net/openwrt/DIR-2660/DIR2660A1_FW104B03.bin apart from extracting the decrypted binary from what D-Link provides? As far as I have seen it seems to be the same as the one I can extract from D-Link's V1.04 B03 padded with 0s to match the size of the original (encrypted+header) download - so I guess the answer is that it doesn't contain anything more)

no it's just decrypted
just a note but on the DIR-878(same PCB different Flash) the boot loader
dated Jul-19-2017 will only except unencrypted firmware but I have another
dated Jul-9-2018 with will accept both unencrypted & encrypted versions

I have edited today's snap shot and added the factory model number to the header
I don't think this will fix it but something to try

so you can try dir-2660-a1-factory-with-header.bin if you like

to go any further you would have to open the case & setup reading of the serial console
looking for errors as you try to flash the unit

I did just check the current snap shot "DIR-2660" & it installed on my DIR-1960
I can connect via ssh but there is a error in the packages
and luci would not install atm

and thanks for the hint and the image. Unfortunately no luck with that either. I did a few more tests related to the same idea (of making the header look as similar as possible to the decrypted "stock" firmware, but had no luck with these either. (as far as I can tell, I was updating checksums correctly in the header, but I was making the changes manually with a hex editor, so I cannot rule out mistakes 100%)

In any case, I agree that we are blind without the serial console. I'll need to see what HW I'll need for that and order it. It may take some days before I manage to gather everything and connect it (hopefully I won't fry it).

1 Like

I finally managed to experiment a bit more. Eventually, the idea from tmgoblin:

provides a functional path to installing openwrt. The console didn't really provide much insight on why the recovery mode rejects openwrt. I can see the following while trying to flash openwrt:

6: System Enter UBoot to Update Img or Bin.

 abuffer(TX Packet buffer) = 0x8FFE3D40
Trying Eth0 (10/100-M)

 Waitting for RX_DMA_BUSY status Start... done

Got ARP REQUEST, return our IP
Got ARP REQUEST, return our IP
to check image type

Check image validation:
Image1 Header Magic Number --> OK
Image1 Header Checksum --> OK
Image1 Data Checksum --> OK

image is unencrypto kernel images
*********** len: 1355, s->dataSize: 1355

whereas while trying to flash the stock image I get:

6: System Enter UBoot to Update Img or Bin.

 abuffer(TX Packet buffer) = 0x8FFE3D40
Trying Eth0 (10/100-M)

 Waitting for RX_DMA_BUSY status Start... done

Got ARP REQUEST, return our IP
Got ARP REQUEST, return our IP
to check image type

Check image validation:
Image1 Header Magic Number --> OK
Image1 Header Checksum --> OK
Image1 Data Checksum --> OK

image is unencrypto kernel images
*********** len: 1355, s->dataSize: 1355
lost ACK
image_flg = 0, length = 17994721


updating img...........
ranand_erase: start:180000, len:20000
..ranand_erase: start:1a0000, len:20000
....ranand_erase: start:12a0000, len:20000
.(5192)offs=19529728 piece=0 piece_size=37857 rc=0

and then it reboots. To me, it seems as if it silently rejects the image and stops.

this is the expected result with "U-Boot 1.1.3 (Apr 25 2019 - 14:00:06)" boot loader in a DIR-1960
using recover console by holding reset down while booting
using today's snapshot "openwrt-ramips-mt7621-dlink_dir-1960-a1-squashfs-factory.bin"
it's also followed up by updating the backup copy on the next boot

Got ARP REQUEST, return our IP
*********** len: 1156, s->dataSize: 1156
*********** len: 1156, s->dataSize: 1156
to check image type

Check image validation:
Image1 Header Magic Number --> OK
Image1 Header Checksum --> OK
Image1 Data Checksum --> OK

image is unencrypto kernel images
*********** len: 1355, s->dataSize: 1355
image_flg = 0, length = 8650866


updating img...........
ranand_erase: start:180000, len:20000
..ranand_erase: start:1a0000, len:20000
..ranand_erase: start:1c0000, len:20000
..ranand_erase: start:1e0000, len:20000
..ranand_erase: start:200000, len:20000
..ranand_erase: start:220000, len:20000
..ranand_erase: start:240000, len:20000
..ranand_erase: start:260000, len:20000
..ranand_erase: start:280000, len:20000
..ranand_erase: start:2a0000, len:20000
..ranand_erase: start:2c0000, len:20000
..ranand_erase: start:2e0000, len:20000
..ranand_erase: start:300000, len:20000
..ranand_erase: start:320000, len:20000
..ranand_erase: start:340000, len:20000
..ranand_erase: start:360000, len:20000
..ranand_erase: start:380000, len:20000
..ranand_erase: start:3a0000, len:20000
..ranand_erase: start:3c0000, len:20000
..ranand_erase: start:3e0000, len:20000
..ranand_erase: start:400000, len:20000
..ranand_erase: start:420000, len:20000
..ranand_erase: start:440000, len:20000
..ranand_erase: start:460000, len:20000
..ranand_erase: start:480000, len:20000
..ranand_erase: start:4a0000, len:20000
..ranand_erase: start:4c0000, len:20000
..ranand_erase: start:4e0000, len:20000
..ranand_erase: start:500000, len:20000
..ranand_erase: start:520000, len:20000
..ranand_erase: start:540000, len:20000
..ranand_erase: start:560000, len:20000
..ranand_erase: start:580000, len:20000
..ranand_erase: start:5a0000, len:20000
..ranand_erase: start:5c0000, len:20000
..ranand_erase: start:5e0000, len:20000
..ranand_erase: start:600000, len:20000
..ranand_erase: start:620000, len:20000
..ranand_erase: start:640000, len:20000
..ranand_erase: start:660000, len:20000
..ranand_erase: start:680000, len:20000
..ranand_erase: start:6a0000, len:20000
..ranand_erase: start:6c0000, len:20000
..ranand_erase: start:6e0000, len:20000
..ranand_erase: start:700000, len:20000
..ranand_erase: start:720000, len:20000
..ranand_erase: start:740000, len:20000
..ranand_erase: start:760000, len:20000
..ranand_erase: start:780000, len:20000
..ranand_erase: start:7a0000, len:20000
..ranand_erase: start:7c0000, len:20000
..ranand_erase: start:7e0000, len:20000
..ranand_erase: start:800000, len:20000
..ranand_erase: start:820000, len:20000
..ranand_erase: start:840000, len:20000
..ranand_erase: start:860000, len:20000
..ranand_erase: start:880000, len:20000
..ranand_erase: start:8a0000, len:20000
..ranand_erase: start:8c0000, len:20000
..ranand_erase: start:8e0000, len:20000
..ranand_erase: start:900000, len:20000
..ranand_erase: start:920000, len:20000
..ranand_erase: start:940000, len:20000
..ranand_erase: start:960000, len:20000
..ranand_erase: start:980000, len:20000
..ranand_erase: start:9a0000, len:20000
....ranand_erase: start:9c0000, len:20000
.(5192)offs=10223616 piece=0 piece_size=114 rc=0

it seems like maybe dlink has updated the boot loader with an extra check
I would think the next step is to add the header model information to the uboot header
& then try to encrypt the file with the tool in the GLP source code
to make a comparable web flash image
if this works an encryption tool may have to be written to do this

as you have serial access you could try loading the inframs image into ram
& if it boots fine you may be able to flash the sysupgrade image via that
but before you flash anything do backup all of your mtd partitions just in case
the only thing is it's nice to have luci compiled info the initramfs image
where the snapshot won't have it
the dir-1960 version is the same you could use it
you will get a warning about the firmware model number being different when flashing tho

Hi everyone.

I just bought a D-Link DIR-2660 that I'm currently trying to flash.
I managed to run the telnet exploit, and now I have a working telnet connection.
After uploading the new firmware, I still don't see any file /tmp/firmware.img. Actually, portions of the uploaded file are saved in files like the following


which are then removed.
I'm currently figuring out a way to upload the firmware to later run mtd_write.


In my case, the stock FW had wget which means you can download anything directly to the router. If you connect the router in a way that it has internet access, then you can probably even do:

cd /tmp
wget https://downloads.openwrt.org/snapshots/targets/ramips/mt7621/openwrt-ramips-mt7621-dlink_dir-2660-a1-squashfs-factory.bin

Note: editing the link above - in the first version I had pasted the wrong image link - the initramfs-kernel instead of the factory one.

(but do confirm the image sha256sum before flashing it. I also connected a usb flash drive and saved on it all the mtd partitions before flashing anything. I'm not sure how exactly I would use this backup if things would go wrong, but better having it than not)

If you would like to download the image from your local network, starting a temporary http server on another system that listens to <port number> is as simple as running:

python -m SimpleHTTPServer <port number>

in the directory you want to share (the directory on the other system that has the firmware images). This should run on almost any linux distro with python 3.

1 Like

some of the DIR-2660's are not accepting the openwrt firmware
I made a version of the part that makes the header that includes the model & part number
like the factory firmware
my DIR-1960 works with out this so I can't test it
but the code is here

1 Like

master snapshots should now work fine as the header has the extra info

1 Like

Hi, I have the same problem, even with curl I am unable do make the router accept openwrt.

can you help me finding your snapshot to give it a try?

it's just the Master branch snapshots
with snapshot you have to ssh into it & install luci

I know with a windows browser you get a page back
witch say if the firmware is rejected or starting to upload in to flash
I'm not sure if you get any feed back with curl on Linux

Thank you, I'll try it asap but ... which file I have to use? Kernel, sysupgrade or factory?

No luck. With curl this is the output

curl -v -i -F "firmware=@openwrt-ramips-mt7621-dlink_dir-2660-a1-squashfs-factory.bin"

*   Trying
* Connected to ( port 80 (#0)
> POST / HTTP/1.1
> Host:
> User-Agent: curl/7.74.0
> Accept: */*
> Content-Length: 8782080
> Content-Type: multipart/form-data; boundary=------------------------9e3a7ac3d8affefe
> Expect: 100-continue
* Done waiting for 100-continue
* We are completely uploaded and fine
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
HTTP/1.0 200 OK
< Content-type: text/html
Content-type: text/html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><style type='text/css'>.warning{margin:50px 0;color:red;font-size:22px}</style></head><script type="text/javascript">var percent=1;var Timer;function uiOnload(){Timer=setTimeout("upStatus()",2200);}window.onload = uiOnload;function upStatus(){percent++;if(percent > 100){clearTimeout(Timer);document.getElementById('wait').style.display = 'none';document.getElementById('result').style.display = '';return;	}document.getElementById('time').innerHTML = 'Device is upgrading the firmware...' + percent + '%';	Timer = setTimeout('upStatus()',2200);}window.onload = uiOnload;</script><body><center><div><center style='margin:50px 0;color:blue;font-size:24px'>D-Link Router Recovery Mode</center></div><div id=wait><center style='margin:50px 0;font-size:15px'><span id=time>Device is upgrading the firmware... 1%</span></center></div><div id=result style=disp* Closing connection 0
lay:none><center class=warning><span>Upgrade successfully!</span></center></div><hr/><div><center class=warning>WARNING!!</center></div></center><ul><li style='margin:50px 0 10px;font-size:14px'>Do not interrupt the update process,as it may demage the device</li></ul><hr/></body></html>

It remains with red led flashing, if after a while (10-15 minutes) I reboot the router, I'm again in the stock firmware

I own a DIR-2660 A1, Original Firmware 1.11.

I tried with the "two steps" web recovery mode upload, and this is the result.

The recovery seems to be very finicky regarding the firmware upload process, on the COVR devices I could hardly make it work anymore after updating to the latest linux kernel, not sure whether it's browsers or the network stack etc... it tends to work best on windows with ie10 and the "two-step" approach, i.e. reboot after opening the recovery page, and clicking the button after reboot (which prevents the browser from spamming the bootloader with further requests, e.g. favicon.ico and stuff).

Besides, I'm not sure whether the new bootloaders still accept unencrypted images (the COVR-C1200 don't, however they don't check rsa signature).

Does flashing D-Link OEM firmware work via the recovery?
If so, you could try an encrypted version of the latest snapshot (from 2021-10-16), this should also be flashable via the normal web interface from the D-Link firmware.

at this point it may be worth back dating you firmware
download & try to install dlink firmware a version older then current
part of this will be seeing if it will accept the older firmware
and if successful maybe then it may accept openwrt
I have not seen any firmware update the bootloader "U-BOOT"
yet but this could change
note "the RU versions do but different all together source code"