Latest Tweets

Transform your Hak5 Packet Squirrel into an automatic TOR annonymizer

Preamble

I’ve been testing some Hak5 devices recently. I have to admit that they are all incredible, easy to use and well-designed. The Packet Squirrel is an incredible small MIPS device, based on OpenWRT, full of possibilities. Although its main goal is to perform advanced MitM attacks, it can be used for the common good as well. Being a MIPS device, some of the most used and well-known utilities and programs are included, but of course some others are not. TOR, for instance, it’s not installed out-of-the-box. That’s not a problem, of course, because you can always get its sources and cross-compile it. So I thought that using the Packet Squirrel for routing all the TCP traffic from a “TARGET” computer would be nice. Instead of using the device to perform MitM attacks, this would showcase its possibilities in quite another way.

Get to know the device

Before trying to cross-compile TOR, we need to know which libraries and hardware the device runs on. So we connect the device to our computer using the “ETH IN” device, we power it on and we connect to it using an SSH session. Then we perform the usual commands to get the standard C library used, its Kernel version, OpenSSL version, system architecture, and so on:

uname -a
Linux squirrel 3.18.45 #13 Mon Oct 30 21:24:27 UTC 2017 mips GNU/Linux

cat /proc/cpuinfo |grep model
cpu model : MIPS 24Kc V7.4

ls -l libc.so.0
lrwxrwxrwx 1 root root 21 Oct 30 21:24 libc.so.0 -> libuClibc-0.9.33.2.so

busybox |head -1
BusyBox v1.23.2 (2017-09-06 11:27:56 UTC) multi-call binary.

That’s fine; but we still need to know if the architecture is Big Endian or Little Endian, and of course if the processor is either MIPSR1, MIPSR2, or whatever. There are myriads of ways to do so, but we can just grab a binary from the squirrel and use readelf. The “busybox” binary will do:

readelf -h busybox |more
ELF Header:
Magic: 7f 45 4c 46 01 02 01 00 01 00 00 00 00 00 00 00
Class: ELF32
Data: 2’s complement, big endian
Version: 1 (current)
OS/ABI: UNIX – System V
ABI Version: 1
Type: EXEC (Executable file)
Machine: MIPS R3000
Version: 0x1
Entry point address: 0x4038a0
Start of program headers: 52 (bytes into file)
Start of section headers: 0 (bytes into file)
Flags: 0x74001005, noreorder, cpic, o32, mips16, mips32r2
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 7
Size of section headers: 0 (bytes)
Number of section headers: 0
Section header string table index: 0

Now we have everything we need to start the cross-compilation of TOR. The following table summarizes all of our findings:

 

Component Software Version
Standard C Library uClibc 0.9.33.2
SSL OpenSSL 1.0.0
Linux BusyBox 1.23.2
Kernel Kernel for MIPS 3.18.45
Architecture MIPS 32 Big Endian MIPS32R2

Setting up the cross-compilation framework

Although there are a bunch of ways to setup a cross-compilation framework, I have chosen Buildroot. After downloading this version, I have changed some basic things according to our previous table. Mind me, this version of Buildroot ships with newer versions of uClibc and OpenSSL, but we can fix that later on. You can find my configuration file for the buildroot framework here.

After performing the first compilation, I modified the uclibc and openssl packages to meet the Squirrel versions. According to the Buildroot documentation, there are some ways to customize your environment but I went the quick and dirty way instead. First, I did the following changes to build uClibc 0.9.33.2:

  • I downloaded uClibc 0.9.33.2 under $BUILDROOT/dl:¬†wget https://www.uclibc.org/downloads/uClibc-0.9.33.2.tar.xz.
  • I added the sha256sum of¬†uClibc-0.9.33.2.tar.xz to¬†$BUILDROOT/package/uclibc/uclibc.hash.
  • I changed uClibc version and package name in¬†$BUILDROOT/package/uclibc/uclibc.mk accordingly.

