Tags: curl web discord lfi 


Writeup by Ender

StegBot has two commands, extract and embed. Both modes use `curl` (this is important) to write files to a temporary folder that can be used for extraction, embedding, or simply downloading an image.

The fact that the program uses `curl` to download the files is handy for getting things from the web, but this also opens up another possibility: local file inclusion with the `file://` protocol. However normally this would be restricted to jpg files in both modes, *except* that there is no check in the "embed" mode with just the image URL. This means we can download any accessible file from the remote system.

The flag is embedded in a processed image that's accessible on the local file system, the original one marked as `bof.jpeg`. By nature the program marks the processed files with a cryptographically secure filename, but . . . it also logs the names of the resulting file and original file to a log file. Along with the password.

Step 1: Testing. As a test, I used the embed command without additional arguments to download `file:///app/bof.jpeg`. No argument, the file appeared moments later. LFI is a go.

Step 2: Retrieving the log. I found the file that was being used for logging and passed `file:///app/app.log` as my "embed" URL, and got back an unreadable file. This was fine, however, as the program simply marked a log file as jpeg and gave it to me without fuss. Dropped the `.jpeg` extension and opened it up as a text file. `bof.jpeg`, its processed kin's filename, and the password were in the first line. Could also use this to snag `/etc/passwd` and maybe even more privileged files depending on what user the service is running under, though getting sensitive data is nasty enough on its own.

Step 3: Snagging. Using extraction mode, I passed the URL to the processed image alongside the password, bot spat out the flag. GG.

Missteps: At one point I thought to try a steghide CVE exploiting a reduced bruteforce, but that involved actually having the file to begin with. Additionally, the bot uses the `spawn` family of commands for its shell executions, so bash RCE wasn't possible.