XSS易容术---bypass之编码混淆篇+辅助脚本编写

一、前言
本文原创作者:vk,本文属i春秋原创奖励计划,未经许可禁止转载!
很多人对于XSS的了解不深。
一提起来就是:“哦,弹窗的”、”哦,偷cookie的。”
骚年,你根本不知道什么是力量。虽然我也不知道,哈哈。
好了,不瞎扯了,进入今天的主题:
XSS易容术---bypass之编码混淆

二、正文
1、总括

很多时候,我们的一些关键字被过滤。
直接闭合前面payload,插入测试语句<script>alert(/xss/)</script>,
是弹不出窗的。
原因有很多,过滤方式也有很多,所以绕过的姿势自然也不少。
但并不是什么情况都能绕过的,例如:

<div>

  <?php echo htmlspecialchars($_POST['xss']); ?>

</div>


接收过来的数据,被php函数htmlspecialchars处理
这个函数是转实体,转实体后,你再怎么折腾,也绕过不了。

2、xss常用的编码
第一个,html实体编码,例如:&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x29;
第二个,进制类,例如:\x61\x6c\x65\x72\x74\x60\x78\x73\x73\x60,某些时候,也有不带x,例如:\5c\6a
第三个,Unicode,例如:\u0061\u006c\u0065\u0072\u0074\u0060\u4e2d\u6587\u4e5f\u53ef\u4ee5\u0060
第四个,纯转义,例如:\'   \"   \<   \> ,这样的在特殊字符前加\进行转义。
先变个魔术,猜猜这样的代码能不能成功弹窗。

<img src=# onerror=eval("\x61\x6c\x65\x72\x74\x28\x2fxss/)")>


180511migibmx856zgi8jd.png
|
|不
|准
|偷
|看
|
|
|
|
好吧,可以弹窗如图:
180345eqfmqqjxq4qfvmz5.png
那这样呢:

<img src="javascript:alert(1)">


|
|
|
|不
|准
|偷
|看
|
|
|
|
|
|
|
是不行的哦!你可以自己试试
190138soud3nu3plxnxbpr.png
是不是颠覆了你的xss观。
什么?js伪协议不能用了?
哈哈,其中奥妙无穷,跟我一起来探索吧。

3、编码的正确使用姿势。
3.1    总论

我相信很多人都知道,是有那么几个编码是运用在xss的bypass里的(bypass就是绕过)
但是具体怎么用,什么时候用,在哪里用,并不清楚。
这可是有讲究的,瞎用的话浏览器可不帮你解析。
除非你有这个工具:
180837whjh90j10johih9o.png

它会告诉你什么时候,用什么编码,辅助你学习。
什么?这个工具在哪?
额,没错,这是笔者自己写的,在后面会放出源码~~
好了废话不多说,总结如下:
3.2    编码运用总结
html标签中:

  • html中当然会支持html实体编码,例如&#61,也有&lt;
  • 支持十六进制,但是要以&#x开头,其中x大写小写无所谓。
  • 支持十进制,要以&#开头,注意,没有x哦。
  • 支持数字部分高位补充0,例如&#00000000061,&#61这两是一样的。
  • 可能你已经发现了,后缀有没有;  都无所谓
     

javascript中:

  • eval函数里,支持十六进制,但是要以 \x 开头,x只能小写!必须两位,例如:\x5c
  • eval函数里,支持八进制,但是要以 \ 开头。必须两位,例如:\134
  • eval函数里,还支持\u前缀的unicode,本质是:16进制的ascii码。必须是四位,例如:\u005c

注意了,这个可和html实体编码不一样,对格式比较严格,不能随便在数字部分补充0。

聪明的童鞋可能已经发现了:
为什么第一个说的是html标签,第二个没说script标签呢?
以为js代码不一定要在script标签中啊。
比如这个:

<img src=# onerror=alert(/xss/)>


这就是在on事件中。
这样会出现什么有意思的事情呢?
细心的同学也许发现了,没错,是混合双打:
183853aph68yj8orlrp6yj.png
img是html标签,里面用html编码是没问题的,而on事件里面可以直接解析js代码,
于是我使用eval函数,然后用js支持的编码替换内容,一样可以成功弹窗。
复杂使用起来就如一开始那副图那样,用了多种编码。

也可以这样:
184941jclhqhhkun1ppumd.png
书上还有说css里支持\开头的十六进制,但是笔者实验没有成功。Orz(ps:书比较旧,现在浏览器不支持很正常)
4、献上辅助脚本源码(html+js)
 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

