Reverse ASUS RT-AC5300

Downloading firmware
In this laboratory, we are going to use the model: RT-AC5300 firmware.

Extracting the firmware
At this moment, we need to unzip the zip file and use binwalk to analyze the .trx file. Using the option "-e" we can extract all the files from the .trx file.

We can see the firmware uses little-endian, and this is probably a sign that it is using a 3x ARM version or minor.

We got the WWW content 😎

After emulating it, seems like this:

User mode - Firmware emulation
Why not emulation your router firmware instead of getting a physical device? 🤓
Backing to the extracted folder from the .trx file (firmware itself), we have a file called 1C we need to analyze. We got some precious information, such as:

We can confirm some details by using the Linux strings utility:
In sum, we can confirm the following details:
Kernel version: 2.6.36.4
gcc version 4.5.3
Buildroot 2012.02 (used to compile the rootFS)
ARMv7 processor - Dual Core 32-bit ARMv7 (Cortex-A9) @ 1.4GHz
FS ini present on /etc and /root folders! 😱
In fact, we should check everytime the device configuration available on the vendor page to learn about it, and get the device datasheet in order to confirm some details.

Using qemu-arm approach
Per-process emulation is useful when only one binary needs to be emulated. To this that, next install full dependencies:
The user-mode emulation can be made by using the following command:
The -L option is important for when the binary links to external dependencies such as uCLibc or encryption libraries. It tells the dynamic linker to look for dependencies with the provided prefix.
We can get the following error:
qemu-arm: Could not open '/lib/ld-uClibc.so.0': No such file or directory
By inspecting the /lib/ folder, we can see the following:

The file "ld-uClibc.so.0" is present, so we need to just add the current dir to the qemu-arm execution. Otherwise, if the UClibc.so file has another name, we could resolve that by doing a symbolic link, e.g.: squashfs-root/lib/ld-uClibc-0.9.29.so to squashfs-root/lib/ld-uClic.so.
So, the final qemu command is the following:
Using qemu-user-static approach
Another way to emulate the process is to perform a cross-architectural chroot with QEMU.
You can also download the target qemu-user static file pre-compiled from GitHub 😼
Next, we copy the qemu-arm-static binary to the rootFS directory of the firmware. We then chroot into the firmware root and obtain a working shell:


This is possible due to QEMU registering with the kernel during installation to handle binaries with certain magic bytes via the binfmt_misc mechanism.
We can try to run the httpd service, getting some errors - of course, because the /etc/ folder is not mounted, NVRAM system is not present - but we will just workaround this later! 😎

This is the best method to test a single binary or feature in a short period of time without losing a lot of hours configuring and preparing the environment.
Next, we can start e.g., telnetd service inside our emulated environment ;)
Emulation NVRAM
In the previous user emulation scenarios, we found problems to emulate correctly the NVRAM. In this way, we can use hooks in a simple library to intercept calls to libnvram using LD_PRELOAD.
You can simply access this project on GitHub, compiling the C files with the target arch (ARM) or just download the arm version from releases.
You can also compile the nvram file using a cross-compiler for ARM architectures.

It works 😋

Hook functions
If we need to hook any function, LD_PRELOAD is our best friend.
For example, the next hook will emulate the native open file call from gclib.
We can compile it onto ARM using a cross compiler:


Even though we don't have the /etc/rc.d or /etc/init.d to run the appropriate RC script to kick off the userland services, we were able to execute single binaries, which can give us some input about the device operation, or even finding vulnerabilities at this level.
Firmware full emulation
To do this, we can use Buildroot 2012.02 to create your rootFS and compile kernel version 2.6.36.
To compile it, you can use a normal Linux distribution (Kali Linux), or try to use an old version of ubuntu 16.4.
To start using buildroot, you need to compile the manual and learn about it.
For this ASUS router, the best configs are the following:







board config name:

To choose the right kernel defconfig:
or accessing: output/build/linux-2.6.36.4/arch/arm/configs

To start the compilation process: make all or using a specific GCC version: make HOSTCC=gcc-4
Fixing kernel crashes or dependencies
"gets" undeclared here

Fix
textinfo incompatibilities with GCC documentation
This is frustrating me too, I cannot install texinfo, because texinfo is compatible with the tex documentation for this version of the compiler I have to use, which is what's breaking the documentation in the first place.

Instead of editing files, when I run make I pass the argument MAKEINFO.
One minor point about this. I think it should be pointed out what this does. It basically overrides the MAKEINFO variable predefined by GNU make, which normally points to the program to call in order to get makeinfo invoked. So by setting it to true you are effectively replacing calls to makeinfo by calls to /bin/true (can be seen with make -npf /dev/null |grep ^MAKEINFO).
Fix
Can't use 'defined(@array)'

Fix
Can’t use ‘defined(@array)’ (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373 has prompted where is the delicate error message, open timeconst.pl to see (under the kerner directory).
Compiling everything is a long journey, you can also test more recent kernel versions and so on to avoid some errors when you are building your environment for emulation.
At the end, you will get something like this on your output/images folder:
Now, it's time to start your qemu emulator:
Finally, merge the rootfs (host + router), and exploit it like a baws 😉




Using docker containers and relax to emulate your firmware 👾
Other options instead of using qemu are docker containers.


Resources
Last updated
Was this helpful?
