All right. It’s Saturday night, I have no date, a two-liter bottle of Shasta and my all-Rush mix-tape…let’s hack.

On a whim I downloaded firmware v1.13 for the DIR-100 revA. Binwalk quickly found and extracted a SquashFS file system, and soon I had the firmware’s web server (/bin/webs) loaded into IDA:

dir-100_loaded_in_ida.png

Strings inside /bin/webs

Based on the above strings listing, the /bin/webs binary is a modified version of thttpd which provides the administrative interface for the router. It appears to have been modified by Alphanetworks (a spin-off of D-Link). They were even thoughtful enough to prepend many of their custom function names with the string “alpha”:

alpha_functions.png

Alphanetworks’ custom functions

The alpha_auth_check function sounds interesting!

This function is called from a couple different locations, most notably from alpha_httpd_parse_request:

alpha_auth_check_call.png

Function call to alpha_auth_check

We can see that alpha_auth_check is passed one argument (whatever is stored in register $s2); if alpha_auth_check returns -1 (0xFFFFFFFF), the code jumps to the end of alpha_httpd_parse_request, otherwise it continues processing the request.

Some further examination of the use of register $s2 prior to the alpha_auth_check call indicates that it is a pointer to a data structure which contains char* pointers to various pieces of the received HTTP request, such as HTTP headers and the requested URL:

s2_data_structure.png

$s2 is a pointer to a data structure

We can now define a function prototype for alpha_auth_check and begin to enumerate elements of the data structure:

struct http_request_t
{
    char unknown[0xB8];
    char *url; // At offset 0xB8 into the data structure
};

int alpha_auth_check(struct http_request_t *request);

alpha_auth_check itself is a fairly simple function. It does a few strstr’s and strcmp’s against some pointers in the http_request_t structure, then calls check_login, which actually does the authentication check. If the calls to any of the strstr’s / strcmp’s or check_login succeed, it returns 1; else, it redirects the browser to the login page and returns -1:

auth_check_code.png

alpha_auth_check code snippet

Those strstr’s look interesting. They take the requested URL (at offset 0xB8 into the http_request_t data structure, as previously noted) and check to see if it contains the strings “graphic/” or “public/”. These are sub-directories under the device’s web directory, and if the requested URL contains one of those strings, then the request is allowed without authentication.

It is the final strcmp however, which proves a bit more compelling:

user_agent_strcmp.png

An interesting string comparison in alpha_auth_check

This is performing a strcmp between the string pointer at offset 0xD0 inside the http_request_t structure and the string “xmlset_roodkcableoj28840ybtide”; if the strings match, the check_login function call is skipped and alpha_auth_check returns 1 (authentication OK).

A quick Google for the “xmlset_roodkcableoj28840ybtide” string turns up only a single Russian forum post from a few years ago, which notes that this is an “interesting line” inside the /bin/webs binary. I’d have to agree.

So what is this mystery string getting compared against? If we look back in the call tree, we see that the http_request_t structure pointer is passed around by a few functions:

call_graph.png

It turns out that the pointer at offset 0xD0 in the http_request_t structure is populated by the httpd_parse_request function:

user_agent_struct_1.png

Checks for the User-Agent HTTP header

user_agent_struct_2.png

Populates http_request_t + 0xD0 with a pointer to the User-Agent header string

This code is effectively:

if(strstr(header, "User-Agent:") != NULL)
{
    http_request_t->0xD0 = header + strlen("User-Agent:") + strspn(header, " \t");
}

Knowing that offset 0xD0 in http_request_t contains a pointer to the User-Agent header, we can now re-construct the alpha_auth_check function:

#define AUTH_OK 1
#define AUTH_FAIL -1

int alpha_auth_check(struct http_request_t *request)
{
    if(strstr(request->url, "graphic/") ||
       strstr(request->url, "public/") ||
       strcmp(request->user_agent, "xmlset_roodkcableoj28840ybtide") == 0)
    {
        return AUTH_OK;
    }
    else
    {
        // These arguments are probably user/pass or session info
        if(check_login(request->0xC, request->0xE0) != 0)
        {
            return AUTH_OK;
        }
    }

    return AUTH_FAIL;
}

