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:
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
1 ⨯
imagedata .. 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}