Injectics
Use your injection skills to take control of a web app. - by 1337rce & l000g1c
Last updated
Use your injection skills to take control of a web app. - by 1337rce & l000g1c
Last updated
The following post by 0xb0b is licensed under CC BY 4.0
We start with a Nmap scan and find only two open ports, 22
on which SSH is running and a web server on port 80
.
On the page we find an allusion to the Olympic Games, only this is the Injectics. The games of injections, nice :D.
There is one login form, from which another admin login is possible.
The following shows the admin log in.
When testing both forms for SQL injection, the former is the normal login conspicuous. This gets an error when entering the special character '
. We use Burp Suite, because the client-side filter excludes the use of special characters.
We use the following payload list of HackTricks to test for possible SQL injections.
We use FFuF to try them out and filter the results with error message containing num_rows
or no change at all. We have a variety of hits but choose the first one ' OR 'x'='x'#;
.
We pass this URL encoded via Burp Suite because of the said filter. We intercept a login request, manipulate it (username=' OR 'x'='x'#;
), forward this and the subsequent requests and are redirected to /dashboard.php
.
On the dashboard, we have the possibility to edit the ranking list.
Let's take a closer look at editing via /edit_leaderboard.php
.
We are able to execute stacked queries.
A stacked query attack involves injecting a payload that includes multiple SQL statements separated by a semicolon (;
). This allows the attacker to execute multiple queries in a single execution context.
We assume that the table is called leaderboard. We get the parameters from the URL. Using our stacked query, we can now rewrite the country field. This means that we can write information that we want to enumerate from the database into the country field in order to exfiltrate it.
At first, we will limit ourselves to one field, later we will just use all fields, otherwise it would be too time-consuming to always determine the content of the field. We can determine the version of the database.
Version of DB:
We can determine the current database, we need to enumerate the entire schema.
Current DB is bac_test
:
However, when trying to retrieve information from information_schema
, nothing was found.
The field remains unchanged.
A filter seems to be active, this has already been noticed before, but was not taken into account at first. When testing the SQL injection, I wanted to reset the table to its origin because I always worked row by row. Something special happened with the wirting the name Korea
. When trying to write this country into the table, only Kea
was written. So the OR
is cut out before the SQL evaluation. At first, I didn't think anything of it. But the word inf
or
mation_schema
also contains an or
.
Result of changing to the name Korea:
There may be more SQL keywords filtered. Let's try it first with SELECT,
FROM,
OR,
and information_schema.
(FROM should work, as we have already used this successfully). And we see that SELECT
and the or
are deleted from information_schema
becomes infmation_schema
. I have not shown the payload input in the screenshots below, as it would otherwise be too much.
Ok, how can we work around this. If the words are deleted as a whole, SSELECTELECT
could become SELECT
again: S[SELECT]ELECT
This would then only have to be evaluated, let's hope. To check our bypasses, we write these OORR
and SSELECTELECT
in the country field. And they are filtered as expected.
We are now adapting our previously failed query. SELECT
becomes SSELECTELECT
and information_schema
becomes infoorrmation_schema
. We are now able to enumerate the tables. We have the tables leaderboard
and users
.
The users table has the fields email
and password
, among others:
The contents of these fields are now obtained using the following query (Here, too, we have to adjust the password field for the filter.):
We are able to extract the credentials of two users. For dev@injects.thm
and superadmin@injectics.thm
.
We use the credentials from superadmin@injectics.thm
to log in to adminlogin /adminLogin007.php
.
A redirection to the dashboard takes place, but this time we find the first flag there.
This solution completely escaped me and shows how important it is to enumerate at the beginning. Many thanks to h00dy, we had discussed our solutions, and he showed me this one.
Don't miss out on his content:
There is a mail.log
, with a crucial hint.
If the users table is ever deleted or corrupted, it will be filled with the default credentials from the mail.
So just drop the users table, and we can then use the default credentials found to log in to the admin portal and get the first flag.
At the Profile page, we can now customize our first
and last name
. The email
cannot be changed. No payloads for SQL injection apply here.
What we do see, however, is that the first name is reflected on the dashboard. This could possibly be an SSTI.
We try the SSTI payload {{7*7}}
to determine whether it is actually an SSTI.
And this is also evaluated. SSTI is possible!
The following resource provides helpful information for discovering SSTI and determining the template engine.
Don't miss out on the following resource too, but twig is not covered there:
Using the following tree, we can see how we can determine the engine. Since {{7*7}}
was evaluated, this could be Jinja
2, Twig
or Unknown. Since we know that it is a PHP server, it will probably be twig, but it could also be an engine that is not vulnerable or unknown.
We try the {{7*'7'}}
payload and...
... it gets evaluated, it is very likely twig
.
At PayloadsAllTheThings
we find a number of payloads that we can test, but none of them seem to work:
passthru does not seem to be filtered, but the filter function seems to be anonymized because we are in a sandbox.
On HackTricks we find other payloads that also do not work, but here the function sort
for system is still used.
By combining the two, we get a payload that works:
So we can execute system commands, nice. Now we just need a reverse shell. We set a listener to 4445
on nc -lnvp 4445
and use my favorite reverse shell via busybox.
After we have set the payload and reloaded the dashboard,...
...we get a connection, we are www-data
and can read the second falg at /var/www/html/flags/.txt
.