In other words, if your browser’s user agent string is “xmlset_roodkcableoj28840ybtide” (no quotes), you can access the web interface without any authentication and view/change the device settings (a DI-524UP is shown, as I don’t have a DIR-100 and the DI-524UP uses the same firmware):

in_like_flynn.png

Accessing the admin page of a DI-524UP

Based on the source code of the HTML pages and some Shodan search results, it can be reasonably concluded that the following D-Link devices are likely affected:

  • DIR-100
  • DI-624S
  • DI-524UP
  • DI-604S
  • DI-604UP
  • DI-604+
  • TM-G5240

Additionally, several Planex routers also appear to use the same firmware:

  • BRL-04UR
  • BRL-04CW

You stay classy, D-Link.

UPDATE:

The ever neighborly Travis Goodspeed pointed out that this backdoor is used by the /bin/xmlsetc binary in the D-Link firmware. After some grepping, I found several binaries that appear to use xmlsetc to automatically re-configure the device’s settings (example: dynamic DNS). My guess is that the developers realized that some programs/services needed to be able to change the device’s settings automatically; realizing that the web server already had all the code to change these settings, they decided to just send requests to the web server whenever they needed to change something. The only problem was that the web server required a username and password, which the end user could change. Then, in a eureka moment, Joel jumped up and said, “Don’t worry, for I have a cunning plan!”.

Also, several people have reported in the comments that some versions of the DIR-615 are also affected, including those distributed by Virgin Mobile. I have not yet verified this, but it seems quite reasonable.

[原文地址]

提示:xmlset_roodkcableoj28840ybtide,反过来看是:editby 04882 joel backdoor_teslmx

相关内容:

英文原文:Reverse Engineering a D-Link Backdoor

中文译文:[译文] 逆向分析 D-Link backdoor

原文讨论:

Julien says:

October 12, 2013 at 9:27 pm

WOW,

really works..

tested against one of the ip listed in shodanHQ!

Reply

Julien says:

October 12, 2013 at 9:29 pm

http://imageshack.us/photo/my-images/14/wikq.png/

Reply

Pingback: Ciekawa tylna furtka w kilku modelach ruterów D-Linka | Zaufana Trzecia Strona

Vodka says:

October 12, 2013 at 9:52 pm

It’s said in the Russian forum post:

Try to read the string backwards.

xmlset_roodkcableoj28840ybtide

Reply

joel says:

October 12, 2013 at 11:51 pm

Edit by 04882 joel backdoor

Reply

bugaloo says:

October 14, 2013 at 10:07 pm

joelbackdoor actually

Reply

Equinoxe says:

October 12, 2013 at 10:07 pm

Wow, this is insane, changing your user-agent to backdoor will gain you access.

I wonder on how many firmwares this (type of) backdoor is added.

(maybe the same string “xmlset_roodkcableoj28840ybtide” or with any other string)

Reply

Just for fun says:

October 12, 2013 at 10:18 pm

«xmlset_roodkcableoj28840ybtide» «editby04882joelbackdoor_teslmx»

http://habrahabr.ru/post/197314/#comment_6843864

Reply

Nickname says:

October 12, 2013 at 10:19 pm

I think it is old backdoor :

http://forum.codenet.ru/q58748/%D0%BF%D0%B5%D1%80%D0%B5%D0%B1%D0%BE%D1%80+%D0%BB%D0%BE%D0%B3%D0%B8%D0%BD%D0%BE%D0%B2+-+%D0%B4%D0%B0%D0%B9%D1%82%D0%B5+%D1%81%D0%BE%D0%B2%D0%B5%D1%82

last post.

Reply

Nickname says:

October 12, 2013 at 10:44 pm

Sorry it is linked in the article

Reply

Sfinx says:

October 12, 2013 at 10:32 pm

Why use this made-in-china crap at all ? I’ve stopped using more than 5 years ago after discovering the IP’s list of the DDOS network in one of the FXS devices firmware.

Reply

Moschops says:

October 13, 2013 at 8:35 am

Because it’s cheap, easy and does the job most people need it to.

Reply

Ricardo says:

October 13, 2013 at 4:36 pm

Do you honestly think that anyone cares about the fact that you are not affected by this?

