不用cookie 一个盲打储存XSS对“某btc平台”攻城略地

2018-04-10 11:09:22 75 13286 6


首先说一下,其实“这类”文章土司论坛是有的,只是大家很少去翻。今天简单的分享一下。

前一阵一直在玩比特币,但是无奈又TM站在了人生的最高点,别问我为什么用“又”,WCTMD投了1500最后剩几十元。然后这次的目标是朋友推荐的一个站点,据说送币子,注册就送。。。

这篇文章主要讲的是思路,还有XSS平台的使用。。。没有思路你只能止步不前。某日对某站点。然后我就随手测试一下放了一段XSS代码,然后没过多久发现,我的邮箱居然收到了XSS平台发来的信息,然后登录XSS平台一看,发现居然有收货,很是意外,这就是传说中的盲打XSS,然后简单的看了一下,如下图。



既然有cookie,还有后台地址,那么尝试登录一下吧。结果发现。登录不进去,跳转到了登录界面。



经过查看,估测应该是打到的cookie有问题,对方可能设置了httponly,这样对方网站关键的cookie我是获取不到的,那就无法登录对方的后台。不过这里看到一个好消息,那就是对方网站的后台对外开放,在互联网上居然可以访问。那就妥妥的了。咱们继续看刚才XSS平台收到的信息,这里已经收到对方中招的后台URL地址了。

后台地址:https://xxxx.com/admin/userCert/index

还有这个地址的html源码,如下图:


这里要注意,很多时候获取到的对方的html源码都是“相对地址”,需要你自己补全为“绝对地址”,上图中红色的就是相对地址,没有网站的域名地址,绿色圈中的就是绝对地址。把源码中的所有连接地址都补全像图中绿色圈中的样子。

然后本地打开(因为对方的后台对外开放,互联网可访问了),所以补全后,我们本地打开。如下图:

这里可以看到,他人实名信息,这里有身份证正反面,还有手持照片。为了好奇,我点击了一下其中一个手持照片。地址如下:


https://xxxx.com/admin/userCert/getImageFile?fileId=M00/00/06/rB_4MxxxxxBBBG87xTGg.bbbb


当然我打开这个地址的时候,URL直接跳转到了登录界面。没办法,毕竟没登录。没办法登录,那么刚才一直什么补全html中连接为何?这里先不做解答,卖个关子,先说眼前的问题,这个图片看不了怎么办?就在我在前台,也就是用户界面操作各个功能的时候发现。



我们看一下咱们上传的这个图片地址。
https://xxxx.com/portal/getImageFile?fileId=M00/00/06/rB_4MVxxxxxxAMtVc.aaaa


然后这里我们在返回看一下后台的读取图片的地址。
https://xxxx.com/admin/userCert/getImageFile?fileId=M00/00/06/rB_4MxxxxxBBBG87xTGg.bbbb


相信聪明的你是不是已经思路打开了呢?


如果我们吧后台URL地址的红色的那个值替换到上面个人中心那里,是不是就可以显示了呢?
https://xxxx.com/portal/getImageFile?fileId=M00/00/06/rB_4MxxxxxBBBG87xTGg.bbbb
我访问了一下这个地址。然后如下图:

这里其实想说明的是思路很重要。要利用一切可以利用的。当然了,获取他人信息不是咱们的主要目的,咱们要直捣黄龙,说好的。


------------------小插曲暂时停一下,继续刚才那个补全html开始------------------


这里要重点说一下,为什么要补全html呢,其实不光是为了看样式,它的重点在于让你通过html源码能对 对方网站结构有一个大概的梳理。这里我给出重点的html源码中的内容。


