This is a cool way to quickly emulate architectures other than the one you’re running on without having to roll out a full VM!
I’ve done a basic and awful job of automating it so you can see how the pieces work together. You’ll probably need to tweak a bunch of stuff to use these tools more generally, but now you have a clear starting point from which to tinker.
How to do the thing
I’ve made three scripts: one to prepare your environment, one to build the Dockerfile and container image, and one to run the container (I’ve only included two run commands but obviously you could store whatever you wanted in there).
I’ve presented them this way so it’s easy to follow. I don’t think the run script is required.
Here is a usage example with the WNAP320 firmware:
git clone https://github.com/unmeg/docker-emu.git
mv WNAP320* firmware.zip
chmod +x prep_docker.sh run_docker.sh build_docker.sh test_docker.sh
These commands will eventually drop you into a shell with access to the extracted firmware rootfs.
I used this the other day to test a bindshell I’d compiled for a router I’m working on. It was super quick and easy because I just put the compiled binary in the /addons folder and built the container. Seconds later I was running the shell and testing its functionality.
I haven’t gotten gdbserver and remote debugging to work with this setup yet, which would sort of boost the whole thing from Very Cool to Totally Awesome.
As of writing, I successfully get the binary (by putting it in addons) and can run it, but I get packet errors when I connect with GDB from my host. I’m not sure where the problem is and I haven’t really spent any time on it.
My plan was to figure it out before posting this up, but I’m getting more and more distracted from that task every day, so it may be a while.
If you get it working, let me know how and I’ll update the scripts/post with credit to you!
Credit where it’s due
Speaking of credit..
I stole this idea wholesale from a great AirGap2020 talk on emulating firmware with Docker. You should watch the video and give thanks to Ilya.
I’d never touched Docker before this side-quest so it’s possible I’ve done this in a sub-optimal way. Feel free to let me know if you see anything daft.
Similarly, I compiled these scripts like a week after I got this all working, and I was neither careful nor considerate when I threw in package downloads and repo clones. It’s possible I’ve grabbed too much stuff for your setup! I was just trying to account for all possible comers. Carve out whatever you don’t want.
These scripts are for MIPS so firmware for other architectures won’t work. At some point I will do some other versions too, but the idea was just to demonstrate how this works.