After that, I did the same with the libopenssl package:

  • I downloaded libopenssl 1.0.0.s under $BUILDROOT/dl:¬†wget https://www.openssl.org/source/old/1.0.0/openssl-1.0.0s.tar.gz.
  • I added its sha256sum to $BUILDROOT/package/libopenssl/libopenssl.hash
  • I changed libopenssl version and package name in $BUILDROOT/package/libopenssl/libopenssl.mk
  • I commented out the¬†LIBOPENSSL_PATCH variable in¬†$BUILDROOT/package/libopenssl/libopenssl.mk.
  • I moved all the patches to another directory to prevent the build system from applying them (because it was a different version, the patch command would fail): mv *.patch foo.

After all these changes, I performed the “make -j8” once again. At some point, when the libopenssl package was about to be installed, I got an error concerning the “install_docs” and “doc” rules. So I removed the “doc” directory from the¬†EDIRS variable in $BUILDROOT/output/build/libopenssl-1.0.0s/Makefile along with the “install_docs” rule in the install rule. After performing the compilation again, the following error showed up:¬†../libssl.so: file not recognized: File truncated. So I deleted this truncated file and executed “make -j8” again. This time the compilation ended without errors and the new libraries were sucessfully installed.

Finally, I removed the entire libevent from my previous built: rm -rf $BUILDROOT/output/build/libevent* and then I re-compiled it using the new OpenSSL libraries: make -j8. The buildroot environment was ready to use.

Cross-compiling TOR

Because our Packet Squirrel does not include the libevent library, I decided to build TOR statically linking libevent with the resulting binary. The PAcket Squirrel does not have support for some well-known modern protections, so I disabled any hardening during the compilation as well. The configure command I issued was this:

./configure –target=mips-buildroot-linux-uclibc –host=mips-buildroot-linux-uclibc –build=x86_64-pc-linux-gnu –prefix=/home/tonic as/buildroot/target/opt/tor –enable-static-libevent –with-libevent-dir=/home/buildroot/buildroot/build/libevent-2.1.8-stable/.libs/ –e nable-static-zlib –with-zlib-dir=/home/buildroot/buildroot/build/libzlib-1.2.11 –disable-gcc-hardening –disable-linker-hardening –disable-tool-name-check –disable-threads –disable-asciidoc

After that, I built and installed TOR: make -j8 install.

Finally, I copied all the files under $BUILDROOT/output/target/opt/tor to the Packet Squirrel, on its USB pendrive (previously formatted using EXT4): scp -r $BUILDROOT/output/target/opt/tor root@172.16.32.1:/mnt/

The payload

Because this device does not have too much free space, I had to setup some directories on the USB pendrive to accommodate some TOR files (logfiles and the like). With that done, I wrote the following payload:

#!/bin/bash
# TOR payload
# 2018 by T. Castillo Girona
# This is a simple payload that allows to route all the DNS queries and TCP
# traffic from a TARGET through TOR.
 
LOGFILE=/mnt/tor/logs/payload.log
TOR=/mnt/tor/bin/tor
TORCFG=/mnt/tor/etc/tor/torrc
TORLOG=/mnt/tor/logs/tor.log
 
IPTABLES=/usr/sbin/iptables
 
function grab_target_ip() {
 
	target_ip=`cat /tmp/dhcp.leases |awk '{print $3}'`
	if [ ! -z "$target_ip" ]; then
		# Set the led to BLUE:
		LED B
		echo $target_ip
	else
		# Set the LED to fail:
		LED FAIL2
		echo "`date` STAGE2: TARGET IP : Not a DHCP lease" >> $LOGFILE
		sync
		echo ""
		# Stop the payload:
		exit 1
	fi
 
}
 
