 My name is Michael Coppola and I will be presenting Owning the Network Adventures in Router Root Kits. Start off just a little bit who I am. I'm a security consultant at a small consulting firm, virtual security research out of Boston and just a side note we are hiring. I'm an undergraduate at Northeastern University. Just in the past I've done some stuff, played some competitions and won some of them. And if you want to see more information about this talk, as well as some other work I've done, my site is pop-pop-ret.net. So a little bit, how did I come on this topic? How did this all start? A year ago I was on a penetration test and I came across a device called a MicroTik router. Basically MicroTik is a brand of router that's based on a very minimalistic Linux distribution but there's a lot of stuff going on in user lands. Specifically, one thing of interest is that you can install modules on these routers through the MPK packages. So you can install new features like a SOX proxy, a VPN, IPv6 support, and even do crazy things like virtualization on the router itself. So this got me thinking, if we can install code on these MicroTik routers, even if they're vendor provided, what happens if we're able to create our own MPK package and possibly execute our own code on the device? Can we get a root shell? And this got me thinking. Unfortunately, there wasn't, the work done on MPK packages was mostly done on, the existing work was mostly done on very old versions. I believe it was version two of the MicroTik router. And there's not very many of those around. But version two, you can basically blow apart MPK package, stick your own code in, package it and run homebrew software on the device. But newer versions, I believe three or four, version three or four, the MPK format had an extra layer of encryption and no one had really figured that out yet. But they got me thinking, if this idea could be applied to MicroTik routers, why not apply it to all consumer routers? As many of you have probably seen this page or something similar to it on your consumer router, you can download an update for the firmware from Netgear site or the Belkin site or D-Link site and basically reflash the router through the web interface and you get a newer version of it. But what happens if we take that version of the software right off of the firmware, right off the vendor site, manipulate it to install our own code in a reflash of device through the web panel? So the big question brings us to can a universal process be developed to modify SOHO router firmware images to deploy malicious code without altering the interface or functionality of the device? And in hacker circles, we like to call this a root kit. So the intentions of this talk, I'm not going to teach you how to be a super early hacker. I'm not a reverse engineer but I'm going to share my experience pursuing a topic in a challenge I encountered, the mistakes I made and hopefully you guys can take something away from this talk, go home and do the same stuff that I was able to do, gain some better insight into the internals of the routers and release a project, release a project that I've been working on for the past number of months to help facilitate basically the back dooring of routers. And at the end, we'll do some demos, we'll pop some shells and put some devices. That's why everybody's here. So some prior work before getting into this, I wanted to see what work had already been done. Three main areas that I found a lot of help with was the open WRT and DDWRT communities. They've done a lot of work with custom firmware, homebrew firmware, a lot of reverse engineering and profiling of the router devices and the firmware that runs on them as well as a project called the firmware mod kit and basically it's a conglomeration of a lot of tools that help deconstruct and reconstruct firmware images and as well as the Site Dev TTY S0. They've done a lot of firmware modding, reverse engineering as well as exploitation of routers and embedded devices in general. So what are the use cases or something like this? I'm sure as many of you have seen out in the field or in a pen test, a lot of things have default passwords, admin, admin, admin password or just no password at all. Especially home routers. Plug them into a network, plug your computers in and you go. Basically, if you have access to the admin panel, what's the worst that you can do? You can forward some ports if you really wanted to. You can toss a network, but that doesn't help somebody who actually wants to further their exploitation of the network. So as well as if there's a vulnerability in the rider itself that gets you access to it, whether it's at the command level like a shell or just access to the admin panel through remote code execution or an auth bypass. I believe the two talks after me will actually be doing more of that stuff. As well as one vector which I didn't look much into but seems very possible is actually CSRFing the file upload. You can iframe the, put an iframe to a default IP 192.168.1.1 as well as a default password which is probably going to be there. And you can CSRF the actual uploading of firmware. So browse to a website and you get owned. Not just your computer, not just your browser, but your entire network. So a couple of routers that I looked at specifically for this project. The WNR 1000 version 3. It's made by Netgear and it uses the proprietary Netgear CHK format which will go into a little bit more later for the actual structuring of the firmware image. It uses MIPS architecture and as we'll see almost every consumer router out there, at least I was able to use was based on MIPS. And these use really old versions of Linux which is great. This one was used in Linux 2.4.20 which I believe came out in November 2004, 2002. And that's really old. It uses the common firmware environment boot loader as well as for the read-only SquashFS file system version 3.0. The next router that I looked at was a WGR 6.4 version 9. Pretty much same specs across the board except this is using an even older version of SquashFS. The next router was the Belkin FD5 7234 with version 1110. It uses the extended firmware header format which is proprietary to Belkin I believe. Again MIPS, the same old version of Linux, the same boot loader but this uses the read-only KramFS file system. And as well as the TrendNet TW 652 BRP version 3.2R this uses the proprietary Realtek firmware format. Again MIPS using a newer version of Linux 2.6 but I believe this one came out in 2006. It's still pretty old. For a boot loader it doesn't use CFE but instead it uses the DASU boot loader and uses a newer version of SquashFS. So basically what's the generalized technique that it came up with? The five points to pointage, profile the image, extract the parts from the image, deploy the payload, repack the image and update the metadata in that order. It seems fairly intuitive when you break it down like that. But going from zero to the end product it took a lot of playing around, a lot of trial and error and this is by following these steps you can essentially use the same generalized technique and approach any firmware image whether it's been already reverse engineered or not. So before we even started or before I even started working on this project we needed to basically see, obviously we're going to be reflashing the device but obviously we're probably going to be reflashing it with something that's not supposed to be flashed with. So what happens when we break the device, how are we going to recover from it? You're not going to go out and buy 50 routers at $20 each. So one thing that I found out was that nearly every consumer router that I found, they offer a serial port on the circuit board itself. There are four or six or any number of solder pads on the device and basically you have to do is find the terminals, solder the connectors and you get a root shell as well as access to the boot loader and it lets you profile device, lets you view the startup sequence and view more information about what hardware is actually running on it and what specific software is running on it. It lets you test new payloads fairly quickly and easily as well as debugging when payloads go wrong or when reflashing the device goes wrong in case it rejects the firmware that you tried to reflasher it with or it just doesn't work at all. And again the boot loader, by breaking to the boot loader, it gives you an easy recovery, a quick testing of new firmware images and we'll go into how that works very soon. So basically connecting to the console, you're looking for four pins, ground BCC which is positive voltage, TX, RX for transmit and receive and just for example on the WGR614B9, these six pins at the bottom left constitute the serial port but we only care about four of them. A closer look, we have VCC, RX, TX and ground. This can mostly be found usually by trial and error just by trying every possible configuration of connecting the pins to the solder pads but if you want to do it intelligently there's also, you can use a multimeter and first find ground and then find a positive voltage testing for resistance and then basically trying every configuration for RX and TX. So basically this would be the serial pin out for the WGR614B9, we have the four pins and we're going to connect ground to ground VCC to VCC but we're going to cross TX and RX because you want the transmitting side to go to the receiving side and the receiving side to go to the transmitting side and basically this very simple circuit of crossing TX and RX is what constitutes a null modem but we run into a problem, we can't directly connect to the router because computers run at 12 volts and routers run at 3.3 volts and if you connect it directly it's going to fry the router and that's not very constructive. So what we need to do is introduce a voltage shifter into the circuit to prevent damage and facilitate this communication. So luckily Spark Fun has these little kits you can buy for seven bucks, they're really fun solder projects, put them together, you plug in a serial cable on one side and you have your four terminals on the other side and this is the end result of what it looks like, fairly simple, you have some LEDs that show when communication is going and this is what it looks like actually solder to the board. You don't really want to solder directly to it because these are very small and fragile solder pads. Usually you want to, one thing that people do is they actually use a microphone jack or headphone jack and then you can have one of those on either side and just plug it in and you only have to solder at once. But as you see we have ground and VCC on either side connected to each other and RX and TX are crisscrossing. So again receiving goes to transmitting and transmitting goes to receiving. So by doing this you can see we put up the router, we connect to the serial console and we have a root shell. Obviously this doesn't help us for the end product but it lets us mess around with the router, see what's on the file system, see what's running in the kernel and basically lets us do some debugging with real feedback in real time. So this is once the router has booted up and the next one is actually breaking to the boot loader. As you see we broke to the CFE prompt just by holding down control C at the initial boot up sequence and if you run the TFDPD commands in CFE we'll actually start listening on a TFDP server and you can send firmware images over Ethernet to it. It will write that in there, do some integrity checks, tell you if the checksums are wrong and tell you what it's supposed to be and then if everything works out it will reflash the device, write it to memory and then try to boot into it and then you have real time feedback to see if your firmware works or not and what to do to fix it in case it doesn't. So now we have ways to recover, we have a way to debug, how are we going to do the first step, profiling the actual firmware image itself. So this question that we have is basically what exactly makes up this giant blob of binary? We download something from that gear and it's just a .bin file, it's a .chk file and you have no idea what it is. Is there a boot loader in there? Is it a kernel, a file system? These concepts that we know run on this device but we don't know exactly where it is located and early attempts to find these items were crude and limited in helpfulness, basically run strings on it, run hex dump, run file on it but nothing really gives us any tangible feedback. One thing that we can notice immediately is that there's this string, it looks something like a serial number or a model number and it says netgear at the end but again that's just something interesting, it doesn't actually give us any tangible feedback on where to go from there. So if we ran a file at the file command at offset zero and that didn't help us, what happens if you run the file command at every possible offset? Basically, will we be able to find a file system? Will we be able to find a kernel? And no we can't because it's a giant mess, there's tons of false positives and if you actually filter all the false positives you still don't have any data that actually helps you. But luckily doing some research online there's this great tool called BinWalk. I believe the FRAC FRAK talk the other day actually integrated with BinWalk as well. Basically, this tool identifies headers, files and code inside just generally files but specifically suited towards firmware images. It uses a mix of lib magic and custom signature database in order to detect these headers and it's made by the great guys at TTY-0. And the best part is that BinWalk runs in seven seconds and my script ran for two hours and it got amazing results and it was accurate right off the bat. So we see here we have a TRX firmware header, we don't know exactly what that is but maybe we'll look at it a little bit later. We have this blob of LZMA, we don't know what it is but we'll look at it later and we have this file system using the read only squash FS format. This is something that we can work with and we'll look at that next. So basically extracting from the image, how are we going to take these items and work with them from this giant blob. We want to, in this specific image, we want to extract the headers, the LZMA blob and the squash FS file system. Fairly simple, just use DD. We'll start off at zero because we're fairly certain there's going to be a header even if it didn't detect it. It has to be something off at zero. And we'll take the first 86 bytes to include the first header and the TRX header. Simple. Second one, just take the LZMA blob and you don't have to worry too much about how big it is because LZMA will actually disregard any garbage at the end of the file. And we take out this blob, we decompress it and run strings on it and lo and behold here is our Linux kernel. Maybe we can work with this a little bit later. And extract the squash FS file system. Again, just find the offset and extract it. And now the next step is going to be unpacking the file system because that would be the easiest to work with. And if you need to find a way to unpack squash FS, basically we use the unsquash FS utility. And firmware market has a great collection of I believe almost every unsquash FS utility that's available publicly on the internet. Ones that are both open source also proprietary patches that vendors add to squash FS for their own firmware images. But the only problem is that none of them worked. So what are we going to do? The great thing about these routers is that I believe back in 2009 there was a big issue with the fact that all these routers were running Linux, they're running busy box, they're running squash FS, all open source GPL software, but they're not releasing source code for them. So 2009 everybody basically was forced to release their source code. So we can go online to net your site, download the source code for this router, and look for maybe this unsquash FS utility is in there, but it's not. And we see there's no unsquash FS.C in this directory, but we know that it's supposed to be there because it's in the make file, but they removed it. So there's a couple different options that we could basically take at this point. We can try to reverse engineer the actual proprietary patches that Netgear added to this specific squash FS archive. Or maybe we can keep looking online for something that firmware market doesn't have, but again that didn't work. And I usually like to not put forth effort if it's not necessary. It's part of the whole lazy hacker thing. But so why don't we just ask Netgear for the utility, maybe they'll come through. So we send off a little ticket, basically say hi. I believe that this utility is supposed to be in here, it's not in the source code. May I have it please? And the response is I'm sorry that we cannot modify the source code of this router because it's not an open source. And first of all, that makes no sense. Just English wise. And second of all, the source code is available. That's the reason I'm sending the ticket in the first place. So I send the reply. Thank you. I believe that this is GPL, however. Please release the source code. And he replies, he sends me a link on Netgear site and possibly, oh, maybe this is our answer. Maybe there's some different source code that I didn't see on the site. And he sends me a link to the former download page. All right. So I'm like two weeks into this already. And I'm getting kind of frustrated, but I'm still being polite. So I ask, can we escalate this ticket to technical, like to second level technical support, somebody who isn't just reading off the script and possibly get some actual answers. So he escalates the ticket. Two weeks later I get a reply. Here is the download link to the file you requested. And it worked. So if there's any lesson to be taken away from this, it never hurts to ask and you don't know what will happen. All right. Great. Next step, deploying the payload. We have this unpack file system. How can we deploy a payload into this thing and then put it back together and then get code execution on the device. So just looking at the environment. We have a minimalistic Linux system. We have two vectors. We can do this through user land, which is dirtier, quicker, more portable. You can run a single binary across every device because it's the same architecture. It's all Linux. Or you can do kernel land, which is stealthier, but you have more development considerations and it's less portable. You have to tailor it to each specific device. So just looking at user land is very simple. Just do a quick backdoor code and see. Drop it on the file system. Again, you have the same one binary, which is executable across nearly every device. You have the file, but you have a problem. The file is visible. The process is available, visible. But honestly, who cares? No one's going to see the file system. No one's going to see the process list unless you solder into the pads, which at that point is probably sitting in an FBI office and some friends at person's desk. But one problem which might come up is that there's a small subset of routers where you can actually view the list of currently active connections. I didn't come across that very often, but I know that my own home router does that. So something that we should consider. So how can we combat this? Well, at that point, we're going to have to go to kernel land, but we'll talk about that next. So very simply compile, cross compile your C to MIPS. Drop it on the file system and basically find some binary that's always going to run on boot, which is the HTTP server. Now replace it with a shell script that runs our bind shell in the background and then dispatches off to the real HTTP server. And as you see, pack it together, boot up the device, and we netcat to the port, and we have remote root shell. So our next vector could be affecting it via kernel land. You have three possible methods through this infection through a Linux kernel module, infection through def KMM. We're basically editing kernel memory on the fly, or we can do static kernel patching. The problem is that a bug in a code is not just going to kill our payload as userland would, but it's actually going to take down the router and take down the entire network. So if we do do any kernel land modifications, we're going to have to have as little code as possible, put as much code as possible in userland if possible. And another issue is that it has to be compiled against the specific kernel tree if you're doing a Linux kernel module. And even though a lot of routers use the same version of Linux, it's not very universal because we're going to have to download the source code for each router and compile it against that tree. And if you've worked with any GPL source code archives from like any routers, you'll find that they don't actually compile on the first try. They don't compile on the second try or the third try. So it's a real pain in the butt. But again, we have this benefit that all the files, processes and connections are hidden. So let's see, we'll take a look at Linux kernel modules. We won't look at KMM or set a kernel patch that could be future work, but even it's not entirely necessary. It's just more work than you actually need to do. The great thing about using old versions of Linux set, basic root techniques from old frack articles from 2000s, 2001, 1999 are still relevant, as well as all the root kit code that has been updated in years such as Adore. So just a quick look at LKMs, you need an in and exit function that runs on install and uninstall. And if we want to hide processes, we simply hook the redirectory function that's associated with the slash proc directory. Every process running on the system is represented by a directory in slash proc with the PID. That's the name. If you want to hide files and directories, we simply hook the redirectory function associated with the folder that it's in. And if you want to hide connections, we simply hook the output functions associated with proc net TCP and UDP. So a quick structure of how LKMs would look on Linux 2.4 is simple. You have an init module function, a cleanup module function. We put our hooking code in init module and put our unhooking code in cleanup module. And it's pretty much the same concept, but it's a little different in 2.6, except the only difference is that you can really just define arbitrary names for in and exit functions. So a quick look, how would we hide processes and the same idea of files on Linux 2.4 and 2.6? Again, it's simple. You simply open a file pointer to the slash proc directly if you were looking to hide processes. You do some magic to find the redirectory pointer within the file pointer structure. And basically it's just a game of swapping out file pointers. You take the redirectory pointer that's there and simply set it to pointer to your new function, which in this case is the endproc redirectory function. And it takes a callback, a pointer to a callback function called fill directory, which we're going to have to replace. Fill directory is run on every iteration, every item in the directory that is being called on. So all we do is inside this fill directory function is simply have a conditional, have a conditional, is this the file, is this the process ID that we're looking to hide? If so, return zero, if not, run the original one. Very simple. Looking at hiding connections, hiding connections in 2.4 is actually a big pain in the butt. Not that you don't know how to do it, but it's just a lot of parsing, a lot of dirty code I have to write. Looking at a door and g, this is how it's done. It couldn't off it on a slide, but basically the same concepts apply. Basically run the initial, run the original function that returns the information associated with active connections, listening ports on the router, and simply parse out the information that you don't want. So we get the original output of PROCNET TCP, simply iterate through and remove any entries that we don't want and then display it to the user. And then Linux 2.6 is a little easier, but again it follows the same method. Open a file pointer to the PROCNET TCP, replace the file pointer to the function that is used whenever you call PROCNET TCP or read from it, and simply run the original TCP for sequence show function and then parse through the output and remove anything that you don't need or you don't want to show. And every network utility on Linux basically is just parsing output from PROCNET TCP, PROCNET UDP. Netstat is literally just a wrapper around this file, this virtual file and just print it out in pretty formats. Bringing to the next step, repacking the image. Okay, so we have a router image, we were able to extract everything that we wanted, unpack the file system, deploy our payload, how are we going to put it all back together? It's fairly simple, just rebuild the file system in the opposite way that you unpacked it, append the extracted and generated parts back together again, add any sections to define links if necessary. If you look at hex dumps you'll see that even though there is a file system at offset 1000s and it ends at offset 2000s, sometimes they'll just put 10 kilobytes of null bytes just to reach some padding, some padding necessity and we won't worry about metadata yet, we'll take care of that next. So build the file system again just with the appropriate utility inversion, you unpack it with squashFS 2.1, repack it with squashFS 2.1, little ng and big ng and make sure everything matches up. We can use binwalk to verify that we put it back together the way that we took it apart. Paging the image is simple, just dd from dev zero, add it to the end until you get where you want to be. And we're going to leave 58 bytes at the beginning as a placeholder for regenerating that unknown header at the beginning of the firmer image that we saw with the binwalk output there was offset 58, there's a TRX header, but the first 58 bytes we weren't able to identify, but we'll take a closer look at that in the next section. Updating the image metadata, basically this specific firmer had a netgear CHK header. You can tell by the first four bytes are the magic number, star, pound, dollar sign, carrot. And this is, we found this by grepping through the source code for the router, not for the specific string but for the hex decimal representation of it and it was in a defined somewhere in some random file. And looking through we have other data points such as header length and eight bytes of reserved data which doesn't really affect anything, we don't care what's in there. And the kernel checks some, the root file system checks some, the kernel length, root file system length, image checks some, header checks some, and then this board ID, which as you can see next slide, this is that string that we found in our initial profiling of the device. And the HDR zero immediately after it isn't actually part of the board ID but it's actually the beginning of our TRX header. And the TRX header is used to provide metadata about the LZM A blob, the Linux kernel that was directly after it. But as you see we have the header length which is 58 bytes, reserved 8 bytes which we don't really care about, it has no effect on anything we do. The kernel checks some, which we're going to have to, we don't have to worry about because we didn't change the kernel but if we did change it we'd have to update this checks some. And apparently in this specific router they actually don't care about the root file system checks some because the length and checks some are both zeroed out on the stock firmware image. The kernel length which we don't have to change, and image checks some and header checks some, which we're going to have to have to recalculate this because we change the image and we change the header. And how are we going to generate this? Luckily that we have the source code, we have this beautiful utility called packet, you literally give it all the input set you need and it creates the header for you and automatically prepends it to the firmware image and bam this is our final product. We're going to reflash the device with this and we're going to get our shell. So this is where my code comes in. I developed over the past few months a framework called the router post exploitation framework. Basically it abstracts and exploits the process of back to our router firmware images. I believe the website is up, it's in a red mine repository. So if you want to grab it, do it quick before somebody pulls out the red mine zero day and takes it down. And basically the way that it works is you provide an input from our image, you provide the output from our image to the file name that you want output to and the name of the payload and it does everything magically. You don't have to worry about extracting, putting it back together. And basically this is going to allow us to basically create new firmware images for devices. And we don't have to, again, worry about the internals but just say which payload do we want? Do you want a bind shell? Do you want a network sniffer? Do you want a bot net? And it will create this, you ask for input on depending on which payload you decide and it pops out a nice firmware image, reflash the device and we have our shell. So I'm going to do some demos here. All right. Let me just swap this out. So just a little, just a little bit about this. This is RPF. This is the list of things that you can do with it. Basically a couple of flags that just generate more information. And if you want to, you can leave the temporary files in slash temp so that you can instrument on the files if you want to do anything else with them in their extracted form. And we'll take a look at what modules we have so far. Here we go. These are all the firmware images I've been looking at so far. We have Belkin, D-Link, LinkSys, Netgear, and TrendNet. And there's four stages at which the module can be at. Verify, which means it works. You finish the module for that specific router or for that specific firmware image, try it on hardware and it works. It's verified. Unverified, which means you wrote the code. You're fairly certain it's going to work right off the bat or with very little modifications, but it's awaiting a testing on a actual hardware. And I tried to test it on many devices as I could, but unfortunately Ebay always doesn't have the largest selection. There's a roadblock, which basically means there's going to be some work involved. There's something that's stopping the progress moving forward with unpacking and repacking the image. There's going to be some reverse engineering work involved in testing, which means it's currently in development. So let me just set up the network here and we'll start reflashing some routers. Okay. Again, just emulating some sort of attack on a default router that's out there to login with default credentials, ebb and password. We go to the router update page and this gives us a vector to introduce arbitrary code to execute on the device. So we have our firmers here. We're going to use WNR 1000 version 3 firmware and we want to output it to a firmware image that lets us spawn a bind shell. Now this is very simple. It checks the checksum of the firmware image that you input against the module checksum and extracts all those items from the firmware image and asks which port you want to listen on, you want to listen on an elite port and this is our outputted firmware image. Now we're going to reflash the device with this and it's going to ask us is the same one that you want. Yes. And this will just take a minute. In the meantime, is anybody have any questions? Sorry? Yes. Yeah, it was a Lynxus device. This particular Lynxus device uses a file system called PFS slash 0.9. There is very, very, very little information about this file system or archive format available online and the only implementations I found are very broken. They only provide limited support on unpacking the file system. No support for repacking it back together and the only potentially full implementation I found was on a completely Japanese site. All the documentation was in Japanese and it was written in a scripting language called hot soup processor which was just don't want to deal with that. There's another few seconds and it should be ready already. And here is our shell listening on the device. Okay, so this is fine and dandy. We have a root shell on this device that we can access any time remotely but the file system is read only and that's the real pain in the butt. This thing has very, very limited capacity for installing any new software on it. The only writeable part is in slash temp and we only have a couple kilobytes to actually install new code on it. So we'll run into a couple other proof of concept here. Say instead we didn't want to have a bind shell but instead we wanted to install a network sniffer. And if you want extra output, verbose output, just give the slash v flag. And you can see all the intermediary steps that are going on. We track the firmware, we unsquash the file system and we enter our payload. Which port do we want to listen on? In order to receive this SNF traffic port 113 goes through and we'll use the same file name. Write our upgrade, upload and it reflashes again. How many of you are planning to stay in here for FX's talk? There's a possibility of clearing the room. There's a possibility because there's a massive line. There's a possibility of switching this over to track one. Hang tight. We'll let you know what we're going to do. Sorry about that. So any other questions in the meantime? The question was did I find any writers that had signed firmware images? Signed firmware images. Personally I did not. A lot of these personal devices are just using upfuscated proprietary firmware formats. The most they're compressed but again you can decompress them or have some patch to open source utility but no I actually did not come across any that were signed. But that is one thing that vendors could do in order to prevent this type of attack. This works. I may have just bricked the router. Let's try a different one. Okay. While this goes. Any other questions? Yes? The question was do old writers use busybox? Yeah. As far as I was able to tell almost every writer just use busybox. Busybox is a single binary that let you include a whole bunch of common unix utilities in a single binary. And instead of having a different binary for LS, a different binary for cat, a lot of extra overhead, you just have a single binary and you have a sim link to the original one. But yes, everyone that I did encounter did use busybox. Sorry, say that again? No. Sorry, could you come up closer? I can't hear you. I don't think I have. Yes? Oh, the sniffer is running in user land. It opens a raw socket on all ports and simply prints the output to it pipes the output to another port. Hopefully this writer comes back. There we go. Okay. So we netcat to the control port and here we can see the dump of all TCP packets that are going through it. Obviously we don't have, I don't have a network connection here or connection so I can't go out and show any going to Facebook or anything. But you can see just accessing the writer from the admin panel. You can see all the traffic going through. We can go back and inspect it and find passwords say if we were logging in to the panel. Here authorization basic and here's base 64 encoded version of what our login is. So my last demo, let me just get this set up here. So this we can get a shell, we can sniff network traffic but what if we wanted to do something just completely and utterly malicious or if we wanted to install a botnet on our firmware image. So the address of our router or of our IRC server, port of our IRC server channel and prefix something that hope this works. And wait for this thing to finish reflashing and if all goes in well, all goes well, then we should be seeing a new Nick in the channel. Yes. Yeah, I mean obviously if there are vulnerabilities in the router itself, you can always get access to the admin panel that way but the best protection I guess is just to set a strong password on the admin panel. Any other questions? Yes. I believe the question was can you upgrade the firmware from a modified firmware? Yes, you could. That's one potential route for future development. Obviously you can make it so you can prevent any new firmwares from being flashed to it but that might be conspicuous. But yes, at the moment rewriting the firmware after it's been installed will overwrite the firmware and put a fresh copy on it. Any other questions? Yes. The question was have I tried any other man-in-the-middle attacks such as SSL strip? I have not but that's definitely, there's a lot of potential. The only issue that might be a limiting factor is compiling all the code and getting it on the router because you really only have like 10 kilobytes to work with. Actually be flashing the router, killed my connection. I don't remember how much you have but again it's only a couple kilobytes or like a megabyte or something. There's very little space on these and here is our botnetted router and we can do all sorts of fun stuff with it. We can send it shell command. Hopefully the demo guys are not looking upon us favorably today. But there take my word for it there's a lot of cool stuff you can do with this. There's actually implemented DDoS command just for fun but if you check this out online there's on the site you can download this on your own router. This is the first time it actually hasn't worked. So yep. So I believe I run out of time but quickly some things I like to give the people at midnightcode.org they did a lot of work with Belkin reverse engineering and profiling. I like to thank Dan Rosenberg for kicking my button to gear to actually get a talk submitted and as well as the great people at OpenWRT and DDWRT who have helped a lot along the way. So thank you.