写这篇文章的原因是在某次HVV期间遇到了个ASP.NET站点搭配使用了Microsoft Sql Server,于是想总结一下SQLI在SQLServer中的一些姿势
权限判断
Tips:
判断能否堆叠
判断是否能堆叠注入可以使用下面语句作为堆叠的语句,人为设置响应延迟与正常响应时间进行对比从而判断第二个语句是否被执行
1 | WAITFOR DELAY '00:00:05'; -- 执行暂停 5 秒钟 |
- 若响应时间大于设置的延迟说明第二个语句被执行
- 若存在堆叠,还可以根据延迟的时间判断传入的这个参数被多少句SQL语句中使用
判断站库分离
站库分离:网站程序和数据库分别放在了不同的服务器上
判断站库分离可以通过判断客户端主机名和服务端主机名是否一致进而判断是否为站库分离
获取客户端主机名
1 | SELECT host_name(); |
获取服务端主机名
1 | SELECT @@servername; |
若客户端主机名与服务端主机名一致则站库不分离,不一致则站库分离
在进行判断时可以在注入点后添加条件,若条件为真则站库不分离
1 | AND host_name()=@@servername |
查找站点路径
可以通过IIS的配置文件applicationHost.config
C:\Windows\System32\inetsrv\config\applicationHost.config
处理中文
SQL Server中ASCII ()
函数进行了说明👉ASCII (Transact-SQL) - SQL Server | Microsoft Learn
ASCII 是一个 7 位字符集。 扩展的 ASCII(或称 High ASCII)是不由
ASCII
函数处理的 8 位字符集,ASCII
函数能够读取前 7 位的流,而不包括剩余的 1 位。
UNICODE
函数支持返回正确的字符码位,可以通过使用它来找到字符æ
的正确码位。并可通过NCHAR
函数恢复为字符
但值得注意的是在 SQL Server 中,字符串字面量默认使用数据库的默认字符集进行处理,在遇到数据库使用字符集中不存在字符时,无论使用 UNICODE
函数还是转化为16进制依旧会转化成非预期结果
并且一旦写入数据库,即使使用 如:CAST(MyColumn AS nvarchar(MAX))
将 列 MyColumn
显式地转换为 nvarchar
类型也无法恢复
[!TIP]
若需要在不改变数据库的默认字符集情况下,能使用
UNICODE
函数或转16进制时正确转化,建议大家这里根据情况将需要读的列设置为nvarchar
类型
例如:在字符集Chinese_PRC_CI_AS下
1 | SELECT UNICODE('æ') |
结果为63而非230
在设置列为nvarchar
类型的前提下,对于中文的处理可以使用以下方式
将中文使用转化为
UNICODE
函数转化,再通过NCHAR
函数恢复为中文例如:
1
SELECT UNICODE(SUBSTRING((SELECT entry_value FROM daily_back WHERE id = 16), 1, 1))
将中文转化为16进制,再通过CyberChef的Recipe为
From Hex
->Decode text
编码方式选择为UTF-16LE
恢复为中文例如:
1
SELECT CONVERT(varchar(max), CONVERT(varbinary(max), (SELECT entry_value FROM daily_back WHERE id = 16)), 2);
由于中文对应的UNICODE会很大很大,这里更推荐使用16进制进行。不嫌麻烦也可以把UNICODE转化为十六进制