Reply

J says:

October 13, 2013 at 10:33 pm

Hear, hear! We should only use good ol’ Made-in-the-USA routers so we can be sure it’s just the NSA spying on us and not those dirty foreigners!

‘MERICA!

Reply

dutch says:

October 14, 2013 at 8:37 am

Joel doesn’t sound very chinese to me

Reply

Vinzent says:

October 14, 2013 at 2:07 pm

Neither does John, yet John Lee is the CEO.

And a quick search also digs up a “Joel Liu” and a “Joel Lee”, who seem somewhat affiliated with alphanetworks. But that’s probably fake, because it is well known that Chinese parents always pick a Chinese name for their children.

Reply

Vinzent says:

October 14, 2013 at 2:13 pm

Sorry, wring link, try John Lee

Reply

Chip says:

October 12, 2013 at 11:54 pm

I wonder if this succeeds from outside even if outside management is disabled ?

Reply

Spyda says:

October 13, 2013 at 8:18 pm

Are you serious? If RMGMT is disabled, any outside attempt to even connect to the interface is rejected, so of course not.

Reply

Bear says:

October 14, 2013 at 5:50 pm

Have you tried to connect with remote management disabled? I agree that in theory you should not be able to but….

Reply

Raptors will eat you says:

October 14, 2013 at 11:24 pm

Also, if a password is enabled, all attempts without passwords are rejected, so this backdoor doesn’t exist.

Reply

josh says:

October 13, 2013 at 12:46 am

a lot of these d-link routers are facing the web and have an “admin admin” login. you can enable telnet on em too.

Reply

Pingback: Une backdoor dans les routeurs D-Link « Korben Korben

Pingback: Une backdoor dans les routeurs D-Link- Dépannage Informatique PC à domicile Limoges haute vienne 87

Pingback: Une backdoor dans les routeurs D-Link « Mes idées HIGH TECH

Pingback: Une backdoor dans les routeurs D-Link | Blog de tout et de rien

K.Alexander says:

October 13, 2013 at 3:23 am

You just seriously pissed of the NSA

Reply

Scott Arciszewski says:

October 13, 2013 at 4:49 am

Nice find!

On a sidenote, how did you go about downloading your router’s firmware? I can only seem to find articles about updating firmware when I search, nothing about downloading it.

Reply

Jens says:

October 14, 2013 at 4:26 am

To update the router’s firmware, you usually have to download it from the vendor’s support website. And that file can be reverse engineered like explained above.

Reply

RForeman says:

October 13, 2013 at 6:36 am

All the more reason to start adopting openwrt/ddwrt/tomato etc. Hard to believe this slid under the radar so long.. dir100 did you say? Ha!

Nice work Craig.

Reply

paztek says:

October 13, 2013 at 7:40 am

And appending “public/” somewhere in the URL (like in the querystring), does that bypass the authentication too ?

Reply

Craig says:

October 13, 2013 at 1:18 pm

No, as far as I can tell the “public/” and “graphic/” strings have to be in the URL itself, not in the query string. IIRC, the server checks for directory traversal too.

Reply

Pingback: Reverse Engineering a D-Link Backdoor | Boardmad

Pingback: Reverse Engineering a D-Link Backdoor | Enjoying The Moment

Mantas says:

October 13, 2013 at 8:08 am

My DSL-2650U seems to be unaffected by this specific one, fortunately.

Reply

playaspec says:

October 13, 2013 at 2:04 pm

You unit probably has an updated string, but still has this vulnerability. It would be worth capturing your current firmware and running this same analysis on it.

Reply

Pingback: codescaling | D-Link Backdoor badness

Frank says:

October 13, 2013 at 9:29 am

Well, if this was a plot by Kevin to frame Joel so he could become tech lead when the backdoor was found, he surely was playing a loooong game.

Reply

Kevin says:

October 13, 2013 at 1:33 pm

My plans for world domination !!!!

Reply

Andrew says:

October 13, 2013 at 9:36 am

Also works on the DIR-615. Just checked.

Reply

Craig says:

October 13, 2013 at 1:13 pm

Awesome! Any idea which hardware revision? DIR-615 has had a ton of different hardware revs.

