Showing posts with label simet. Show all posts
Showing posts with label simet. Show all posts

Sunday, September 1, 2013

Analyzing and Running binaries from Firmware Images - Part 1

During the first part of SIMET Box Firmware analysis, we downloaded the firmware Image, extracted its contents, compared/analyzed its base and found a couple of interesting files (SSH keys, binary files, init scripts, firewall rules and so on).

For this part we'll focus on identifying binaries, comparing and executing them to find interesting data. Whenever you're analyzing binaries from different architectures, there are a couple of nice tools that aid debugging, reversing and emulating their behavior, like objdump, readelf and QEMU.

Embedded Debian Project provides pre-built binary toolchains for mips, mipsel, arm, armel, powerpc, and a couple of other architectures. In order to download and install it on Debian based Linux distros, you have to apt-get its archive signing key:
sudo apt-get install emdebian-archive-keyring

Now you you need to include their repository on your /etc/apt/sources.list:
deb http://www.emdebian.org/debian/ squeeze main

After the apt-get update you can install binutils for you target archs:
sudo apt-get install binutils-mips-linux-gnu binutils-mipsel-linux-gnu  binutils-arm-linux-gnueabi

For this little exercise I'll analyze three busybox binaries, from three different firmwares: busybox-simet (from SIMET Box), busybox-asuswrt (from AsusWRT-Merlin firmware) and busybox-sb6120 (from Motorolla's SB6120 Surfboard Cable Modem).

Architecture, Big-Endian or Little Endian?

When analyzing SIMET Box we already knew that the device was based on ar71xx platform, which is MIPS based and big endian as stated on OpenWRT's official page. If you want to find it by your own you can use the file utility:


Emdebian binutils also provide useful tools to identify further info from unknown binaries. A nice hack that I commonly use is to display information from object files using different toolchains in order to find out which one understands the file structure properly. For example, objdump -f displays contents of the overall file header.

  • SIMET Box tl-wr740n-v4 (architecture: mips:isa32r2, file format elf32-tradbigmips)

  • AsusWRT-Merlin v3.0.0.4.374.32 (architecture: mips:isa32 file format elf32-tradlittlemips)

  • SB6120 v1.0.2.4-SCM01 (architecture: arm, file format elf32-bigarm)

We now know each file's format/architecture and can proceed using QEMU to emulate the binaries on a virtual environment.

QEMU

QEMU is a generic and open source machine emulator and virtualizer that supports architectures like MIPS, ARM and PowerPC. In order to setup and run single binaries with QEMU on Debian based Linux distributions, you need to install the qemu-user-static package. RogueAsian and devtty0 detail these steps here and here.
sudo apt-get install qemu-user-static

It's important to run qemu on a chrooted environment to avoid mixing your target's libraries with those on your host system.

AsusWRT-Merlin v3.0.0.4.374.32

Let's try this on AsusWRT's busybox first. We'll have to use qemu-mipsel-static because it's MIPS32 based and Little Endian.


Hmmm, not so lucky this time, ld-uClibc.so is missing. Let's check the dynamic section and copy the necessary libraries from the original firmware:
mips-linux-gnu-objdump -x bin/busybox-asuswrt | grep lib


We can also cross compile these libraries on our own or install the target C libraries with dpkg-cross, but using the firmware original libraries is always preferred. After copying the necessary files, we can finally execute it using QEMU:
cp `whereis qemu-mipsel-static | cut -d" " -f2` .
sudo chroot . ./qemu-mipsel-static bin/busybox-asuswrt


SB6120 v1.0.2.4-SCM01

Let's try to run busybox from Motorolla's cable modem Surfboard SV6120 (ARM/Big Endian):

cp `whereis qemu-armeb-static | cut -d" " -f2` .
sudo chroot . ./qemu-armeb-static bin/busybox-sb6120


BusyBox v1.4.2, might be vulnerable to CVE-2011-2716 =)

SIMET Box tl-wr740n-v4

Running the busybox binary extracted from SIMET Box (MIPS/Big Endian):

cp `whereis qemu-mips-static | cut -d" " -f2` .
sudo chroot . ./qemu-mips-static bin/busybox-simet
mips-linux-gnu-readelf -h bin/busybox-simet


Unfortunately, qemu-mips-static did not recognize the ELF image properly and was unable to run SIMET Box's binaries on the fly. For the next post I'll detail on how to overcome this issue with SIMET Box's busybox by running a full OpenWRT MIPS environment on QEMU. This is useful because we can compile and run our own (compatible) kernel, set up a network device, analyze the network activity and its system-wide interactions.

Conclusion
These techniques help identifying unknown binaries from unknown architectures and running them on a virtual environment. They might be useful to analyze malware for embedded systems (Internet Census 2012 anyone?), during forensic analysis and to hack/find vulnerabilities on firmware images.