function start_tor() {
 
	if [ -x $TOR -a -r $TORCFG ]; then
		# Delete any previous log:
		rm -rf $TORLOG 2>/dev/null
		sync
		# Start tor:
		echo "`date` STAGE3: EXECUTING TOR" >> $LOGFILE
		sync
		$TOR -f $TORCFG	2>&1&
		# It may take a while until tor is ready; that's when
		# its log file says: Bootstrapped 100%: Done
		echo "`date` STAGE3: WAITING TO HAVE A VALID CIRCUIT " >> $LOGFILE
		sync
		while [ true ]; do
			cat $TORLOG|grep "Bootstrapped 100%: Done" 2>/dev/null
			sync
			if [ $? -eq 0 ]; then
				# Perfect, we've got a circuit!:
				LED W
				echo "`date` STAGE3: WE HAVE A CIRCUIT " >> $LOGFILE
				break
			fi
		done	
	else
		# No tor binary or no torrc.
		# We leave it here.
		LED FAIL3
		echo "`date` NO TOR OR NO TORRC FILE." >> $LOGFILE
		sync
	fi
 
}
 
function set_ip_tables() {
 
	# Enable redirection for UDP DNS packets:
	$IPTABLES -t nat -I PREROUTING 1 -p udp -i eth0 --dport 53 -j REDIRECT --to-ports 5353
 
	# Enable TCP redirection through TOR:
	# (don't enable redirection for 172.16.32.0/24):
	$IPTABLES -t nat -I PREROUTING 2 -p tcp ! -d 172.16.32.0/24 -i eth0 -j REDIRECT --to-ports 9040
 
	echo "`date` STAGE4: SETTING IPTABLES " >> $LOGFILE
	sync
 
}
 
function rerunTor() {
 
	echo "`date` STAGE4: RE-EXECUTING TOR " >> $LOGFILE
	sync
 
	# Get pid of TOR process and kill it:
	ptor=`pidof tor`
	if [ $? -eq 0 ]; then
		# Kill it:
		kill -9 $ptor
	fi
 
	# Re-execute it:
	start_tor
 
} 
 
function run() {
 
	# Set networking to NAT
	# (we get an IP from the network; we assign an IP to the target)
	# The target gets routed through the Squirrel.
	echo "`date` STAGE1: SETTING NETMODE NAT " > $LOGFILE
	NETMODE NAT
	sleep 20
 
	# Now, make sure our target has a valid IP assigned
	# by the squirrel. Case it has not, stop the payload.
	LED STAGE2
	targetip=`grab_target_ip`
	echo "`date` STAGE2: TARGET IP IS $targetip " >> $LOGFILE
	sync
 
	# Now, prepare our instance of Tor, make sure it is
	# running before doing anything else:
	LED STAGE3
	echo "`date` STAGE3: STARTING TOR " >> $LOGFILE
	sync
	start_tor
 
	# Now set the iptables rules to redirect DNS and
	# TCP traffic trhough TOR transparently:
	LED STAGE4
	set_ip_tables
 
	# Let's set the LED to Success:
	LED R SUCCESS
 
	# Every time the user press the button, we kill
	# tor, and re-run it again so that the circuit
	# gets changed every time.
	while [ true ]; do
		NO_LED=1 BUTTON
		# Once the button has been pressed, proceed:
		rerunTor
		LED R SUCCESS
	done
 
}
 
# This payload will only run if we have USB storage
[[ ! -f /mnt/NO_MOUNT ]] && {
	LED ATTACK
	run &
} || {
	LED FAIL1
}

This payload simply setup the Squirrel as a NAT device; it will get an IP from the network on its “ETH OUT” interface and it will assign a dynamic IP Address to the TARGET computer on its ETH IN device. All the traffic from the TARGET computer will be routed through the Squirrel, and thanks to the iptables rules, the UDP packets for DNS and all the TCP packets will be redirected through TOR. Everytime the button is pressed, TOR is killed and re-executed, so a new circuit is constructed.

This payload is far from being perfect, but it delivers. Feel free to improve this version. If you do not want to go through all the burden of cross-compiling TOR, you can download the binaries here. Just unzip it directly on the USB pendrive on the Packet Squirrel, copy the “payload.sh” to the desired switch directory, and enjoy!