Reply

David says:

October 13, 2013 at 10:08 pm

Works on my DIR-615 too firmware 1.00VG – supplied by virgin media (my isp) here in the UK

Reply

alois says:

October 13, 2013 at 10:50 am

Is there anything about this in the supplied sources?

Reply

ccpz says:

October 13, 2013 at 11:04 am

Also find some clues at DLink’s GPL source code:

http://tsd.dlink.com.tw/downloads2008list.asp?t=1&OS=GPL&SourceType=download

For example, the GPL code of DI-524UP contains config.log,

which includes these magic strings DBACKDOOR_SIGNATURE & DXMLSET_BACKDOOR_USER_AGENT

https://gist.github.com/ccpz/6960941

Reply

ollie says:

October 14, 2013 at 1:25 pm

Knowing now what to look for, both the backdoor key and Joel (judging by the source code comments, obviously a developer at Alphanetworks) can be found all over that source package

Reply

amir says:

October 13, 2013 at 11:08 am

couldn’t confirm this on d-link 655

Reply

Joe says:

October 13, 2013 at 11:11 am

This is most likely a backdoor for the installer CD, though it’s a mystery as to why they don’t use simple HTTP authentication.

Reply

Craig says:

October 13, 2013 at 1:20 pm

That was my first thought too, but after some searching it looks like a lot of the affected devices don’t come with those “auto-setup wizard” tools.

Reply

orthello says:

October 13, 2013 at 11:15 am

Also the Dlink DIR-655 is conformeren to be vulnerable for this type of attack.

Reply

orthello says:

October 13, 2013 at 11:19 am

Sorry…. Is not.

When session is still active you can relogin with any password. This confused me.

Reply

Matt says:

October 13, 2013 at 12:23 pm

Excellent article. Makes me want to dig into some binaries.

Reply

Deepak says:

October 13, 2013 at 12:32 pm

Holy shit!

Good job, man! That’s one heck of reverse engineering. Wondering if D-Link updates their firmware soon in response to this.

Reply

Craig says:

October 13, 2013 at 1:10 pm

My guess is probably not. Most of the affected devices seem to be older and have been end-of-lifed, so people still using them are SOL.

Reply

Shane says:

October 13, 2013 at 1:29 pm

Just changed the name of my neighbors router to “bigblackdix”.

Reply

Barry Kelly says:

October 13, 2013 at 2:06 pm

Your server, or page, is ignoring user requests for desktop view on mobiles – tested with Firefox and AOSP on Android 4.3.

Your articles have forcibly disabled zoom, so the images are not entirely visible from phones.

Reply

youdontneedthat says:

October 14, 2013 at 12:09 am

just double click the images

if you double click the code windows you can scroll to the side

Reply

eekee says:

October 14, 2013 at 3:09 am

On my phone in any browser, double-clicking images scales them, but does not scale them to useful sizes. Most of the images on this page (for example) are shown in a choice of 1/4 screen width or full screen width. The screen is 2.25 inches wide.

Reply

eekee says:

October 14, 2013 at 2:53 am

On the desktop with Firefox 24.0, ctrl+ and ctrl- work here.

On my Android phone I can confirm your problem in Opera. Even in mobile view, pinch-zooming isn’t working.

Reply

Denis says:

October 13, 2013 at 2:51 pm

Please could someone check with your devices, seems you do not need to use any ‘backdoor’ feature there.

Seems it is enough to have ‘public/’ or ‘graphic/’ substring in the URL, something like:

IP/public/..

or perhaps

IP/?public/

Reply

Craig says:

October 14, 2013 at 1:38 am

I don’t think this will work. The ‘graphic/’ and/or ‘public/’ strings need to be in the requested URL (not the query string), and the server checks for directory traversal elsewhere in the http request parser. I did some preliminary (but not complete) testing without any luck.

Reply

Neal Krawetz says:

October 13, 2013 at 3:35 pm

Just checked on a DI-604 (not 604S, 604UP, 604+…) — it does NOT work on the plain DI-604.

Reply

bob says:

October 13, 2013 at 3:36 pm

can anyone recommend a nix debugger that I could play around with the dlink firmware? Looks like there is an IDA version for linux, but you really need the pro which costs a ton.

