The Wonderful World of MIPS

The ever growing Internet of Things (IOT) brings with it a new wave of malware geared toward unfamiliar architectures. Today we take a look at how to compile, analyze, and debug MIPS based binaries. Filename None MD5 None Sample None Video INTRO

MIPS is a Reduced Instruction Set Computer (RISC) that has been around since the early 1980's and it is commonly used in residential gateway routers and switches. You can see why malware authors would want to target MIPS based devices. Today we will demonstrate how to compile, run, analyze, and debug an example MIPS program written in C on an x86 system. While the code we are using is not malware, the techniques and methods in this article will allow you to analyze MIPS based binaries/malware. MIPS is a Reduced Instruction Set Computer (RISC) that has been around since the early 1980's and it is commonly used in residential gateway routers and switches. You can see why malware authors would want to target MIPS based devices. Today we will demonstrate how to compile, run, analyze, and debug an example MIPS program written in C on an x86 system. While the code we are using is not malware, the techniques and methods in this article will allow you to analyze MIPS based binaries/malware.





CROSS COMPILING MIPS ELF ON x86

We will be using Kali Linux 2018 for our base VM. In order to compile our own MIPS ELF, we will need to install a few dependencies



apt-get install linux-libc-dev-mips-cross libc6-mips-cross libc6-dev-mips-cross binutils-mips-linux-gnu gcc-mips-linux-gnu g++-mips-linux-gnu



Today we will use some sample C code that prints out the current PID and PPID as well as the current iterations of a WHILE loop. It will also perform FORK and again print the PID and PPID of the current process. You will notice after the FORK there will be two outputs: one from the parent process and one from the child. It is important to practice debugging FORKs in MIPS because debuggers have a tricky time dealing with them (CLONEs as well.)



Here is the example code we will use for compilation. Be sure to save it with a name like mips-test.c or something similar.



#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

int main(){

printf("PID: %d

",getpid());

printf("PPID: %d

",getppid());

int i = 0;

while(i < 4){

sleep(1);

printf("ITERATION #%d

",i);

i = i + 1;

}

fork();

for (int w = 0; w < 10; w=w+1){

printf("%d: %d\t%d

",getpid(),getppid());

sleep(1);

}

printf("EXITING: %d

",getpid());

return 0;

}









mipsel-linux-gnu-gcc -xc -static -o mips-test.elf mips-test.c



You should now have a file named mips-test.elf. You will need to CHMOD +X mips-test.elf in order to run it. However, if you try to run the file you will encounter and error stating that the architecture is not supported on your machine. In the next section we go through how to run the MIPS ELF on your x86 machine.



RUNNING MIPS ELF ON x86

Again we start by retrieving dependencies:





apt-get install qemu

apt-get install bridge-utils



QEMU is an emulator which allows you to run many different architectures within your host machine and bridge-utils will be needed to enable network functionality later on.



QEMU has two modes: User Mode and Full System Emulation.



QEMU USER MODE



User mode allows us to run a single binary natively through the command line (like the one we just compiled) using the following command:





qemu-mipsel [-strace] [-g 12345] mips-test.elf



To run the binary as-is disregard the -strace and -g 12345 options of the command line. Simply use qemu-mipsel mips-test.elf.



The option -strace outputs the binaries' system calls to the terminal. This can be helpful to get a quick understanding of what the binary is doing.







The -g 12345 option tells QEMU to open the ELF with a GDB Stub loader listening on port 12345. This pauses the ELF at the entry point and waits for a GDB session to be established. We will discuss how to attach to this GDB Stub loader later in the article.





QEMU SYSTEM EMULATION





https://people.debian.org/~aurel32/qemu/



Specifically for this demonstration you will need the MIPS Little Endian flavor of Debian and its corresponding kernel image.



https://people.debian.org/~aurel32/qemu/mipsel/debian_wheezy_mipsel_standard.qcow2

https://people.debian.org/~aurel32/qemu/mipsel/vmlinux-3.2.0-4-4kc-malta



Once you have downloaded these two files you will need to create a shell script in the same folder. You can name it start.sh or something similar. The script will look like this (be sure to modify the path variables at the top to correspond to where you put your files):

#!/bin/bash

qemu=qemu-system-mipsel

path="$HOME/Documents/Debian-MipsEL"

hda="$path/debian_wheezy_mipsel_standard.qcow2"

kernel="$path/vmlinux-3.2.0-4-4kc-malta"

iface=tap0

echo "Stopping eth0, starting tap0"

/etc/qemu-ifup tap0 || quit 1 "Failed to start tap0"

echo "Starting Debian MIPS"

$qemu -net nic -net tap,ifname=$iface,script=no,downscript=no \

-M malta -kernel $kernel -hda $hda -append "root=/dev/sda1 console=tty0" -nographic



QEMU automatically creates the file /etc/qemu-ifup which is supposed to enable networking for the emulated MIPS system, however, I have had many issues with this, so we will be using a modified version for this demonstration. Feel free to backup the current qemu-ifup file because we will be replacing it's contents with the following code (WARNING: These commands work on Kali 2018.1. Be sure the variables at the top are being configured correctly for your distro. ):



#!/bin/bash

ETH0IPADDR=$(ifconfig eth0 | grep inet | cut -d: -f3 | awk '{print $2}')

GATEWAY=$(ip route | awk '/default/ { print $3 }')

BROADCAST=$(ifconfig eth0 | grep broadcast | cut -d: -f3 | awk '{print $6}')

USER=$(whoami)

# First take eth0 down, then bring it up with IP address 0.0.0.0

/sbin/ifconfig eth0 down

/sbin/ifconfig eth0 0.0.0.0 promisc up

# Bring up the tap device (name specified as first argument, by QEMU)

/usr/sbin/openvpn --mktun --dev $1 --user $USER

/sbin/ifconfig $1 0.0.0.0 promisc up

# Create the bridge between eth0 and the tap device

/sbin/brctl addbr br0

/sbin/brctl addif br0 eth0

/sbin/brctl addif br0 $1

# Only a single bridge so loops are not possible, turn off spanning tree protocol

/sbin/brctl stp br0 off

# Bring up the bridge with ETH0IPADDR and add the default route

/sbin/ifconfig br0 $ETH0IPADDR netmask 255.255.255.0 broadcast $BROADCAST

/sbin/route add default gw $GATEWAY



Next we will need a way to undo this bridged network, so we will edit the /etc/qemu-ifdown file and replace it's contents with the following code:



#! /bin/sh

# Bring down eth0 and br0

/sbin/ifconfig eth0 down

/sbin/ifconfig br0 down

# Delete the bridge

/sbin/brctl delbr br0

# Bring up eth0 in "normal" mode

/sbin/ifconfig eth0 -promisc

/sbin/ifconfig eth0 up

# Delete the tap device

/usr/sbin/openvpn --rmtun --dev $1

We can now utilize the following command to cross compile our code to MIPS-Little Endian:Get ready for an epic adventure. To start, we will need to download a couple files from:Now we are off to the races. To start your emulated MIPS system all you need to do is run your start.sh script (don't forget to CHMOD +X). Bootup takes a bit, but if everything went correctly you should be greeted with a login prompt for your MIPS Debian emulated system with user/pass being root/root: