A More Universal Router Payload – Backdooring the Linksys WRT54G Firmware

Recently I’ve had an interest in trying my hand in embedded device hacking. I decided that I’d pick up something I know to start with. After searching eBay I decided on the popular Linksys WRT54Gv5 router. After personally using this router for years I figured it’d be a nice familiar place to start.

No place like 192.168.1.1!

No place like 192.168.1.1!

My first goal was to reverse engineer the firmware to get a better idea of what the internals looked like. This turned out to be a pain as apparently Linksys doesn’t host the firmware anymore and due to the firmware being copyright protected nobody else does either. Which is an idiotic thing by itself but eventually I was able to find a stock copy. I flashed my router with it to keep it consistent and began analysis of the firmware.

Analysis

After reading a bit from the http://www.devttys0.com/ blog I decided to use binwalk to analyze the firmware file.

Here are the results:

Full pastebin here

So, after seeing this I counted myself pretty lucky, here is a breakdown of this data as I understand it:

  • At offset 0×200 we have our MIPS bootloader
  • Offset 0x18D10 is a copyright string for Wind River Systems Inc. this is important because they created the Vxworks Operating System which this router uses
  • Offset 0x194F0 is the Vxworks OS/filesystem which I currently have not been able to disassemble (due to it being a proprietary and largely undocumented filesystem, at least from what I could see)
  • Tons of flat files like “apply.htm” all gzip compressed

Visually our firmware looks like this:

[ Bootloader ] [ Copyright String ] [ VxWork OS & Filesystem ] [ TROC Filesystem Entry ] [ gziped htm/image files ]

What makes us lucky is the fact that the gzipped files are concatenated one after another. This allows us to know where each file ends and starts. The offsets are determined by the magic number signatures for the different filetypes. These are simply a couple bytes that mark what type of file is being used. So for example the bytes for the gzip format are 1f 8b – binwalk finds these and lists where in the binary they are located.

Great, so now we can get to the fun part. Logically, we should be able to slice out files and replace them as long as the size is consistent. This is probably not necessary but it’s a worst case scenario (say, if they actually depend on certain offsets for updates).

Chop Chop!

A little bit of dd and we can chop one of the .htm files out of the router for modification. Binwalk has a built in extract function but I could not get it to work properly (attempt it yourself to see what I mean).

We’ll start off with something simple first, let’s cut out just the “Unauthorized.htm” file and the “lastpassword.htm”. I have no idea why “lastpassword.htm” is actually in this firmware but it will display the current router’s password in cleartext. Perhaps a leftover from fun debugging when this firmware was being built.

“lastpassword.htm”:

“Unauthorized.htm”:

You’ll notice this bit in the “lastpassword.htm” file:

That tag will be replaced with the current router password, so perhaps we will put it in Unauthorized.htm! That way we will always be able to take control of the router regardless of password changes.

Remember, because we’re being paranoid we will ensure the file is the same size as when we started. It’ll be a little bit of a pain due to compression being used on the .htm files, but it’s not too bad.

After a bit of fiddling we end up with:

After a quick ls we can see the files are exactly the same size:

Now reference our binwalk data:

So we’ll cut before and after the original “Unauthorized.htm” file and then we’ll rebuild with cat.

Great! Of course we should double check all is consistent but upon rebuilding everything we can go ahead and flash the firmware!

flashing_firmware

I’ll admit the first time I did this I was pretty nervous it wouldn’t work. However it all works out fine (and why wouldn’t it?).

The firmware has been flashed but did it work?

basic_auth_prompt

We simply cancel this dialogue and get the not authorized page:

unauth_page

Upon viewing the source we have the password in cleartext wrapped in HTML comment tags like we specified:

unauth_html_source

Perfect! We now have persistent access to the router in a pretty stealthy way. But this isn’t universal or useful on a larger scale, what if we want a payload that works more like a botnet?

Backdoor