<head>

    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">

    <title>xss编码转换器</title>

    <script>

    //提示框

        function tips(param){

            str=document.getElementById('tip');

            switch(param){

                case "&#":

                    str.innerHTML="提示:这个前缀只在html标签里才有效哦";

                break;

 

                case "bfstrin":

                    str.innerHTML="提示:对对,就是这里,输入需要编码的字符吧,例如:alert()";

                break;

 

                case "bfstrout":

                    str.innerHTML="提示:写好要转码的字符了吧,选择前缀后缀,以及位数哦。";

                break;

 

                case "\\x":

                    str.innerHTML="提示:这个前缀在eval里面有效哦,注意:必须选择16进制。";

                break;

 

                case "\\u":

                    str.innerHTML="提示:这个前缀在eval里面有效哦,注意:必须选择16进制,只能是四位(自动改好)。";

                break;

 

                case "\\":

                    str.innerHTML="提示:这个在css里面有效哦,但是只要ie6以前的浏览器才支持,Orz。";

                break;

 

                case "%":

                    str.innerHTML="提示:这个放在url里有效哦,%bf%27可是能干掉GBK的。";

                break;

 

                case " ":

                    str.innerHTML="提示:这个。。你竟然不要前缀了。";

                break;               

 

                case "af":

                    str.innerHTML="提示:这个只能配合&#用,而且可有可无。";

                break;

 

                case "jz":

                    str.innerHTML="提示:想换什么进制,eval只支持8进制和16进制,html标签支持10进制和16进制。";

                break;               

 

                case "num":

                    str.innerHTML="提示:html实体编码(&#)里面,ascii码前面可以任意插0,别的都不行。";

                break;               

 

                case "go":

                    str.innerHTML="提示:期待很久了吧,那啥,那个,失败了也和我没关系。。";

                break;               

 

                case "no":

                    str.innerHTML="提示:别,千万别,别按这个按钮,地球会毁灭。";

                break;

            }

        }

 

    //获取参数

        function getparam(){

            var bf=document.getElementById('bf').value;

            var af=document.getElementById('af').value;

            var jz=document.getElementById('jz').value;

            var num=document.getElementById('num').value;

            var param=[];

            param[0]=bf;

            param[1]=af;

            param[2]=jz;

            param[3]=num;

            return param;   

        }

 

    //取数,转ascii

        function enasc(){

            enstr=document.getElementById('bfstr').value;

            var bfstrarr=new Array();

            for(i=0;i<enstr.length;i++){

                tmpstr=enstr.substr(i,1);

                bfstrarr[i]=tmpstr.charCodeAt();

            }

            return bfstrarr;

        }

 

    //编码主函数

        function enxsscode(){

            var param=getparam();

            var bfstrarr=enasc();

            var destr="";

            for(i=0;i<bfstrarr.length;i++){

                bfstrarr[i]=bfstrarr[i].toString(param[2]);   //换进制

                var bu=0;

                if(param[0]=="\\u")

                    bu=4-String(bfstrarr[i]).length+1;

                else

                    bu=param[3]-String(bfstrarr[i]).length+1;

                 

                if(param[2]==16 && param[0]=="&#")

                    destr+=param[0]+"x"+new Array(bu).join('0')+""+bfstrarr[i]+""+param[1];

                else if(param[2]==16 && param[0]=="\\u"){

                    destr+=param[0]+new Array(bu).join('0')+""+bfstrarr[i]+""+param[1];

                }else{   

                    destr+=param[0]+new Array(bu).join('0')+""+bfstrarr[i]+""+param[1];

                }           

            var afstr=document.getElementById('afstr');

            afstr.value=destr;

            }

        }

    </script>

</head>

<style>

    #bg{

        text-align: center;

        margin:0 auto;

        border:2px ridge red;

        width:1200px;

        height:700px;

    }

    #header{

        background: #2f2f2f;

        border-bottom: 7px solid #a1cc33;

        height:60px;

        padding-top: 10px;

    }

    #left{

        float: left;

        border: 2px solid black;

        width: 500px;

        height: 500px;

        margin-left: 50px;

        margin-top: 20px;

    }

    #right{

        float: right;

        border: 2px solid black;

        width: 500px;

        height: 500px;

        margin-right: 50px;

        margin-top: 20px;

    }

    #mid{

        float: left;

        border: 2px solid green;

        width: 70px;

        height: 500px;

        margin-left: 10px;

        margin-top: 20px;       

    }

    #tip{

         

        margin-top: 15px;

        margin-bottom: 0px;

        height: 20px;

        text-align: center;

        color: red;

    }

    .param{

        margin-left: 2px;

        width: 55px;

    }

</style>

<body>

    <div id="bg">

        <div id="header">

            <h1 style="display:inline;">XSS编码转换器</h1>-made by vk

        </div>

 

        <!--主体 -->

        <form action="" method="post">

        <div id="tip">

            提示:左边区域输入待转码的字符

        </div>

        <div id="left">

            <textarea name="bfstr" id="bfstr" cols="30" rows="10"

            style="resize:none; width:490px; height:490px; " ></textarea>

        </div>

        <div id="mid">

                <p style="padding-top: 10px; margin: 0px;">前缀:<br></p>

                <select name="bf" id="bf" class="param">

                    <option value="&#">&#</option>

                    <option value="\u">\u</option>

                    <option value="\x">\x</option>

                    <option value="\">\</option>

                    <option value="%">%</option>

                    <option value=" "> </option>

                </select>

                <br><br>

                后缀:

                <input type="text" id="af" name="af" value=";" class="param" />

                <br><br>

                进制:

                <select name="jz" id="jz" class="param">

                    <option value="8">8</option>

                    <option value="10">10</option>

                    <option value="16">16</option>

                </select>

                <br><br>

                位数:

                <input type="text" id="num" name="num" value="4" class="param" />

                <br><br>

                <input type="button" id="" name="" value="编码-->" class="param" />

                <br><br>

                <input type="button" id="" name="" value="<--解码" class="param"style="padding-left: 2px"/>

                <br><br>

                <input type="button" id="" name="" value="jsfuck" class="param" />

        </div>

        <div id="right">

            <textarea name="afstr" id="afstr" cols="30" rows="10" style="resize:none; width:490px; height:490px; " ></textarea>

        </div>

        </form>

    </div>

</body>

</html>


4、结束语
切记搞清楚,什么编码在什么位置能被浏览器正常解析,在进行实战的时候,一定要现在本地测试一下,然后再把payload扔过去。
不然出错了,你想破脑袋也很难排错。

更多安全技术、精品好文、白帽黑客大佬尽在:http://bbs.ichunqiu.com/portal.php

转载于:https://my.oschina.net/ichunqiu/blog/819257

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值