Sunday, August 25, 2013

SIMET Box Firmware Analysis: Embedded Device Hacking & Forensics

For my first blog post I decided to have a quick look on the firmware from SIMET Box. SIMET is organized by the Brazilian NIC.br in order to test and monitor the Internet speed across the country. For more info (in portuguese) visit their site here. All the data collected is available to the community on reports and heat maps like this.

The organization is now handing out free Wi-Fi routers to Brazilians in order to measure the Internet quality on different regions. The SIMET Box equipment is a custom TL-WR740N pre-installed with OpenWRT. You can also download and install the standalone firmware on other TPLink's SOHO routers.



The project is quite interesting but in times of PRISM and NSA I don't like the idea of using a "black box" at home, so I decided to check its design.

Firmware

As I don't have the actual box, I'll analyze SIMET Box's firmware image. The firmware can be downloaded from http://simet.nic.br/firmware. For this initial analysis I'll be using simetbox-tl-wr740n-v4.bin (MD5 d08798093e1591bece897671e96b5983).


Let's start by using Craig Heffner's binwalk and firmware-mod-kit to unsquash the filesystem:

binwalk -Me simetbox-tl-wr740n-v4.bin


After extracting the files we can browse through the squashfs-root dir and grep files to identify OpenWrt's version base:


We now know that SIMET Box is based on Attitude Adjustment branch (v12.09) for Atheros AR71xx, downloadable on OpenWRT's official site: openwrt-ar71xx-generic-tl-wr740n-v4-squashfs-factory.bin.

After extracting the base firmware (using binwalk) we now have two directory trees to diff. We can use WinMerge or Kdiff3 to compare files.


 

There are some new init.d scripts like atualiza_arqs, autossh, miniupnpd and zabbix_agentd:


Lots of binaries (/bin/busibox for example) are quite similar: they may have a small version difference or were compiled using particular command line arguments:


List of files created by SIMET Box (not present on the OpenWrt's base firmware):
while read -r i ; do file $i ; done < list.txt
/etc/config/autossh: ASCII text
/etc/config/upnpd: ASCII text
/etc/dropbear/authorized_keys: OpenSSH DSA public key
/etc/dropbear/id_rsa: data
/etc/hotplug.d/button/00-button: ASCII text
/etc/hotplug.d/iface/20-autossh: POSIX shell script, ASCII text executable
/etc/hotplug.d/iface/50-miniupnpd: POSIX shell script, ASCII text executable
/etc/init.d/atualiza_arqs_simet: POSIX shell script, ASCII text executable
/etc/init.d/autossh: POSIX shell script, ASCII text executable
/etc/init.d/miniupnpd: POSIX shell script, ASCII text executable
/etc/init.d/zabbix_agentd: POSIX shell script, ASCII text executable
/etc/rc.d/S11sysctl: symbolic link to `../init.d/sysctl'
/etc/rc.d/S19firewall: symbolic link to `../init.d/firewall'
/etc/rc.d/S45atualiza_arqs_simet: symbolic link to `../init.d/atualiza_arqs_simet'
/etc/rc.d/S60zabbix_agentd: symbolic link to `../init.d/zabbix_agentd'
/etc/rc.d/S80autossh: symbolic link to `../init.d/autossh'
/etc/rc.d/S95miniupnpd: symbolic link to `../init.d/miniupnpd'
/etc/uci-defaults/50-reset: POSIX shell script, ASCII text executable
/etc/uci-defaults/50-reset-wps: POSIX shell script, ASCII text executable
/etc/uci-defaults/50-wifi: POSIX shell script, ASCII text executable
/etc/uci-defaults/99-miniupnpd: POSIX shell script, ASCII text executable
/etc/uci-defaults/luci-i18n-portuguese_brazilian: POSIX shell script, UTF-8 Unicode text executable
/etc/uci-defaults/luci-theme-bootstrap: POSIX shell script, ASCII text executable
/etc/uci-defaults/luci-upnp: POSIX shell script, ASCII text executable
/etc/zabbix_agentd.conf: ASCII text
/lib/libpthread-0.9.33.2.so: ELF 32-bit MSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked (uses shared libs), corrupted section header size
/lib/libpthread.so.0: symbolic link to `libpthread-0.9.33.2.so'
/root/.ssh/known_hosts: ASCII text, with very long lines
/sbin/fw3: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1, dynamically linked (uses shared libs), corrupted section header size
/usr/bin/auto_upgrade: symbolic link to `simet_tools'
/usr/bin/checa_udhcpc.sh: POSIX shell script, ASCII text executable
/usr/bin/get_mac_address.sh: POSIX shell script, ASCII text executable
/usr/bin/simet_client: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1, dynamically linked (uses shared libs), corrupted section header size
/usr/bin/simet_dns: symbolic link to `simet_tools'
/usr/bin/simet_porta25: symbolic link to `simet_tools'
/usr/bin/simet_tools: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1, dynamically linked (uses shared libs), corrupted section header size
/usr/bin/sshreversetunnel: POSIX shell script, ASCII text executable
/usr/bin/teste_spoofing.sh: POSIX shell script, ASCII text executable
/usr/bin/wifionoff: POSIX shell script, ASCII text executable
/usr/lib/lua/luci/controller/simet.lua: ASCII text
/usr/lib/lua/luci/controller/upnp.lua: ASCII text
/usr/lib/lua/luci/i18n/base.pt-br.lmo: data
/usr/lib/lua/luci/i18n/upnp.ca.lmo: data
/usr/lib/lua/luci/i18n/upnp.cs.lmo: data
/usr/lib/lua/luci/i18n/upnp.de.lmo: data
/usr/lib/lua/luci/i18n/upnp.es.lmo: data
/usr/lib/lua/luci/i18n/upnp.fr.lmo: data
/usr/lib/lua/luci/i18n/upnp.hu.lmo: data
/usr/lib/lua/luci/i18n/upnp.it.lmo: data
/usr/lib/lua/luci/i18n/upnp.ja.lmo: data
/usr/lib/lua/luci/i18n/upnp.no.lmo: data
/usr/lib/lua/luci/i18n/upnp.pl.lmo: data
/usr/lib/lua/luci/i18n/upnp.pt-br.lmo: data
/usr/lib/lua/luci/i18n/upnp.pt.lmo: data
/usr/lib/lua/luci/i18n/upnp.ro.lmo: data
/usr/lib/lua/luci/i18n/upnp.ru.lmo: data
/usr/lib/lua/luci/i18n/upnp.vi.lmo: data
/usr/lib/lua/luci/i18n/upnp.zh-cn.lmo: data
/usr/lib/lua/luci/model/cbi/upnp/upnp.lua: ASCII text
/usr/lib/lua/luci/sgi/uhttpd.lua: ASCII text
/usr/lib/lua/luci/view/admin_status/index/upnp.htm: ASCII text
/usr/lib/lua/luci/view/simet/simet.htm: HTML document, UTF-8 Unicode text
/usr/lib/lua/luci/view/themes/bootstrap/footer.htm: HTML document, ASCII text
/usr/lib/lua/luci/view/themes/bootstrap/header.htm: HTML document, ASCII text
/usr/lib/lua/luci/view/upnp_status.htm: HTML document, ASCII text
/usr/lib/opkg/info/autossh.conffiles: ASCII text
/usr/lib/opkg/info/autossh.control: ASCII text
/usr/lib/opkg/info/autossh.list: ASCII text
/usr/lib/opkg/info/hping3.control: ASCII text
/usr/lib/opkg/info/hping3.list: ASCII text
/usr/lib/opkg/info/libip6tc.control: ASCII text
/usr/lib/opkg/info/libip6tc.list: ASCII text
/usr/lib/opkg/info/libnfnetlink.control: ASCII text
/usr/lib/opkg/info/libnfnetlink.list: ASCII text
/usr/lib/opkg/info/libopenssl.control: ASCII text
/usr/lib/opkg/info/libopenssl.list: ASCII text
/usr/lib/opkg/info/libpcap.control: ASCII text
/usr/lib/opkg/info/libpcap.list: ASCII text
/usr/lib/opkg/info/libpthread.control: ASCII text
/usr/lib/opkg/info/libpthread.list: ASCII text
/usr/lib/opkg/info/luci-app-simet.control: ASCII text
/usr/lib/opkg/info/luci-app-simet.list: ASCII text
/usr/lib/opkg/info/luci-app-upnp.control: ASCII text
/usr/lib/opkg/info/luci-app-upnp.list: ASCII text
/usr/lib/opkg/info/luci-i18n-portuguese-brazilian.control: ASCII text
/usr/lib/opkg/info/luci-i18n-portuguese-brazilian.list: ASCII text
/usr/lib/opkg/info/luci-sgi-uhttpd.control: ASCII text
/usr/lib/opkg/info/luci-sgi-uhttpd.list: ASCII text
/usr/lib/opkg/info/luci-theme-bootstrap.control: ASCII text
/usr/lib/opkg/info/luci-theme-bootstrap.list: ASCII text
/usr/lib/opkg/info/miniupnpd.conffiles: ASCII text
/usr/lib/opkg/info/miniupnpd.control: ASCII text
/usr/lib/opkg/info/miniupnpd.list: ASCII text
/usr/lib/opkg/info/simet-base-files.control: ASCII text
/usr/lib/opkg/info/simet-base-files.list: ASCII text
/usr/lib/opkg/info/simet-client.control: ASCII text
/usr/lib/opkg/info/simet-client.list: ASCII text
/usr/lib/opkg/info/simet-tools.control: ASCII text
/usr/lib/opkg/info/simet-tools.list: ASCII text
/usr/lib/opkg/info/uhttpd-mod-lua.control: ASCII text
/usr/lib/opkg/info/uhttpd-mod-lua.list: ASCII text
/usr/lib/opkg/info/zabbix-agentd.control: ASCII text
/usr/lib/opkg/info/zabbix-agentd.list: ASCII text
/usr/lib/opkg/info/zlib.control: ASCII text
/usr/lib/opkg/info/zlib.list: ASCII text
/usr/lib/libcrypto.so.1.0.0: ELF 32-bit MSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, corrupted section header size
/usr/lib/libip6tc.so: symbolic link to `libip6tc.so.0.0.0'
/usr/lib/libip6tc.so.0: symbolic link to `libip6tc.so.0.0.0'
/usr/lib/libip6tc.so.0.0.0: ELF 32-bit MSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, corrupted section header size
/usr/lib/libjson-c.so.2: symbolic link to `libjson-c.so.2.0.1'
/usr/lib/libjson-c.so.2.0.1: ELF 32-bit MSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, corrupted section header size
/usr/lib/libnfnetlink.so.0: symbolic link to `libnfnetlink.so.0.2.0'
/usr/lib/libnfnetlink.so.0.2.0: ELF 32-bit MSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, corrupted section header size
/usr/lib/libpcap.so: symbolic link to `libpcap.so.1.1'
/usr/lib/libpcap.so.1.1: symbolic link to `libpcap.so.1.1.1'
/usr/lib/libpcap.so.1.1.1: ELF 32-bit MSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, corrupted section header size
/usr/lib/libssl.so.1.0.0: ELF 32-bit MSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, corrupted section header size
/usr/lib/libz.so: symbolic link to `libz.so.1.2.7'
/usr/lib/libz.so.1: symbolic link to `libz.so.1.2.7'
/usr/lib/libz.so.1.2.7: ELF 32-bit MSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, corrupted section header size
/usr/lib/uhttpd_lua.so: ELF 32-bit MSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, corrupted section header size
/usr/sbin/autossh: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1, dynamically linked (uses shared libs), corrupted section header size
/usr/sbin/hping3: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1, dynamically linked (uses shared libs), corrupted section header size
/usr/sbin/miniupnpd: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1, dynamically linked (uses shared libs), corrupted section header size
/usr/sbin/zabbix_agentd: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1, dynamically linked (uses shared libs), corrupted section header size
/usr/share/libiwinfo/hardware.txt: ASCII text
/usr/share/miniupnpd/firewall.include: POSIX shell script, ASCII text executable
/www/luci-static/bootstrap/cascade.css: assembler source, ASCII text
/www/luci-static/bootstrap/favicon.ico: MS Windows icon resource - 1 icon
/www/luci-static/bootstrap/html5.js: HTML document, ASCII text, with very long lines
/www/simet/ceptro.png: PNG image data, 78 x 30, 8-bit colormap, non-interlaced
/www/simet/cgi.png: PNG image data, 46 x 30, 8-bit colormap, non-interlaced
/www/simet/nic.png: PNG image data, 47 x 25, 8-bit colormap, non-interlaced
/www/simet/nonet.htm: UTF-8 Unicode text
/www/simet/offline.jpg: JPEG image data, EXIF standard
/www/simet/simetbox_minilogo.png: PNG image data, 111 x 23, 8-bit colormap, non-interlaced
/www/simet/view_tab.css: assembler source, ASCII text
/www/simet/view_tab.js: UTF-8 Unicode text, with very long lines

This simple technique is quite useful for forensic analysis of embedded devices, as you have a white-list of known binaries and config files. It's important to review both created and modified files, but I'll focus on the ones listed above. Each binary and config file can be reviewed separately so we can find interesting entries like:

  • SSH reverse tunnel settings and authorized_keys:
  • Password changing scripts and Iptables rules:

  • The device management starting page has an external iframe and users are identified by their MAC Address via HTTP GET requests:

  • Cronjobs to test external access to port 25 and if the ISP allows IP spoofing:
  • Script using hping3 to test if the user's ISP allows packet spoofing:

  • Zabbix agent settings:

As a quick advice to SIMET engineers, it would be nice to have HTTPS for those external queries, a bit more of transparency on what the equipment does internally, who's able to access it (whose authorized_keys are those?), what external IP addresses it communicates with and what information is being collected. Securing SOHO modems is very important, specially here in Brazil where lots of recent attacks were targeting these devices (Fabio Assolini's talk "The tale of one thousand and one DSL modems" detailed this a year ago).

On the next post I'll detail how to run those MIPS32 binaries on a virtual environment using QEMU and analyze some of the files with IDA Pro.