Reply

eduard says:

October 13, 2013 at 7:48 pm

radare2 radare.org

Reply

Craig says:

October 14, 2013 at 1:58 am

GDB also works well, and there’s a nice gdbinit script for MIPS here: https://github.com/zcutlip/gdbinit-mips

Reply

bob says:

October 14, 2013 at 4:36 am

no BSD version so its basically useless

Reply

Craig says:

October 14, 2013 at 4:57 am

Are you saying there’s no radare2 for BSD or no GDB for BSD? I thought both were available for the BSD platform.

Reply

darkkal says:

October 13, 2013 at 5:42 pm

Great work!

Reply

akp says:

October 13, 2013 at 6:08 pm

Good analysis. Does this remain in subsequent firmwares? (v1.13 was deprecated in 2006)

Reply

leoj says:

October 13, 2013 at 7:51 pm

$ unsquashfs 9DB90.squashfs /tmp/9DB90/

Reading a different endian SQUASHFS filesystem on 9DB90.squashfs

Parallel unsquashfs: Using 4 processors

gzip uncompress failed with error code -3

read_block: failed to read block @0xfe1c5

read_fragment_table: failed to read fragment table block

FATAL ERROR aborting: failed to read fragment table

:’(

Reply

jmp says:

October 13, 2013 at 8:16 pm

Good job man, openwrt is the only way.

Reply

DJ says:

October 13, 2013 at 8:44 pm

These are all Phased Out routers, accept for the DIR-100 in EU and is not sold in the USA, that are no longer in development nor marketed and may not see any fixes for this. I notice also that there are no newer gen routers listed or tested for this hack either. IF your concerned about this, I recommend that you phone contact your regional D-Link support office and inquire to check to see if your model router is actually effected by this.

Reply

Craig says:

October 14, 2013 at 1:55 am

Yes, the affected routers all appear to be older models. Probably no longer supported, so they won’t be getting firmware updates.

I guess you could try contacting D-Link. I doubt they will know what devices are affected though. They don’t write the firmware anyway, and based on my previous interactions they have no way of tracking which devices use the same, or similar, firmware.

Reply

Phil says:

October 13, 2013 at 9:19 pm

I’m trying to duplicate your work found that the SquashFS filesystem is compressed with LZMA (not LZMA2/XZ), which is no longer supported. I cannot find a way to decompress it. How did you do mount it?

Reply

Craig says:

October 14, 2013 at 1:52 am

I used the unsquashfs-2.1-r2 utility in the firmware-mod-kit (https://code.google.com/p/firmware-mod-kit/).

Reply

Pingback: Wenig überraschend, finden sich Backdoors nicht nur in TP-Link, sondern auch in… | Die wunderbare Welt von Isotopp

Pingback: Une backdoor dans les routeurs D-Link | Lepuil Lepuil

Pingback: Una puerta trasera en equipos D-Link al estilo NSA

Pingback: ste williams – Back door found in D-Link routers

Pingback: Reverse Engineering a D-Link Backdoor – /dev/ttyS0 | Boardmad

Pingback: d-link router users - security issue - Pelican Parts Technical BBS

Pingback: Backdoor found in D-Link router firmware code

Pingback: rushengine.com | Backdoor found in D-Link router firmware code

James says:

October 14, 2013 at 5:20 am

Good work.

Checking:

DIR-615 Hardware Version: E3 Firmware Version: 5.10

Does not appear to have this vulnerability.

Reply

Pingback: D-Link router 'backdoor' - www.hardwarezone.com.sg

Jasen says:

October 14, 2013 at 5:39 am

for an internal-use backdoor they should have checked the

IP-address of the client.

It’s much harder to fake 127.0.0.1

Reply

Pingback: Alpha Networks Inc. Want to Backdoor Your Router | Subversive Bytes

mattjs says:

October 14, 2013 at 6:27 am

Yeah you’re right some special and reserved IP addresses like 127.0.0.1 should in general be neither routed nor indeed even route-able on most hardware (other than DLINK’s of course HAHA…)

Reply

Pingback: Detectada una puerta trasera en routers D-Link - tuexperto.com

Pingback: Cool Math Games » Backdoor found in D-Link router firmware code

rootless rooter says:

October 14, 2013 at 6:59 am

D-Link 100,firmware 1.13 [most recent] rev.A,supplied by T-Systems in Czech rep.

status : confirmed and working.

nice nob,man!

Reply

tamarack day camp says:

October 14, 2013 at 7:44 am

I’m extremely impressed with your writing skills as well as with the layout on your weblog. Is this a paid theme or did you modify it yourself? Anyway keep up the excellent quality writing, it is rare to see a nice blog like this one today.

Reply

Pingback: เราท์เตอร์ D-Link หลายรุ่นมีช่องทางล็อกอินลับ | Webtheboy.com เว็บไซต์วาไรตี้

Peter Hurst says:

October 14, 2013 at 11:46 am

This appeared to work once with a DLINK 2640R but only when I entered the xmlset_roodkcableoj28840ybtide User string in IE9 and used compatibility mode. Then for no reason it stopped again.

Reply

Hans Munister says:

October 14, 2013 at 12:32 pm

Does not work on my DI-524

Request:

————-

GET / HTTP/1.1

Host: 192.168.1.2

Connection: keep-alive

Cache-Control: max-age=0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

User-Agent: xmlset_roodkcableoj28840ybtide

Accept-Encoding: gzip,deflate,sdch

Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4

————–

Response:

————–

HTTP/1.0 401 NG

WWW-Authenticate: Basic realm=”DI-524″

————–

But this has tought me to buy a new router anyway. Fritzbox ?? Any suggestions ?

Reply

Android Apps for pc says:

October 14, 2013 at 3:19 pm

Fantastic blog! Do you have any tips for aspiring writers?

I’m planning to start my own website soon but I’m a little lost on everything.

Would you recommend starting with a free platform

like WordPress or go for a paid option? There are so many options out there that I’m completely overwhelmed ..

Any recommendations? Thanks a lot!

Reply

Pingback: Have a D-Link Router ? You may be compromised | New Technology Update

Pingback: Yebaa.com | D-Link to padlock router backdoor by Halloween

Pingback: D-Link to padlock router backdoor by Halloween

Pingback: D-Link 路由器有人為植入的後門,無需密碼可進入管理頁面 | 網絡安全與隱私

Pingback: 轉貼:D-Link 路由器有人為植入的後門,無需密碼可進入管理頁面

someone says:

October 14, 2013 at 8:17 pm

Well, I have a DIR-100 and it doesn’t work for me for some reason. (I changed the UA in the Chrome Settings and tested the changes on a website that displays the UA)

Hardware Version : E1 Firmware Version : v4.00TP

Reply

Pingback: Backdoor Found In D-Link Routers - Internet4k : : Internet For Knowledge | Internet4k : : Internet For Knowledge

Pingback: Makl Ndrix » Blog Archive » The closeness of software, and its dangers.

Chupacabras says:

October 14, 2013 at 9:40 pm

I have tried it with DI-524 but this backdoor doesn’t work.

Firmware Version: V2.06-orange , Wed, Jul 25 2007

Reply

Pingback: Backdoor en routers D-Link - | Indagadores |Seguridad informatica |Seguridad en internet

DIR-632 owner says:

October 14, 2013 at 10:31 pm

Confirmed that DIR-632, hardware version A1, firmware version 1.02, is not vulnerable.

Phew!

Great work, Craig.

Reply

Stanley Ang says:

October 14, 2013 at 10:53 pm

That’s why you should use OpenWrt.

Reply

Pingback: Backdoor encontrada em roteadores da D-Link atinge milhões de usuários | TecnoGeek – Novidades Tecnológicas

Pingback: D-Link to padlock router backdoor by Halloween

danzhu says:

October 14, 2013 at 11:44 pm

My DIR-619L is also affected,firmware version is 1.15.

Reply

Pingback: D-Link to padlock router backdoor by Halloween : My Creative Directory

Michael says:

October 15, 2013 at 1:04 am

Nice write-up!

And +1 for the Futurama reference.

Reply

Pingback: D-Link routers found to contain backdoor

Pingback: D-Link to padlock router backdoor by Halloween | raynermkx479