In search of a more universal backdoor we will make this one completely Javascript. Javascript is a good option due to the fact that it is not platform dependent (MIPS assembly payload wouldn’t work on a non-MIPS router etc). It also provides us with enough functionality to change all of the built in setting to whatever we please (via XMLHTTPrequests, etc.). While we won’t be able to preform DoS attacks we will be able to do important things like control the router’s DNS server. Control over the router’s DNS is valuable to malware authors who can use this to do network wide adware/malware attacks. This is because most computers will simply use the DNS that the router chooses, so it’s much more efficient to simply hack the router than all of the individual computers. This sort of attack has already been preformed in the wild by malware like the Zlob trojan, which turned out to be very effective.

So, let’s get to it!

The homepage of the router is the “basic.htm” file, upon logging in the user is immediately directed there. So if we backdoor that page we will have a good level of persistence. We will make a payload that will send the username and password back to our control server and also enable remote authentication on port 1337.

After a bit of Javascript coding and we have something usable:

In two requests we will both set remote control and send the username and password back to the botnet server.

Using the same method as before we trim off all excess space and useless HTML (lots of commented out code in the production firmware, it’s pretty horrifying). Then we will pack it back into the firmware (remember: we must ensure the files are the same size).

Another flash and wallah! We have our new backdoored firmware!

router_backdoor

Granted this is just a proof of concept, the real backdoor would probably contact a C&C for further instructions/fresh set of DNS servers.

Much more simple than you’d think, most router firmware that I’ve analyzed can be modified in this same way.

Until next time,
mandatory

7 comments

  1. The telephone used to have a phone number you called to set you watch. It gave the time. “At the tone, the time will be….”

    This site is run by the national institute of standards and gives one random number every 60 seconds.

    http://www.nist.gov/itl/csd/ct/nist_beacon.cfm

    Read the output hex bytes.

    http://beacon.nist.gov/home

    If you enter the UNIX time (seconds since Jan 1970)

    http://beacon.nist.gov/rest/record/1393143360

    You get the random number for any minute in the past.

    There is no way this can be messed-up unless you think I own NIST. You can check the number yourself with your own router. Are you retarded. It’s like you think I hacked into the phone number for time and made the time wrong.

  2. Thanks for a great post!

    One question from a n00b, how important is it to keep the size of the chopped part? Do the router chop it in fixed sizes as well and if you don’t keep the size it’ll break?
    If so, is that true for the last part as well?

    I was wondering since I’ve played a bit with a D-Link 4G modem: http://oskarhane.com/inspecting-the-firmware-of-a-d-link-dwr-923-4g-modem/

    I just don’t have the balls to try it and possibly brick the modem :)

    1. Hey Oskar,

      Cool post – I love looking through router firmware, usually it results in some interesting finds (especially when you start throwing things in IDA).

      As far as keeping the size of the chopped parts…it depends. I’m super paranoid, so if it’s worst case (they do extract via offsets) then it’s important but that’s probably not how it works in most cases. It wouldn’t really make sense to do it based off firmware offsets but I also see a lot of very weird production coding. I’d be more worried about checksums that need to be verified (ie. some sha1 hashes in the browser header that need to be changed to match the rest of the firmware).

      Long story short no, the sizes shouldn’t break it. However making it too big could be a problem. Personally there is a reason I bought a 20$ router to backdoor and not a 100$ router ;)

  3. Best option as not all backdoor present already can give better control option than yours if it use with some command and control.That way if any router compromised either by default firmware or by hacker exploit SOHO routers security will be compromised permanently.This can make junk Chinese router manufacturers have to put extra efforts on their firmware writing or have to surrender their market share for good manufacturers who cares and effort for customers like cisco.
    Are u by any chance demonstrating this year defcon 22 router hacking competition???MY honest opinion your payload if use with any C&C is down right baddest badassness which they want in competition.Just In case the link of it http://sohopelesslybroken.com/

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">