Evaluating the security of OpenWRT (part 1)

Sep 18 2014 Published by under infosec

I have recently spent  some time pondering the state of embedded system security.
I have been a long time user of OpenWRT, partly based on the premise that it should be “more secure” out of the box (provided attention is paid to routine hardening); but as the Infosec world keeps  on evolving, I thought I would take a closer look at the state of play.

OpenWRT – an embedded Linux distribution.

OpenWRT is a Linux distribution targeted as a replacement firmware for consumer home routers, having been named after the venerable Linksys WRT54g, but it is gaining a growing user base in the so-called Internet of Things space, as evidenced by devices such as the Carambola2, VoCore and WRTnode.

Now there are many, many areas that could be the focus of security related attention.  One useful reference is the Arch Linux security guide , which covers a broad array of mitigations, but for some reason I felt like diving into the deeper insides of the operating system. I decided it would be worthwhile to compare the security performance of the core of OpenWRT, specifically the Linux kernel plus the userspace toolchain, against other “mainstream” distributions.

The theory is that ensuring a baseline level of protection in the toolchain and the kernel will cut of a large number of potential root escalation vulnerabilities before they can get started.  To get started, take a look at the Gentoo Linux toolchain hardening guide.  This lists mitigations such as: Stack Smashing Protection (SSP), used to make it much harder for malware to take advantage of stack overrun situations; position independent code (PIC or PIE) that randomises the address of a program in memory when it is loaded; and so-on to other features such as Address Space Layout Randomisation (ASLR) in the kernel, all of these designed to halt entire classes of exploits in their tracks.

I wont repeat all the pros and cons of the various methods here.  It should be noted that these methods are not foolproof; new techniques such as Return Oriented Programming (ROP) can be used to circumvent these mitigations.  But defense-in-depth would appear to be an increasingly important strategy.  If a device can be made secure using these techniques it is probably ahead of 95% of the embedded market and more likely to avoid the larger number of automated attacks; perhaps this a bit like the old joke:

The first zebra said to the second zebra: “Why are you bothering to run? The cheetah is faster than us!”

To which the second zebra replied, “I only have to run faster than you!”

Analysis of just a few aspects.

There is an excellent tool “checksec.sh”, that can scan binaries in a Linux system and report their status against a variety of  security criteria.
The original author has retained his website but the script was last updated in November 2011. I found a more recently maintained version on GitHub featuring various enhancements (the maintainer even accepted a patch from me addressing a cosmetic bugfix.)

Initially I started using the tool to report on just the status of the following elements in binaries and libraries: RELRO, non-executable stack, SSP and PIC/PIE.

The basic procedure for using the tool against an OpenWRT build is straightforward enough:

  1. Configure the OpenWRT build and ensure the tar.gz target is enabled ( CONFIG_TARGET_ROOTFS_TARGZ=y )
  2. To expedite the testing I build OpenWRT with a pretty minimal set of packages
  3. Build the image as a tar.gz
  4. Unpack the tar.gz image to a temporary directory
  5. Run the tool

When repeating a test I made sure I cleaned out the toolchain and the target binaries, because I ahve been bitten by spuriuos results caused by changes to the configuration not propagating through all components.  This includes manually removing the staging_dir which may be missed by <code>make clean</code> . This made each build take around 20+ minutes on my quad core Phenom machine.

I used the following base configuration, only changing the target:

I repeated the test for three platform configurations initially (note, these are mutually exclusive choices) – the Carambola2 and rt305x are MIPS platforms.

There are several directories most likely to have binaries of interest, so of course I scanned them using a script, essentially consisting of:

The results were interesting.

(to be continued)

No responses yet

OpenWRT WDS between legacy WRT54G and recent TP-Link devices

Mar 30 2014 Published by under howto

For a while now I had a multiple wifi routers all providing access points, and a connection to each other, using a feature called WDS. All of the routers run OpenWRT. Recently one of them died and everything kind of stopped working properly. I actually had the following configuration:

TP-LINK <--wired,bridged--> ASUS WL500G <--wireless,WDS,bridged--> Linksys WRT54G

Now this all worked because the conventional wisdom appears to be that WDS works when the device at each end is the same, i.e. Broadcom to Broadcom (which I had in the case of WL500G and WRT54G) and is problematic at best otherwise.

Documentation alluding to this includes:

http://wiki.openwrt.org/doc/recipes/broadcomwds

http://wiki.openwrt.org/doc/recipes/atheroswds

http://wiki.openwrt.org/doc/howto/clientmode

So with the WL500G out of the picture, the TP-Link and WRT54G were no longer able to see each other, and I experienced a loss of connectivity from my workshop where the WRT54G was physically located.

However if you look under the covers a bit, it seems this configuration can be made to work, as suggested by the folk over at DD-WRT.

So with a bit of tweaking I was able to get WDS working between the TP-LINK and WRT54G as follows.

TP-LINK Router (WR1043ND, OpenWRT 10.03 Backfire)

Content of /etc/config/wireless:

WRT54G Router (WRT54G, OpenWRT 10.03 with legacy 2.4 kernel for broadcom wireless)

Content of /etc/config/wireless:

Notes

  • xx:xx:xx:xx:xx:xx is the MAC address of the WR1043ND, and yy:yy:yy:yy:yy:yy the MAC address of the WRT54G
  • Both devices have to be on the same channel
  • On the secondary router (WRT54G) you actually connect on the ssid LOCALSSID but all DHCP, etc. comes from the TP-LINK

Note also you need to ensure that DHCP on the LAN is disabled on the second router!

I am unsure why this configuration has apparently been problematic for some – perhaps it is quite router specific as to whether it works.

No responses yet

Achievement unlocked – OpenWRT device porting – and a quick and dirty level conversion

Apr 26 2013 Published by under howto, tech

Porting a Linux Router

So I just posted what I hope this time are properly formatted patches to the OpenWRT developers mailing list, a set of patches that add support to OpenWRT for the D-link DIR-632-A1 router.

You can see some of my progression on the OpenWRT forum.

This was quite a bit of a journey, as I had a few false starts and along the way crossed a number of different areas in the Linux kernel. The best thing was debugging bit-banging of device registers, which reminds me of hacking on my Commodore 64 many years ago. I have of course had occasion to do such at times professionally, but I have rediscovered my desire to do more low level hacking, and having recently received a Raspberry Pi as a gift and finding use for my leostick from the 2012 linux conf I expect to have plenty of opportunity when I manage to find some more spare time.

Along the way I extended significantly my knowledge of how to work with OpenWRT and build customised images, etc. I added a build guide for this router to the wiki pending acceptance of patches into the main stream; I think this cuts through the useful but verbose documentation elsewhere in the wiki.

When you need a USB-TTL RS232…

and you live 45m from Jaycar, and its 9pm Friday night anyway and you certainly don’t want to wit 3days for Internet delivery from your friendly Aussie electronics suppliers (hello Core electronics!) or a month for some Chinese no-brand on ebay… and you want to hack now!

A crucial part of hacking a router is access to the serial port.  These are always at logic level, and in the case of the DIR-632 at 3v3 not 5V, further complicating things.  However all I had handy was a USB-RS232 dongle running at proper RS-232 levels, of +/- 12V – so connecting this would be sure to let the smoke out of something…

Now it turns out I have a shedful of what most people would term junk.  But usefully this included a tube of MAX232 chips I acquired some years ago.  So first, find a handful of resistors and capacitors, and a birdnest later, one logic level to RS232 converter:

nest

There is a leostick there, but it is being used to provide 5V :-) Originally I attempted to use it as a serial relay, but apparently there is a bug in the firmware in the model I have that causes problems with the d0/d1 serial port and thus all I could ever see was junk… (thanks to MarkJ for letting me know)

