Hacking the D-Link DI-524 Interface

by der_m

Here's an example of the practicality of the hacking mindset.

It's easy to forget that 90% of hacking is scratching your head in confusion and digging to find the answers to that confusion.  About a year ago, I bought the D-Link DI-524 wireless router from Best Buy for about $15.  I figured that was a steal I couldn't pass up!  It even came with an USB adapter!  I could resell the adapter, since it wouldn't work in Linux anyway, and maybe get a free router out of it!

A year later, when I actually had the Internet connection to use it on, I discovered exactly why the router was so cheap: the web interface refused to encrypt my wireless connection!  That's a very important feature D-Link neglected to enable!  So I tried to Telnet in.  Connection refused.  SSH?  No.  I checked for a firmware update... but D-Link practically disavowed the existence of this thing.  The most they could give me was an emulator for the interface, which confirmed that I had what appeared to be the latest firmware, cheap garbage that it was.

So for about a month I secured my wife's wireless through obscurity alone, by disabling SSID broadcast and allowing only our two MAC addresses to connect.  (There's not much traffic on our street - still not forgivable.)  I sat next to our TV wired, because my old Wi-Fi card couldn't connect to a non-broadcast signal.  Finally, I decided to take the time to figure this out.

The DI-524, like most modern routers, was configured through the web browser.

I use IceWeasel (pronounced "Firefox"), so I could type Ctrl+U and handily look at the HTML.  I didn't have that many clues, because JavaScript sucks for debugging and D-Link wasn't very forthcoming with error messages.

However, I noticed that when I hovered the cursor over the "Apply" button, my status bar said: javascript:send_request()

So I searched the HTML for "send_request".  Here's what I got:

function send_request() {
  if (precheck_key() && check_wpa()) {
    get_by_id("apply").value = "1";
    form1.submit();
  }
}

As you can see, send_request() confirmed precheck_key() and check_wpa() both returned TRUE, then made the value of apply TRUE, and submitted the form.

Therefore, either precheck_key() or check_wpa() was messing something up.

check_wpa() was about 40 lines of code... so I glossed right over it.

That's right - you're allowed to do that in hacking.  (In hindsight, I actually looked over the code, and it turned out that it confirmed that you retyped your passphrase correctly, and weren't using "1234," or something stupid like that.)  So, I Ctrl+F for precheck_key():

function precheck_key() {
  var auth = get_by_id("auth");
  if (auth.selectedIndex == 0) {
    return true;
  }
  else {
    return check_key();
  }
}

I ventured a guess that the function get_by_id() was a nice way to call document.getElementById(), so I typed this into the location bar on IceWeasel:

javascript:alert(document.getElementById("auth"))

A dialog box popped up and behold: [object HTMLSelectElement]

I went a step further and typed:

javascript:alert(document.getElementById("auth").selectedIndex)

Now the dialog box returned "3"... but what does that mean?

A quick Google search told me that selectedIndex is the index of the value a drop-down menu has chosen.

I looked again at the webpage, and saw that the fourth option, WPA-PSK, was the "3" it referred to, and so I mustn't change it.  (Remember, "0" is "1", and "3" is "4".)

So then the if/then/else clause runs check_key().

Ctrl+F through the source code, and found this was the only reference to check_key()!  Way to go D-Link!  That would certainly explain why the authentication failed.  So I determined that all those checks could be bypassed and proceeded to the "then" clause of the send_request() function to see if I could manually do it.

I typed into the location bar:

javascript:alert(document.getElemntById("apply").value)

The dialog box popped up "0".  Thus, I set the value:

javascript:alert(document.getElementyById("apply").value = 1)

and typed in that previous step again to confirm that I actually did reset the value.  So far, so good.

I typed:

javascript:alert(form1.submit())

Aha!

The webpage changed, indicating the router was restarting.  15 seconds later, it showed me that all was well!

I overcame D-Link's idiocy and have a working, encrypted , wireless router!  I now connect happily to a broadcast wireless connection through "wicd" and can keep my laptop, along with my mess, out of the living room, which also gives me a happy wife!

Shoutouts to the Revolution, phalkon13, suncrushr, nocturn, ziddar, angelsteed, abbot, stas, "TWO-FO", and my fellow sleeper agents.


Bug appears to be fixed with updated firmware: legacyfiles.us.dlink.com/DI-524/REVE/

	 1797532 DI-524_REVE_FIRMWARE_5.10.ZIP
	 4860859 DI-524_REVE_MANUAL_1.00_EN.PDF
	 3068662 DI-524_REVE_QIG_1.00_EN.PDF
	16394304 DI-524_REVE_ROUTER_SETUP_4.00.EXE
	 1790969 DIR-524_REVEx_FIRMWARE_5.13.B01.ZIP
Return to $2600 Index