有关XSS编码问题的个人总结

本文总结了XSS攻击中的编码利用,包括URL编码、HTML实体编码、JS编码和CSS编码。并详细解释了浏览器的HTML解析和解码顺序,通过示例展示了如何利用解码顺序来构造有效payload。同时,文章探讨了编码的注意事项,如避免编码特定符号,以及在何处插入payload以达到反射型XSS的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

XSS也太太太难了,主要也是因为自己没花时间集中。

文章脉络:根据我粗浅的理解,从开始学习XSS到现在,从一开始的见框就插到现在去学构造、编码,首先需要的是能看懂一些payload,然后再去深入理解。所以,文章首先会介绍一些常见的可供利用的编码,然后再理解浏览器如何解析HTML文档,最后再总结一下。应该有很多不正确的地方,希望看到的朋友帮我指正以下,带我挖洞,冲。QQ:2309896923

写的这些内容都是借鉴总结了许多大神的文章,对大神提及的一些注意点进行总结归纳。

一、一般可利用的编码

1.URL编码
格式:%十六进制数

字符编码
=%3D
a%61
我太难了%E6%88%91%E5%A4%AA%E9%9A%BE%E4%BA%86

记住常用符号、字母的 ASCII 码,能熟练转换 10 -16 进制即可。中文的URL编码略有不同,因为用的地方没有,也就不详写了

如何利用:浏览器的 URL 地址栏,反射型 XSS,可以将特殊字符进行 URL 编码,可以尝试多次编码试一试;POST过去的数据,存储型 XSS,跟反射型的一样。最后提一点:因为一般网站处理数据的时候最开始解码的一般是 URL 解码,所以可以在用其他编码构造完成 payload 后,最后再进行 URL 编码,由此可见,可以根据解码顺序,灵活得进行编码,最先解码的,就最后编码,懂我什么意思吧,我也不太懂我到底有没有说懂

2.HTML实体编码
格式:&#十进制/十六进制; (一般是用十进制)十六进制的时候为 &#x十六进制数

字符实体名称实体编码
<&lt;&#60;
:&colon;&#58;
换行&NewLine;&#13;
空格&nbsp;&#32;

对照ASCII码表基本就可以轻松转换了

HTML实体编码对照表参考地址:https://www.w3school.com.cn/html/html_entities.asp

如何利用:注意不要编码 标签的 <> 、属性名、以及赋值号(等号=,冒号:)就可以了

3.JS编码
格式:①--unicode:\u十六进制 ②--\八进制、\十六进制

字符\u\八进制\十六进制
a\u0061\141\x61
b\u0062\142\x62
c\u0063\143\x63

如何利用:一般使用 jsUnicode编码比较多,其他的两种还在研究,望得到高人指点

4.CSS编码
格式:\1~6位十六进制数
后边就不能直接紧跟数字或字母,否则会被当成转义里的内容处理,所以CSS 选择了空格作为终止标识,在解码的时候,再将空格去除。

如何利用:在使用 style 属性或标签的时候使用,或者也可以在引入外部 CSS 文件的时候,将引入的文件内容进行编码

二、弄清楚浏览器解码顺序

浏览器解析顺序:

示例HTML代码:
<a href="j&#x61vascript: //%0&#x61;&#x00025;61l\u0065rt(1)">click me</a>

解释:
1.首先浏览器接收到HTML代码,会先开始进行HTML解析,构造DOM树,粗略的讲就是识别 <> 这些标签,赋予其特殊含义,区别于纯文本内容。
注意此时并不会做任何解码操作,所以构造 &#lt;img src&#x3d;"javascript:al\u0065rt(1)">是不会弹窗的,因为没有识别到标签,它相当于就是一个纯文本,具体来说就是:标签属性名和赋值符号不能编码,但是标签属性的值可以编码

2.DOM树构造完成,开始HTML解码,变成了<a href="javascript://%0a%61l\u0065rt(1);">click me</a>

3.唉,碰到链接类属性 href 了,尽管发现了是javascript伪协议,浏览器也会直接 URL 解码一次,然后就变成了 <a href="javascript://al\u0065rt(1)">click me</a>

4.解码后,因为是 javascript 伪协议,所以 JS 解析器便开始工作了,解析成了 <a href="javascript://alert(1)">click me</a>,注意在识别协议的时候,协议是不能被任何编码的,除非在识别之前已经被解码了,不然的话是不能被识别出来的的,比如说 href="j%61vascript:alert(1)" ,冒号被编码也不行,浏览器虽说会 URL 解码,但是并不会解码之后再识别一次这是什么协议,于是不管是 http 协议还是 javascript 伪协议也好,此时都发挥不了作用而且,此时 href="j%61vascript:alert(1)" 中的冒号括号也不能被 js 编码,否则不会弹窗

5.然后就顺利弹窗了

6.当然,并不是所有时候都是这种解码顺序,要依据具体情况而定。

7.演示一下如何自己进行编码:
可以看到上述例子浏览器解码顺序为 HTML实体解码 -> URL解码 -> JSUnicode解码 <-----> 于是便反过来编码 JSUnicode解码 -> URL解码 -> HTML实体解码
假设要编码的内容:<img/src/onerror=alert(1)>,可以先思考一下改如何编码,再往下看

首先JSUnicode编码 : <img/src/onerror=\u0061\u006c\u0065\u0072\u0074(1)>,加不加双引号包裹onerror后面的内容无所谓,加也好,不加也好,最好不加,因为双引号被过滤了的话,会更麻烦,依据前文所述,此处的注意点有:不能编码括号 (),还有一点很奇怪,弹窗提示的 1 字符也不能被编码,否则不会弹,除非加引号包裹起来。
其次HTML编码 : <img/src/onerror=\u0061&#x5C;&#x75;006c\u0065\u0072\u0074&#x28;1)>此处的注意点有:不能编码标签的 <>、属性、等号=
最后URL编码 : %3Cimg/src/onerror%3D%5Cu0061%26%23x5C%3B%26%23x75%3B006c%5Cu0065%5Cu0072%5Cu0074%26%23x28%3B1%29%3E

最后一个问题:这句payload应该插在哪? 一般是反射型的XSS直接便可以见到效果,
有php环境的可以试一下:a.php 内容为 <?php echo $_GET["a"]; ?>,然后用浏览器打开这个文件,后面接 ?a=%3Cimg/src/onerror%3D%5Cu0061%26%23x5C%3B%26%23x75%3B006c%5Cu0065%5Cu0072%5Cu0074%26%23x28%3B1%29%3E,即可弹窗

如图:

注意点总结:

1.转义编码应当只出现在标示符部分,不能用于对语法有真正影响的符号,也就是括号,或者是引号、等号、冒号

2.浏览器是不会在html标签里解析js中的那些编码的!所以我们在οnerrοr=后面放js中的八进制、十六进制编码(jsUnicode编码除外)是不会解析 你放进去是什么 解析就是什么!而另一方面,如果想用这种方式来替换掉圆括号,或者引号,会判定为失败。同时,主要注意的方式,上边这种直接在字符串外进行专一的方式,只有Unicode 转义方式被支持,其他转义方式则不行。其实,这样的策略是正确的,因为对于JavaScript,转义编码应当只出现在标示符部分,不能用于对语法有真正影响的符号,也就是括号,或者是引号。其实,这样的处理方法,反而是比CSS 更加合理的。

3.HTML解析器在建立文档树的时候会针对节点内的Entity编码(即实体编码)解码后传输。

4.使用DOM 操作,对DOM Tree 造成了改变,会调用到 HTML 解析器重新对其解析,意思就是,用 DOM 操作创建了节点标签什么的,会重新调用 HTML 解析

5.在一个页面中,可以触发 JS 解析器的方式有这么几种:
直接嵌入< script> 代码块。
通过< script sr=… > 加载代码。
各种HTML CSS 参数支持JavaScript:URL 触发调用。
CSS expression(…) 语法和某些浏览器的XBL 绑定。
事件处理器(Event handlers),比如 onload, onerror, onclick等等。
定时器,Timer(setTimeout, setInterval)
eval(…) 调用。
可以想一下这个 <script>\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0031\u0029</script>,为什么这个不弹窗呢?????????????????
不清楚可以看一下参考文章的第一篇!!

另外一些例子:
以下两个表示相同:
<img src="http://www.example.com">
<img src="ht&#x74;p&#x3a;//www.example.com">
因为在识别协议之前,已经HTML解码了,所以并不会出现识别协议失败

下面两个例子代码不会执行,因为,编码的是标签本身的结构而非节点内的内容:(这一点非常重要)
<img src&#x3d;"http://www.example.com">
<img s&#x72;c="http://www.example.com">

 

 

更多干货 请点击这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值