<script>
    $(document).ready(function () {
                $("#table_list").bootstrapTable({
                    method: "POST",
                    contentType: "application/x-www-form-urlencoded",
                    url: "/admin/userCertx/list",
                    striped: true,
                    pagination: true,
                    pageSize: 10,
                    pageNumber: 1,
                    pageList: [5, 10, 15, 20, 25],
                    search: false,
                    detailView:false,
                    sidePagination: "server",
                    queryParamsType: "undefined",
                    responseHandler: function(res) {
                        return {
                            "rows": res.list,
                            "total": res.total
                        };
                    },
                    columns: [{
                        title: "ID",
                        field: "id",
                        sortable: true
                    },{
                        title: "用户名",
                        field: "username"
                    },{
                        title: "全名",
                        field: "firstName",
                        formatter: function(value, row, index) {
                        return row.firstName + " " + row.lastName;
                }
                    },{
                title: "证件号码",
                field: "idNo"
            },{
                        title: "身份证正面照",
                        field: "idCardFront",
                formatter: function(value, row, index) {
                    if(!value){
                        return "无";
                    }
                    return '<a target="_blank" href="getImageFile?fileId=' + value + '">查看</a>';
                }
                    },{
                title: "身份证反面照",
                field: "idCardBack",
                formatter: function(value, row, index) {
                    if(!value){
                        return "无";
                    }
                    return '<a target="_blank" href="getImageFile?fileId=' + value + '">查看</a>';
                }
            },{
                title: "身份证正面照",
                field: "idCardInhand",
                formatter: function(value, row, index) {
                    if(!value){
                        return "无";
                                        }
                    return '<a target="_blank" href="getImageFile?fileId=' + value + '">查看</a>';
                }
            },{
                title: "状态",
                field: "verifiedStatus"
            },{
                        title: "操作",
                        field: "verifiedStatus",
                formatter: function (value, row, index) {
                            if(value === 'REJECTED' || value === 'PASSED') {
                                if(row.operReason) {
                            return '<button class="btn btn-primary btn-xs" type="button"><i class="fa fa-edit"></i> 查看备注</button>  ';
                        }
                                return "";
                    }
                            if(value !== 'SUBMITTED') {
                                return "";
                                        }
                    var operateHtml = '<button class="btn btn-primary btn-xs" type="button"><i class="fa fa-edit"></i> 通过</button>  ';
                    operateHtml = operateHtml + '<button class="btn btn-danger btn-xs" type="button"><i class="fa fa-remove"></i> 拒绝</button>  ';
                    return operateHtml;
                }
                    }]
                });
    });

    function query() {
        var username=$("#username").val();
        var status=$("#status").val();
        $('#table_list').bootstrapTable("refresh",{url:"/admin/userCertx/list?username=" + username + "&status=" + status}
        );
    }

    function pass_reject(id, passed){
        if(!passed) {
            layer.prompt({title: '"请输入审核未通过原因"', formType: 2}, function(text, index){
                layer.close(index);
                $.ajax({
                    type: "POST",
                    dataType: "text",
                    url: "/admin/userCertx/passReject",
                    data: {
                        userCertId: id,
                        passed: passed,
                        operReason: text
                    },
                    success: function(msg){
                        layer.msg("操作成功", {time: 2000},function(){
                            $('#table_list').bootstrapTable("refresh");
                            layer.close(index);
                        });
                    }
                });
            });
        } else {
            layer.confirm("是否确定?", function () {
                $.ajax({
                    type: "POST",
                    dataType: "text",
                    url: "/admin/userCertx/passReject",
                    data: {
                        userCertId: id,
                        passed: passed,
                        operReason: null
                    },
                    success: function(msg){
                        layer.msg("操作成功", {time: 2000},function(){
                            $('#table_list').bootstrapTable("refresh");
                            layer.close(index);
                        });
                    }
                });
            });
        }
    }
</script>



整个HTML源码中的内容,也就这一块。通过分析这段HTML代码,可以大致分析出网站如下结构。这段是HTML代码里面的JS代码,网站的大部分功能都是ajax操作的。

网站后台首页地址:
https://xxxx.com/admin/ 或者 https://xxxx.com/admin/index

网站后台会员列表页(经过测试,这个页面确实是正常访问的网站会有列表页,但是这个页面会通过ajax调用其他页面来显示数据):
https://xxxx.com/admin/userCertx/

网站后台会员列表数据页面:
https://xxxx.com/admin/userCertx/list?pageSize=100&pageNumber=1
(通过上面的JS分析,需要携带两个参数pageSize为显示多少条信息,pageNumber显示第几页)。
这个URL地址为通过上面代码分析自己组合的地址,这里参数为什么是100还有1,后续讲。

网站后台会员状态列表(例如只查看某用户名的会员,例如只看是否通过审核的会员):
https://xxxx.com/admin/userCertx/list?username=" + username + "&status=" + status
username 疑为会员名称
status 疑为会员状态

针对网站后台会员功能操作(审核通过功能):
https://xxxx.com/admin/userCertx/passReject
应该向此URL提交3个参数:
userCertId: id 应该是会员ID
passed: passed 应该审核状态,REJECTED代表未通过。passed代表通过。
operReason: text 应该是随意值,指备注。
还有几个可能无关紧要,这里就不做分析了。既然分析出来这么多URL结构及作用了。咱们就可以写JS代码,通过CSRF配合来做操作啦。

好,废话不多说,注意,这里最好修改对方中招的项目。这里有个小技巧。如图。




首先进入XSS平台,然后使用【指定多URL页面源码读取】这个插件。我整理了,我现在需要探测对方后台首页的代码,这样更利于分析对方网站结构。然后还有会员列表,这样我能获得对方的数据。



那就第一个filename填入如下地址:

https://xxxx.com/admin/

那就第二个filename1填入如下地址:

https://xxxx.com/admin/userCertx/

那就第三个filename2填入如下地址(如果URL没那么多,可以为空不填写):

https://xxxx.com/admin/userCertx/list?pageSize=100&pageNumber=1

更改完之后,坐等管理员继续中招。结果没等几分钟,管理员果真又中招了。XSS平台来信息了。如图:




这里我只举例首页(https://xxxx.com/admin/)html源代码组合后的样式结果吧如下图(动图):



相信这么看之后,对整个网站的整体的结构已经相当之一目了然了吧。

https://xxxx.com/admin/userCertx/

https://xxxx.com/admin/userCertx/list?pageSize=100&pageNumber=1

也很有收货,上面的确实如我所想,html源码里面没什么内容,只是一个JS代码,能看到一些简单的架构。

而下面的URL地址,直接就返回100条用户的数据,JSON格式的,我们只需要格式化一下。然后分分钟到手平台用户的数据。各种高清无码身份㊣等信息。




到此网站结构已经分析的很明确了。

然后再次通过更改XSS平台的项目直接获取https://xxxx.com/admin/user/index 后台管理员地址。

通过分析直接获取到了后台管理员的帐号和密码,无奈无法解开加密后的密码。




不过不要灰心,因为刚才上面获取到了https://xxxx.com/admin/user/index 管理员后台的源码,所以通过源码分析出,添加后台管理员的代码。然后写一段JS脚本,如下:



最后等了半天,晚上21点管理员又登录了。结果中招确实添加了一个我指定的管理员帐号。但是我发现最终还是登录不进去。如图:



不过不用担心,因为对后台的功能基本已经了如指掌,所以我留了一个后门。没进去怎么留的后门?当然是通过CSRF + XSS留的,以后只要管理员上线浏览到了后门的页面地址,那么他绝笔会中招。。。中招就可以继续玩他了。
现在,他整个网站基本可以掌控。只不过没办法进后台,所以还需要管理员浏览中招的页面才可以。

没过多久可能因为我分析对方网站代码分析某个地方失误,导致对方运营人员进不去后台了,然后技术通过数据库查看代码看到了我留的后门。如图,里面有我创建的管理员帐号:admis 还有我更改的其他管理员的信息留的后门。



其实到这里就结束了,整个网站后台的功能全部都分析的明明白白了【因为这个平台可能才创立没多久,所以后台功能暂时没那么强大,没办法XXOO】。不过这里我想说的是,我是好人,所以我并没有动人家的数据,而且也没有做恶意破坏,做人还是有点原则的好(你信么? )。  好了,到这里暂时结束了,不说了,警察叔叔来找我说请我吃饭了。


自评TCV=2



文章来源(自己博客首发,其他任何地方没发过,最近才公开的文章): http://coao.co/3035.html

关于作者

Shrimp56篇文章674篇回复

互相学习技术而已。
请有空多访问一下本人的个人博客:
https://woj.app/

评论75次

要评论?请先  登录  或  注册