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