After reading through a lot of the discussion in the discord, it seems like people pulled down the image and went searching for a needle in a haystack. While this works, I would like to take this time to highlight my favorite Docker reversing tool, [dive](https://github.com/wagoodman/dive).
Dive is a neat tool that lets you see all of the changes made to an image layer by layer. This can help expedite the process of reversing because you get a list of things that were done to the image, and are able to view those changes in the file system of the image. You still have to navigate to the overlay directory on your machine to get the file, but this has saved me a lot of time during CTFs in the past.
I'll switch over to my Remnux machine to show exactly how it's done. We're already given the name of the image, so we can just load that onto our machine.
remnux@remnux:~/ctf/htb_uni/forensics_peel_back_layers$ docker pull steammaintainer/gearrepairimage
Using default tag: latest
latest: Pulling from steammaintainer/gearrepairimage
7b1a6ab2e44d: Pull complete
858929a69ddb: Pull complete
97239c492e4d: Pull complete
Status: Downloaded newer image for steammaintainer/gearrepairimage:latest
For people that don't understand, the `steammaintainer/gearrepairimage` refers to the name of a docker repository, which is similar to a git repository in many ways. Simply put, docker repository are supposed to store and provide docker images, along with elements of version control with those images. The `docker pull` command is, in a sense, similar to the `git clone` command.
We can now check the status of our image with `docker images`.
remnux@remnux:~/ctf/htb_uni/forensics_peel_back_layers$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
steammaintainer/gearrepairimage latest 47f41629f1cf 9 days ago 72.8MB
Now that the image is up, we can load it into dive by using the image ID, and start using the tool.
remnux@remnux:~/ctf/htb_uni/forensics_peel_back_layers$ sudo dive 47f41629f1cf
This is what `dive` looks like.
A brief explanation of what you're seeing:
- The top left window labeled **Layers** shows the layers and stages that make up the image. You can navigate through these using the arrow keys.
- The window to the right labeled **Current Layer Contents** shows you exactly what the file system looks like at that layer. `dive` also tries to color code what files have changed or were added.
- The window to the left called **Layer Details** tells you exactly what commands were executed in the Dockerfile, a file that sets up the image on launch, for that layer
If we look at the second layer, we notice the following entry in "Layer Details".
#(nop) COPY file:0b1afae23b8f468ed1b0570b72d4855f0a24f2a63388c5c077938dbfdeda945c in /usr/share/lib/librs.so
This seems to be the only lead at this time. We can locate this file in the "Current Layer Contents".
We can access the file by entering the image at that layer and going from there, but I find it easiest to go to `/var/lib/docker/overlay2`.
root@remnux:/var/lib/docker/overlay2# ls -la
drwx--x--- 6 root root 4096 Nov 22 11:20 .
drwx--x--- 13 root root 4096 Nov 22 11:20 ..
drwx--x--- 3 root root 4096 Nov 22 11:20 2d4dd1a91c123d2099cb70cba5b4312c92b724babdf35dcdb864beee914e0ca0
drwx--x--- 4 root root 4096 Nov 22 11:26 45e6bf07a22d7ce25c287cf9828868893e36983898de96d800c412463964c869
drwx--x--- 4 root root 4096 Nov 22 11:26 c9272024e3fffe4dc145973237870c8a8aecf8689392daf21b6719ad24ca7401
drwx------ 2 root root 4096 Nov 22 11:20 l
We've already done the work of finding the file that looks out of place, so we just have to navigate the relevant layer folder and grab the file (alternatively, run a quick find command and work from there). I'll copy this shared object file to my working directory from earlier, and do my go-to move of running `strings` on the file. We find the flag almost immediately, just have to do some cleaning up.
remnux@remnux:~/ctf/htb_uni/forensics_peel_back_layers$ strings librs.so
Some further analysis in ghidra shows us that the flag was hard coded in hex across 4 lines, so that's why it looks the way it does.
Although we've already found the flag, we probably don't want a random image still running on our system, so we can run `docker image rm IMAGE_ID`, after exiting `dive`, to remove the image.