Contents

Synk Fetch the Flag 2022 - Forensics - Potty Training


Contents

Potty Training

writeup

This challenge has no task description besides that the challenge was sponsored by stegano.

Let’s download the file from the description:

1
wget https://fetch.ctf-snyk.io/files/4d3889ec3c6d7d8af2978a36d6bc1460/potty.png?token=eyJ1c2VyX2lkIjo1MjExLCJ0ZWFtX2lkIjo0MDgsImZpbGVfaWQiOjQyfQ.Y2whFQ.hjYZ3KoJnXjQD7-foPUzzD8UTyQ -O potty.png

Here is the image:

/images/potty.png

First let’s check if this is really a png file by running the file command:

1
2
3
file potty.png 

potty.png: PNG image data, 1650 x 1200, 8-bit/color RGB, non-interlaced

So it looks like it is in fact a png file.

My first attempt was to just print out every readable string using the strings while searching for the flag format like so:

1
strings potty.png | grep SNYK

But it did not find anything.

Knowing that we have a png file here, I could use some tools like zsteg to find the flag:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
zsteg ./potty.png   
                                                                        1imagedata           .. text: "-\"\nVD51%"
b1,r,lsb,xy         .. text: ";R.3Ov?*7.>?&\""
b1,rgb,lsb,xy       .. text: "111:\n        import requests\n        r = requests.get('http://potty-training.c.ctf-snyk.io/')\n        print(r.text)"
b2,r,msb,xy         .. text: "]}}wUuUu"
b2,g,msb,xy         .. text: "u}UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU"
b2,b,lsb,xy         .. text: "AUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU"
b4,r,lsb,xy         .. text: "gfgvgvvvfffvfffvfgwwggwvgffvfggwfggwgvvvfffvfffvfgfvgffvfggwfggwgvvwfgfvfwvwggfvfvwvfwfwgfwwgwgvfwwwfvvvfwgwfvwvfwwvfwwwfvgvfvfvfffvfffvggfvfwfvgvvwfgvwffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
b4,r,msb,xy         .. text: "nnnfffnfffnf"
b4,g,lsb,xy         .. text: "fwfvgffffgfffgfffgffvgvwvgfwvwfvvwfvvvfffgfffgfffgffgwfwvwfvvwfvvwvgvwvffwfvvgfwgwvvwwvvwwvvvgffwgfgvwvgggfvvgvwwgfgggfggwvfggfffgfffgffvgffwgvfvgvvvwfvgvffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
b4,g,msb,xy         .. text: "nffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
b4,b,lsb,xy         .. file: 0420 Alliant virtual executable not stripped

zsteg found some python code hidden in the lsb (least significant bit) inside the image:

1
import requests\n        r = requests.get('http://potty-training.c.ctf-snyk.io/')\n        print(r.text)

LSB steganography is a common way of hiding text inside images.

You can read more about LSB Steganography here: https://itnext.io/steganography-101-lsb-introduction-with-python-4c4803e08041 as I will not dive too deep into how exactly this works here.

We can now start to create a new python program using the code we got from zsteg:

1
echo "import requests\n        r = requests.get('http://potty-training.c.ctf-snyk.io/')\n        print(r.text)" > flag.py

let’s check it:

1
2
3
4
5
cat flag.py   
          
import requests
        r = requests.get('http://potty-training.c.ctf-snyk.io/')
        print(r.text)

ok let’s try to run it and see if we can get the flag:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
python3 ./flag.py

<html>
  <head>
    <title>Good puppy!</title>
  </head>
  <body>
    <h1>Good puppy! 🐕</h1>
    <p>Here's your flag 🦴</p>
    <p>SNYK{dd67edb70a28335068dd5ea9304007b69543357ff471b3144e3355bca34cb35d}</p>
    <a href="https://snyk.io/blog/snyk-international-dog-day-recap/">Snyk + Dogs = 💜</a>
  </body>
</html>

And it worked! We got back the flag from the sever.

flag: SNYK{dd67edb70a28335068dd5ea9304007b69543357ff471b3144e3355bca34cb35d}