Writeup: bounce_the_flag

OSUSEC CTF League is back, baby! And it’s on Mondays! Piping hot writeups are back on the regular menu and we’re getting right into things with a classic SQL injection.

The challenge: “Let’s kick things off with one of my favorite classic games: Bounce the Flag! Bounce the flag is an immersive hyper-realistic gaming experience blah blah blah. One of Bounce the Flag’s most celebrated competitors, Mr. Flag, blahdie blahdie blah, forgot the password to his account, blah blah blah”

Forget about all that stuff – It’s gaming time!

Sweet! High score!

Awesome! I just got a high score! Time to record this epic win on the Bounce the Flag HOF!

What?! I definitely typed my password in right, but I must not have an account. I’m mad! This piece of gaming history deserves to be on the leaderboard! I’m gonna get this score up on the leaderboard, mark my words.

Luckily, we have access to the source code of the server and have been told ahead of time that the server is vulnerable to SQL injection 😀

username = request.form['username_input']
password = request.form['password_input']

res = sql_fetchall(
        connection,
        f"""
        SELECT score, game_time
        FROM users
        INNER JOIN games
        ON users.id = games.user_id
        WHERE username = '{username}' AND password = '{password}'
        ORDER BY game_time
        """
    )

Our opportunity lies in the unsanitized username and password field. Submitting

Mr. Flag' -- 

gives us the message “Pfffffft you call that a high score?!! Try again when you score at least 1337 points!”

As the score is held client-side, opening up the dev console and entering score=1338 is enough to log in and save our score.

If we can modify our username or password to break the SQL request for the stats page, we’re golden.

I had trouble crafting the username statement, so I switched to putting the exploit in the password, with the final exploit being:

Username: Mr. Flag
Password ' or 1=1 union select password,username from users --