DeconstruCT.F 2023 - why-are-types-weird
Description
Category: Web
Jacob is making a simple website to test out his PHP skills. He is certain that his website has absolutely zero security issues.
Find out the fatal bug in his website.
Resolution
1. PHP Type Juggling
We navigate to the website and we have a login page.
We need to log in as admin
but we don’t know anything about the password.
However, there is a big hint in the title: why are **types** weird
.
It reminds me PHP Type Juggling and I tried magic hashes payloads from PayloadsAllTheThings because:
- when we login, only the hash of the password is compared;
- magic hashes are hashes that start with
0e
followed by digits. PHP interprets them as scientific notation so those magic hashes are interpreted asint(0)
. 'abc' == 0
for any string including the hash of the real password!
We need to try several hashes because we don’t know the algorithm used.
After trying some hashes, we found a valid one: 10932435112
.
This magic number has a hash of 0e07766915004133176347055865026311692244
with the SHA1 algorithm and allowed us to connect as admin
.
2. PHP Injections
Now we are logged in as admin
and we have access to the admin panel:
It asks us for an ID
and returns the username
and the password
of that user.
When we enter nothing we get an error:
1
Warning: SQLite3::query(): Unable to prepare statement: 1, incomplete input in /var/www/html/read_details.php on line 8
Now we know that we can do SQL Injection and more importantly that the database software is SQLite3.
We tried to list all users with the input 1 OR 1=1
but there is not the admin
user.
admin
must be in a different table, we can list all the table with this query: SELECT sql FROM sqlite_schema
.
When added to our input it becomes: 1 union SELECT sql FROM sqlite_schema
.
We got this error:
1
Warning: SQLite3::query(): Unable to prepare statement: 1, SELECTs to the left and right of UNION do not have the same number of result columns in /var/www/html/read_details.php on line 8
It means that the number of columns of the first table (3: ID
, Username
and Password
) doesn’t match with the number of column of the second table (only 1: sql
).
We just need to add columns like this: 1 union SELECT sql, 1, 1 FROM sqlite_schema
.
This time we got a list of table:
We can see that there is a table called power_users
where admin
should belong to.
Let’s get all of them with this injection: 1 union SELECT id, username, password FROM power_users
.
And this time we get the flag: dsc{tYp3_juGgl1nG_i5_cr4zY}
.