The circuit is basically as described here (1), but I used 2x 2u2 capactitors in parallel, not having enough 1uF (* I really get into going the whole bush-mechanic-electronics thing!)

However, this doesnt fix the whole problem – the MAX232 is powered by 5V, although I also later found out it may have worked at 3v3 anyway.

I suspect many of the younger maker crowd might not be aware of some trick that can be employed when necessary: you can of course buy a 2cm sized 3v3 to 5v level converter form Jaycar, or from China on ebay, but again I didnt want to wait, and I had a pile of BC547 transistors handy and basic knoweldge of how logic circuits are actually built.

Thus, two transistors and a few resistors later, a logic level converter:

              -+-----------------+- 5V
               |                 |
               |                 Z
               |                 Z
               |                 Z
               |                 Z        __
               |                 |     __|  |__
               Z                 |
               Z                 +--------->
     __        Z   __    __      |
  __|  |__     Z     |__|      | /
               |               |/
               +----/\/\/\-----|
               |               |\
             | /               | \
     4k7     |/                  V
---/\/\/\----|                   |
             |\                  |
             | \                 |
               v                 |
               |                 |
               +-----------------+
               |
               |
             --+--
              ---
               -

(ASCII art FTW!)

Going he other way, I just ran three signal 1N4148 diodes in series, this dropped the line to about 3v5 which managed to not blow anything up with!

 

And several rather late nights^H^H^H early mornings later:

Links:

(1) http://www.scienceprog.com/alternatives-of-max232-in-low-budget-projects

No responses yet

OpenWRT tips

Feb 17 2012 Published by under howto

“Undeleting” files from the /rom filesystem…

This post describes in gory detail how to recover files from the ROM image in case you accidentally removed a base package from OpenWRT.
In brief, locate files called ‘META_*’ on /overlay and edit them to remove deletions from the overlay filesystem. For detail, read on…

TL;DR

When first installed, the OpenWRT image is built into a squashfs read-only filesystem, mounted at /rom and underlying the root (/).  Writes to the root filesystem persist on a jffs2 filesystem mounted at /overlay and merged at the root using mini_fo.  Ignoring operations occurring actually on /rom/ and /overlay paths, if a file is overwritten, the file is actually stored in /overlay at the same relative location, and mini_fo makes the newer file appear to the system form that point.  Operations in /overlay/ itself are obviously filtered by mini_fo.  /tmp, /dev, etc. are all mounted on tmpfs outside of this process.

So how are deleted files handled? It turns out there is a special file made in each directory in /overlay, that mini_fo hides from view in the applicable root level directory, that records files on /rom that are deleted.

The special files are prefixed with ‘META_’, for  example: META_dAfFgHE39ktF3HD2sr, the content is simply one file per line, two fields, the letter D followed by the deleted file:

Undelete files by simply removing the entry from the META_ file.

In the event you remove a package that was in the /rom image using ipkg, it is easy enough to get back by finding editing all the special files in /overlay and removing the deletion references.

Hint: although there are various to choose from, I always start with the smallest /rom image, as that allows easier reconfiguration by adding and later removing packages, and provides a bigger R/W jffs2 partition at /overlay.  If you need to delete a package that was in /rom, it doesn’t actually give you any extra space on the small SSD…

No responses yet

OpenWRT web admin (LUCI) wierdness

Feb 09 2012 Published by under howto

I had a router configured with OpenWRT BackFire (10.03) and had a need to upgrade it to support the web management interface.

So to do this login to a console and:

However, in my attempt to streamline things and reduce disk usage I managed to only have the ‘Essentials’ menu, this was missing various important items such as detailed dnsmasq settings (which was the whole point of the exercise.) So I pushed on and installed luci, which should have enabled the “Administration” menu but did not.

After much mucking around and browsing through the installed files, I stumbled upon this:

after which logging in the “Administration” menu is now present.

No responses yet