Level 6A - The Chosen Ones
Domain(s): Web
Last updated
Domain(s): Web
Last updated
We have discovered PALINDROME's recruitment site. Infiltrate it and see what you can find! http://chals.tisc23.ctf.sg:51943
When we open the URL provided, we are greeted with a form that prompts us to guess a value.
It seems that we are required to guess a number between 1 and 1,000,000.
However, brute-forcing that value is extremely unlikely to work, therefore we need to look further into this. There is a comment hidden on the page that holds a Base64-encoded string.
Upon decoding this string, we are shown a function written in PHP.
The function generates a random integer lower than 1,000,000 using a seed which is calculated from the previous random number stored in the PHP session.
Let's first retrieve 4 sequential random numbers from the application by entering any value into the form. For example:
According to the code, the seed for the next random number is first calculated, and the current random number is that value % 1000000
.
This means that for the random number 477722, the seed for the next number could be 1477722, 2477722...
And in the following chunk of code
We can derive that the seed is smaller than the 2**32=4294967296
.
This means that for the value 477722, the seed generated could be 1477722, 2477722...429477722.
Therefore, knowing the current random number, we could guess the value of the seed to generate the next random number, which has a 1 in 4294 chance, compared to the earlier 1 in 1000000.
We can test this theory with the following code.
The code uses the previous random value to bruteforce the seed and checks if it matches the next value.
With this logic, we can write a script to bruteforce the random number generation on the website.
Running this script, we get a valid number after awhile and a cookie to use for further exploitation.
Using these cookies on the browser, we can now view table.php.
With the ability to search by first and last name, this already looks like a typical SQL injection challenge. However, it seems that the first and last name fields are not injectable.
We saw that there we have a cookie named rank. Let's try an always true payload in the cookie value.
We are able to list all of the users but the flag isn't there. Let's try to enumerate the database.
First, let's do a UNION SELECT and find the number of columns being queried.
With four columns, we see that the new row was appended to the result.
We know that the DBMS is MySQL, so we can crafta query as follows, to gather information about the tables.
We find a table named CTF_SECRET which is likely the table we are supposed to target
Now, we list the columns in the table and we see a column named flag.
Now all we need to do is query the flag column from the CTF_SECRET table.
Flag: TISC{Y0u_4rE_7h3_CH0s3n_0nE}