昨天朋友发现了一个xss,审核人员要求提出造成这个洞的原因,所以需要去找这个洞的生成函数,然后按照正常流程:先找页面中生成的触发xss的节点-》再通过该节点的特征(比如类名,属性等)来全局搜索生成这些特征的特定生成函数。但是!发现这个过程第一步就没有——也就是说,页面中并没有节点中存在事件为onerror=alert(1)的节点。所以这里我猜测,可能是临时或者类似eval的生成函数,所以要找的话就比较麻烦。
想了一下——既然触发了alert函数,那我直接hook alert这个函数不就好了?说做就做
首先了解一下在js下的hook方式:
let myalert = window.alert // 将alert这个函数-》交给myalert,也就是说这里myalert=alert
window.alert = function(fx){myalert(fx)}//调用alert的时候其实就是调用了我们的hook函数..
这样做是不是很意义不明?其实并不是..因为alert是native函数(我认为应该调试不了),但是通过这种window.alert = function(fx){myalert(fx)}alert不就变成了可调试的函数?
接着了解一下油猴脚本:
简单介绍,它就是一个浏览器插件,既然是浏览器插件,那么他的运行等级可以很快,但是油猴脚本的运行默认是在dom加载完后添加上去的,比如:
设置一个百度脚本
输出1
因为我们是要hook,所以要求肯定最早加载,那么就要引出我们油猴的加载顺序标签:
@run-at定义了脚本可以运行的最初时刻。这意味着,通过@require引入的脚本如果在获取时耗费过多时间,那么脚本可能在网页加载后执行。无论如何,在给定注入时刻后且脚本注入成功的情况下,发生的所有DOMNodeInserted和DOMContentLoaded事件都会传递到用户脚本。
run-at document-start 脚本将尽可能快地注入。
run-at document-body 如果body元素存在,则脚本将被注入。
run-at document-end 该脚本将在发生DOMContentLoaded事件时或之后注入。
run-at document-idle 在发生DOMContentLoaded事件后注入脚本(如果不设定的话,此加载策略为默认)。
run-at context-menu 如果在浏览器上下文菜单(仅限桌面Chrome浏览器)中点击该脚本,则会注入该脚本。注意:如果使用此值,则将忽略所有@include和@exclude语句,但这可能会在将来更改。
所以也就是说我们如果我们想让脚本比页面更早被加载出来的话,那么我们要在脚本的前面标出run-at document-start如下:
添加@run-at document-start
比之前更快打印出了1
那么接下来再使用之前我讨论过的hook手段来进行hook,但是可能需要不一样一点:我们拿console来做例子(为了脱敏(我总不可能把人家那个漏洞摆到面前然后调试吧),这只是一个教学的文章)。
接着hook调试-》找出关键的触发函数。这里你可能纳闷了,油猴脚本怎么调试?source->油猴
接着刷新页面,让js重新执行一次。
然后我们跟随我们的函数栈,就可以找到真实调用的函数了(就可以找到标题描述的一类生成函数了)。

到此就结束了。感谢昨天朋友的经历让我突然想到还能这么玩...