Sunday, September 20, 2015

CSAW CTF 2015 Write Up: Weebdate (web500)

The anual CSAW CTF Qualification Round took place on September 18-20 and it was yet another really cool CTF. I played with my friends from TheGoonies and we ranked #128 overall (The Goonies 'R' Good Enough).

Task - Weebdate (web500)

Since the Ashley Madison hack, a lot of high profile socialites have scrambled to find the hottest new dating sites. Unfortunately for us, that means they're taking more safety measures and only using secure websites. We have some suspicions that Donald Trump is using a new dating site called "weebdate" and also selling cocaine to fund his presidential campaign. We need you to get both his password and his 2 factor TOTP key so we can break into his profile and investigate.

Flag is md5($totpkey.$password)

http://54.210.118.179/

This is a basic Flask application running a dating site. The website has some features like most web applications we are used to: creating users, editing profiles, sending messages, searching users and exposing the whole customer data thourgh SQL Injection and LFI.

SQLi

The CSP reporting URI was vulnerable to SQL injection. SQLmap had no problems finding and exploiting it.

python sqlmap.py -u 'http://54.210.118.179:80/csp/view/1' --cookie='session=donaldtrump010_1442717300_f65cb746b519c2b49f8e938a896e08e96f5fc533' --dbms=mysql --batch
The 'weeb' database had three tables: messages, reports and users. The 'user' table had eight columns: user_id, user_name, user_password, user_ip, user_image, user_credits,
user_register_time and user_profile.




Passwords had a SHA256 pattern so I quickly started cracking them using John The Ripper:

john --format=raw-sha256 hash.txt --wordlist=rockyou.txt

Most cracked passwords had patterns like 'testtest', 'lablab' and 'guest1guest1'. After some time I realised that the username was used as a Salt. I generated a small wordlist concatenating donaldtrump's user and password and I finally managed to crack it:




The login form displays "Invalid verification code" when you type a wrong TOTP verification code and it returns "Invalid credentials" when you mistype the password. I knew that his password was 'zebra' but I still needed to find out the TOTP algorithm in order to steal his seed.
LFI

The 'image_url' parameter from '/profile/edit' was vulnerable to LFI, displaying the full content from local files:



A curious note here is that it was the first time I managed to find a bug using Burp Collaborator. The scanner identified the external HTTP/DNS interaction and after some digging I quickly found the LFI =)
After some a lot of time bruteforcing the dirs and files, we managed to find the server root:
We are particularly interested on the generate_seed() function:

- server.py


- utils.py


The TOTP is not stored server-side: it is generated at runtime using a seed based on the username and his registration IP Address. We had the user IP address from the SQLi dump and we can now use the get_otp_key() function to generate his TOTP key:
The flag is the md5($totpkey.$password): a8815ecd3c2b6d8e2e884e5eb6916900