Linux IGD & Pseudo ICS daemon
A very popular UPnP stack on Linux based devices is Linux IGD. This stack
cound be found on many Linux based devices that do not contain a Broadcom or
Texas Instruments CPU, but Realtek or ADMtek devices. There are various
incarnations of this stack, with a varying degree of bugs. Early versions were
written in C++, and included a check to see if the NewInternalClient parameter in the AddPortMapping SOAP request is an actual IP address, but newer
versions (written in C and used on a lot of routers) omitted this check and
just passed strings around, meaning you can put basically anything in it,
including shell commands which are executed on the router with full root
privileges.
Depending in the version of Linux IGD that was used there
might be a check for length on the NewInternalClient parameter (15 characters maximum). Even with
this check you can still execute a small shell command inside backticks with
full root privileges on the router itself. This is enough to reboot the
router, or set it back to factory defaults. This is the code that is used on
all EdiLinux based devices (EdiLinux is what's running on a lot of devices from
Edimax and its resellers).
The faulty code can be found mostly in the
files pmlist.c (in
the function pmlist_AddPortMapping), pmlist.h and gatedevice.c.
These bugs were
fixed Linux IGD in May 2006. These versions use execv() instead of system(), or use libiptc if
available.
Other bugs that are present (but I don't know yet if they
exist in every version of Linux IGD, or just in devices from a single
manufacturer) is that the UPnP port is running on the WAN side and you can use
UPnP to make internal ports (such as the webinterface) available on the WAN
interface. I have also seen one device where you could actually use a lot more
code than 13 characters.
Pseudo ICS daemon
Pseudo ICS daemon is a predecessor of Linux IGD and works only with systems that are based on a Linux 2.2 kernel. It is not used much, but every once in a while a device pops up which has this stack. The Pseudo ICS daemon software was written in 2002, but development has stopped a long time ago. Compared to early versions of Linux IGD there are more checks in place to verify the correctness of parameters.
Linux IGD devices
Linux IGD is one of the most widely used UPnP stacks. A lot of companies use it
in their products. These companies often make use of the same ODM companies.
There are a lot fewer 'unique' devices out there than you might
think.
The GPL sources for a Linux based device are a good indication if
they are provided (this is not always the case, please contact
gpl-violations.org if you find a GPL violation). The GPL sources quickly lets
you determine if the device is vulnerable or not.
Recognizing Linux IGD
The Linux IGD system can be recognized in a few ways. None of these are totally
fool proof and other stacks might use them too. The first one is the TCP port.
Normally 49152 is used, but occasionally TCP port 49153 is used as well. It
seems that sometimes it uses this port if it gets confused enough (accidental
power loss, reboot) and 49152 seems to be locked or busy for some reason (for
example, another instance of a UPnP daemon).
Linux IGD quirks
The Linux IGD stack has a few quirk you should keep in mind when trying to
exploit it. It doesn't always respond directly to discovery requests, but sends
out a NOTIFY every now and then (usually 30 minutes). If your script actively
first sends a discovery request (as required by the protocol) and then waits
until it gets an answer, it will have to wait a long time. It is easier to
hardcode the URLs to send commands to in that case.
Another quirk is
that sometimes (but not always) the Linux IGD stack requires its input to
follow some rules, otherwise it will reject it. I've seen on one device that
NewPortMappingDescription (part of
WANIPConnection in IGD) needed to have some value and it needed to be a
'normal' character. A single space for example was rejected, while 'a' was
acceptable, even in combination with spaces.