

Here is how I captured the stripe.com CTF flag. A complete walkthrough. - dividuum
https://github.com/dividuum/stripe-ctf

======
agscala
I've always read about these techniques but it's way, way cooler being able to
see them actually done. I don't think I would have gotten nearly this far, so
such a detailed explanation of every solution taught me a lot!

Thanks a bunch

~~~
saurik
Reading this, I found it interesting how much guesswork was totally
reasonable. In comparison, my solutions to the buffer overflow levels involved
runnging objdump on the binary and calculating the exact indexes and addresses
I wanted; the idea of "just put it in there 20 times and guess until it works"
might have occurred to me, but only after I had given up understanding the
specific state machine.

While this made my solution for the fun() level much cleaner (I didn't need a
nop-slide, and I had no shell code: I overwrote a single address on the stack
to short the program into a call to system(), return-to-libc-style), it
apparently wasn't warranted to spend that time or effort: dividuum was able to
metaphorically sprint through those levels while I was wasting time staring at
the track. ;P

~~~
dividuum
I didn't bother trying the return-to-libc approach since the bruteforce way
worked for me. I guess your result is much cleaner though. Do you have any
code online?

~~~
saurik
The only level that involved "code" was the final one; otherwise, it was more
just running the program with the right arguments (so I'm not exactly certain
what you are hoping to see). While solving the levels I tried to get each one
down to an easily-paste-able bash command-line. If you log in as level04 you
can just paste this command:

while ! echo 'cat /home/level05/.password' | /levels/level04 "$(printf
%1036s)"$'\xd0\x23\x5b\xf7____\xee\xab\x6a\xf7' | grep -F ''; do true; done

(To be clear: I still had to brute force the ASLR; but even if you are doing
the executable-stack+shell-code approach, you don't need the nop-sled as you
can just calculate exactly where you intend to return to; that's what I meant
by "totally reasonable" "guesswork": the nop-sled works and kept you from
having to stare at the assembly.)

(Note: my original version only required a single address, but involved more
messiness outside of the program; the command I pasted here is a revision I
made after an e-mail exchange I had with a1k0n, who reminded me that "/bin/sh"
was a string that already existed in libc, so I could run an actual shell
rather than some random garbage.)

(edit: Awesome! It turns out mpetrov managed to make a 100% deterministic
version, which makes the executable-stack+shell-code approach look a lot
cleaner, as it drops away that irritating brute force step ;P.
<http://news.ycombinator.com/item?id=3630826>)

