声明
本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请在CSDN 私信 联系作者立即删除!
进到网页想要分析,打开开发者工具,直接被debugger了
过debugger
方式一
打开开发者工具(f12),之后看到一个debugger,直接找到debugger处,右键,一律不在此处暂停,第一个debugger,过了之后,会来到第二个debugger,在右键,一律不在此处暂停。就过掉了
方式二
点击右侧小箭头,关闭断掉就可以过掉debugge了
方式三
- 本地替换
- fiddler替换
- hook debugger
- ................
分析1
- 过掉debugger后,前往应用程序,找到存储,点击清除网站数据,(记得勾选 包括第三方cookie)
- 重新刷新网页,分析请求
第一次请求new_house.html,返回响应的cookie
第二次请求new_house.html
第三次请求为我们需要请求的数据接口
通过以上流程就可以请求到数据接口的数据
分析2
定位cookie入口
进来的时候可以看到加载的js是一个虚拟js打开,要定位cookie位置可以hook的方式
前往应用清空本地网站数据,然后通过控制台注入或油猴插件注入(推荐油猴)
/*
* hook-cookies
* */
(function () {
// 先将当前要cookie的cookie属性保存到一个临时变量中
var cookie_cache = document.cookie
// 通过defineProperty方法对cookie属性进行重写
Object.defineProperty(document,'cookie',{
get:function (){
console.log("get cookie: ",cookie_cache)
return cookie_cache
},
// 当设置cookie时触发set函数,然后进行debugger
set:function (val) {
console.log("set cookie: ",val)
debugger;
var cookie = val.split(";")[0]
var ncookie = cookie.split("=")
var flag = false
var cache = cookie_cache.split(';')
cache = cache.map(function (a) {
if(a.split("=")[0] === ncookie[0]){
flag = true
return cookie
}
return a
})
cookie_cache = cache.join(";")
if(!flag){
cookie_cache+=cookie+";"
}
this._value = val;
return cookie_cache
}
})
})()
通过以上脚本进行hook注入,hook好了之后,根据控制台的调试输出,发现已经断住了,断入的文件是一个vm文件(当前可以确定cookie是在vm中生成的),然后右侧的调用堆栈往上跟栈,找到cookie生成的地方
通过控制台的调试输出,可以知道:
- _$Ed就是当前cookie值
- _$Xl是cookie的key名称
- _$xh[_$k7[39]] 输出后是一个 _$xh[’cookie‘]
- 通过以上得到的结果就是:正在将cookie设置到_$xh[’cookie‘]身上
目前debugger到了cookie,但是当前cookie是上一个栈传进来的,那么当前需要在定位到的位置打上一个断点,继续向上跟栈,或者直接点击当前栈的上一个栈,这里就直接跟到上一个栈了
技巧的引出
以上已经暂时定位到cookie的位置了,但是分析都需要重新hook-cookie,所以这里需要将js保存到本地,因为每次js混淆都是动态的,所以比较麻烦。
通过事件监听器断主网页刷新后加载的js,找到需要本地替换保存的文件
断到一个$ts的变量,这个js文件是一个外部连接的js,里面的内容会有非常多的数组,生成的cookie会借助这个文件里面的内容,当前的内容还是一个乱码的状态,后面会通过主页的js,将这个文件的内容恢复成不是乱码的js
src="/4QbVtADbnLVIc/d.FxJzG50F.dfe1675.js 以上的js就是通过这个外链连接加载的
保存主页代码,使用本地替换的方式
随便选择一个文件夹,或者创建一个新的文件夹,在本地,然后点击选择文件夹就可以将当前的html文件保存到本地,如果不适用本地替换的方式也可以直接复制到编辑器中进行调试分析
保存到本地后可以看到当前打开的文件左下角有一个浅蓝的小圆点,那么代表你保存成功了,
这样做的好处是,每次刷新页面的时候就不会去重新请求新的文件,js的混淆也不会是动态的,这样比较好进行分析
提示:保存成功的是可以对保存后的文件进行修改的
vm加载位置
进到load(异步中),看到有两个eval
跟着跟着跟到了html文件
那么可以知道,vm是通过这个html文件中的js进行加载的,我们可以将$KU到控制台进行输出。可以看到是一个eval函数。
找到了vm加载的位置后,可以根据 篇幅: 技巧的引出通过本地替换js文件,然后在执行vm的前面打一个debugger
提:这里仅为个人观点,可能不对,请大佬指出问题
关于_$Vs.call(_$q0, _$_I);
- 当前_$Vs是混淆后的eval函数,
- eval的作用是可以将传入的字符串作为 JavaScript 代码执行
- call方法的作用是,在调用现有函数时,将指定的
this
值和一系列参数传递给该函数 - eval.call(Window,"代码") 表达的意思是,Window(全局)作用作为调用者,然后将 "代码" 传给eval函数。这里的意思可以理解为,将_$_I代码,在全局作用域中执行
补环境执行html中的js
首先可以将html中的js复制到本地,大概900多行
_$Vs.call(_$q0, _$_I); 将html中的js复制到本地之后,将 _$q0 中$_ts 原始的文件中的js复制到本地,/4QbVtADbnLVIc/d.FxJzG50F.dfe1675.js 在网络中搜索这个地址,讲里面的内容复制到本地中
运行前补环境:
报错:window is not defined
补:
window = {
"$_ts":{}
}
报错:
var _$Vs = _$q0.eval.toString();
TypeError: Cannot read properties of undefined (reading 'toString') 报错没有toString方法,但是toString方法前面是eval方法,先补eval在补toString
通过搜索:var _$Vs = _$q0.eval.toString(); 找到位置,通过console.log(_$q0) 输出,输出结果可以看到我们在window中定义的 $_ts。
那 $_ts 到底是啥,继续使用console.log(window) ,可以看到输出window得到的输出结果和_$q0一样,目前确定_$q0就是当前定义的window了,如果不确定的话可以通过 console.log(window === _$q0) 来进行判断
补:toString()
window = {
"$_ts":{},
eval_js:"", // 保存生成后的代码
eval:function (data) {
// console.log(data)
window.eval_js = data
return data
}
}
最后在本地执行,得到执行eval后的代码,也就是将 /4QbVtADbnLVIc/d.FxJzG50F.dfe1675.js 文件中的代码处理后得到的结果,也就是vm中的js,然后经过对比,可以看到生成的vm代码是和网页加载的vm代码是一样的,那么证明我们成功了
总结
- 分析流程
- 第一次请求:返回响应cookie 结尾为80S
- 第二次请求:本地生成cookie 结尾为80T,返回相应cookieJSESSIONID1
- 第三次请求:携带第一次返回的响应cookie和第二次生成的cookie请求,数据接口得到数据
- 过debugger
- 生成vm代码
- 拿到html中的混淆js,找到外部加载的js,放到本地补环境执行,拿到生成的vm代码
- cookie的生成在vm代码中