猿人学14题—备而后动-勿使有变
抓包分析
打开f12开发者工具抓包,会出现无限debugger
使用hook注入绕过
Function.prototype.__constructor_back = Function.prototype.constructor;
Function.prototype.constructor = function() {
if(arguments && typeof arguments[0]==='string'){
if(arguments[0].indexOf("debugger")!=-1){
return function(){}
}
}
return Function.prototype.__constructor_back.apply(this,arguments);
}
成功绕过
翻页,进行抓包
发现每翻页一次会发送两个请求,进入第一个请求查看,没有什么特别的参数,只有headers中携带了cookie,返回了一段js代码。
可以看到请求携带的cookie有七个,我们将除了sessionid以外的cookie都删除(登录后sessionis标识用户),重新翻页测试
,还是可以正常获取数据
我们可以看到第一个请求,多携带了一个mz
,所以mz
这个值是本地生成的,第二个请求多携带了一个m值,m值也是本地生成的
大致流程
1、本地生成mz值,请求第一个接口
2、本地生成m值,请求第二个接口
mz参数生成
这里使用油猴hook
// ==UserScript==
// @name Hook Cookie
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @include *
// @grant none
// @run-at document-start
// ==/UserScript==
(function () {
'use strict';
var cookie_cache = document.cookie;
Object.defineProperty(document, 'cookie', {
get: function () {
return cookie_cache;
},
set: function (val) {
console.log('Setting cookie', val);
// 填写cookie名
if (val.indexOf('mz') != -1) {
debugger;
}
//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 + "; ";
}
return cookie_cache;
}
});
})();
刷新网页,断点生效
网上跟一层堆栈
将这两行代码简单处理一下
b64_zw = btoa(z);
document["cookie"] = 'mz=' + b64_zw + ';path=/'
z来自上面的代码
z = [navigator['\x61\x70' + '\x70\x43' + '\x6f\x64' + '\x65\x4e' + '\x61\x6d' + '\x65'], navigator['\x61\x70' + '\x70\x4e' + '\x61\x6d' + '\x65'], navigator['\x61\x70' + '\x70\x56' + '\x65\x72' + '\x73\x69' + '\x6f\x6e'], navigator['\x63\x6f' + '\x6e\x6e' + '\x65\x63' + '\x74\x69' + '\x6f\x6e'], navigator['\x63\x6f' + '\x6f\x6b' + '\x69\x65' + '\x45\x6e' + '\x61\x62' + '\x6c\x65' + '\x64'], navigator['\x64\x6f' + '\x4e\x6f' + '\x74\x54' + '\x72\x61' + '\x63\x6b'], navigator['\x67\x65' + '\x6f\x6c' + '\x6f\x63' + '\x61\x74' + '\x69\x6f' + '\x6e'], navigator['\x68\x61' + '\x72\x64' + '\x77\x61' + '\x72\x65' + '\x43\x6f' + '\x6e\x63' + '\x75\x72' + '\x72\x65' + '\x6e\x63' + '\x79'], navigator['\x6c\x61' + '\x6e\x67' + '\x75\x61' + '\x67\x65'], navigator['\x6c\x61' + '\x6e\x67' + '\x75\x61' + '\x67\x65' + '\x73'], navigator['\x6d\x61' + '\x78\x54' + '\x6f\x75' + '\x63\x68' + '\x50\x6f' + '\x69\x6e' + '\x74\x73'], navigator['\x6d\x65' + '\x64\x69' + '\x61\x43' + '\x61\x70' + '\x61\x62' + '\x69\x6c' + '\x69\x74' + '\x69\x65' + '\x73'], navigator['\x6d\x65' + '\x64\x69' + '\x61\x53' + '\x65\x73' + '\x73\x69' + '\x6f\x6e'], navigator['\x6d\x69' + '\x6d\x65' + '\x54\x79' + '\x70\x65' + '\x73'], navigator['\x6f\x6e' + '\x4c\x69' + '\x6e\x65'], navigator['\x70\x65' + '\x72\x6d' + '\x69\x73' + '\x73\x69' + '\x6f\x6e' + '\x73'], navigator['\x70\x6c' + '\x61\x74' + '\x66\x6f' + '\x72\x6d'], navigator['\x70\x6c' + '\x75\x67' + '\x69\x6e' + '\x73'], navigator['\x70\x72' + '\x6f\x64' + '\x75\x63' + '\x74'], navigator['\x70\x72' + '\x6f\x64' + '\x75\x63' + '\x74\x53' + '\x75\x62'], navigator['\x75\x73' + '\x65\x72' + '\x41\x63' + '\x74\x69' + '\x76\x61' + '\x74\x69' + '\x6f\x6e'], navigator['\x75\x73' + '\x65\x72' + '\x41\x67' + '\x65\x6e' + '\x74'], navigator['\x76\x65' + '\x6e\x64' + '\x6f\x72'], navigator['\x76\x65' + '\x6e\x64' + '\x6f\x72' + '\x53\x75' + '\x62'], navigator['\x77\x65' + '\x62\x6b' + '\x69\x74' + '\x50\x65' + '\x72\x73' + '\x69\x73' + '\x74\x65' + '\x6e\x74' + '\x53\x74' + '\x6f\x72' + '\x61\x67' + '\x65'], navigator['\x77\x65' + '\x62\x6b' + '\x69\x74' + '\x54\x65' + '\x6d\x70' + '\x6f\x72' + '\x61\x72' + '\x79\x53' + '\x74\x6f' + '\x72\x61' + '\x67\x65'], screen['\x61\x76' + '\x61\x69' + '\x6c\x48' + '\x65\x69' + '\x67\x68' + '\x74'], screen['\x61\x76' + '\x61\x69' + '\x6c\x4c' + '\x65\x66' + '\x74'], screen['\x61\x76' + '\x61\x69' + '\x6c\x54' + '\x6f\x70'], screen['\x61\x76' + '\x61\x69' + '\x6c\x57' + '\x69\x64' + '\x74\x68'], screen['\x63\x6f' + '\x6c\x6f' + '\x72\x44' + '\x65\x70' + '\x74\x68'], screen['\x68\x65' + '\x69\x67' + '\x68\x74'], screen['\x6f\x72' + '\x69\x65' + '\x6e\x74' + '\x61\x74' + '\x69\x6f' + '\x6e'], screen['\x70\x69' + '\x78\x65' + '\x6c\x44' + '\x65\x70' + '\x74\x68'], screen['\x77\x69' + '\x64\x74' + '\x68'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x61\x6e' + '\x63\x65' + '\x73\x74' + '\x6f\x72' + '\x4f\x72' + '\x69\x67' + '\x69\x6e' + '\x73'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x61\x73' + '\x73\x69' + '\x67\x6e'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x68\x61' + '\x73\x68'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x68\x6f' + '\x73\x74'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x68\x6f' + '\x73\x74' + '\x6e\x61' + '\x6d\x65'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x68\x72' + '\x65\x66'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x6f\x72' + '\x69\x67' + '\x69\x6e'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x70\x61' + '\x74\x68' + '\x6e\x61' + '\x6d\x65'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x70\x6f' + '\x72\x74'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x70\x72' + '\x6f\x74' + '\x6f\x63' + '\x6f\x6c'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x72\x65' + '\x6c\x6f' + '\x61\x64'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x72\x65' + '\x70\x6c' + '\x61\x63' + '\x65'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x73\x65' + '\x61\x72' + '\x63\x68'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x74\x6f' + '\x53\x74' + '\x72\x69' + '\x6e\x67'], document['\x6c\x6f' + '\x63\x61' + '\x74\x69' + '\x6f\x6e']['\x76\x61' + '\x6c\x75' + '\x65\x4f' + '\x66']],
简单处理下
z = [navigator["appCodeName"], navigator["appName"], navigator["appVersion"], navigator["connection"], navigator["cookieEnabled"], navigator["doNotTrack"], navigator["geolocation"], navigator["hardwareConcurrency"], navigator["language"], navigator["languages"], navigator["maxTouchPoints"], navigator["mediaCapabilities"], navigator["mediaSession"], navigator["mimeTypes"], navigator["onLine"], navigator["permissions"], navigator["platform"], navigator["plugins"], navigator["product"], navigator["productSub"], navigator["userActivation"], navigator["userAgent"], navigator["vendor"], navigator["vendorSub"], navigator["webkitPersistentStorage"], navigator["webkitTemporaryStorage"], screen["availHeight"], screen["availLeft"], screen["availTop"], screen["availWidth"], screen["colorDepth"], screen["height"], screen["orientation"], screen["pixelDepth"], screen["width"], document["location"]["ancestorOrigins"], document["location"]["assign"], document["location"]["hash"], document["location"]["host"], document["location"]["hostname"], document["location"]["href"], document["location"]["origin"], document["location"]["pathname"], document["location"]["port"], document["location"]["protocol"], document["location"]["reload"], document["location"]["replace"], document["location"]["search"], document["location"]["toString"], document["location"]["valueOf"]];
可以看到是取了浏览器的一些环境
所以mz可以固定
TW96aWxsYSxOZXRzY2FwZSw1LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzExNC4wLjAuMCBTYWZhcmkvNTM3LjM2IEVkZy8xMTQuMC4xODIzLjgyLFtvYmplY3QgTmV0d29ya0luZm9ybWF0aW9uXSx0cnVlLCxbb2JqZWN0IEdlb2xvY2F0aW9uXSwyMCx6aC1DTix6aC1DTixlbixlbi1HQixlbi1VUywwLFtvYmplY3QgTWVkaWFDYXBhYmlsaXRpZXNdLFtvYmplY3QgTWVkaWFTZXNzaW9uXSxbb2JqZWN0IE1pbWVUeXBlQXJyYXldLHRydWUsW29iamVjdCBQZXJtaXNzaW9uc10sV2luMzIsW29iamVjdCBQbHVnaW5BcnJheV0sR2Vja28sMjAwMzAxMDcsW29iamVjdCBVc2VyQWN0aXZhdGlvbl0sTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzExNC4wLjAuMCBTYWZhcmkvNTM3LjM2IEVkZy8xMTQuMC4xODIzLjgyLEdvb2dsZSBJbmMuLCxbb2JqZWN0IERlcHJlY2F0ZWRTdG9yYWdlUXVvdGFdLFtvYmplY3QgRGVwcmVjYXRlZFN0b3JhZ2VRdW90YV0sMTAzMiwwLDAsMTkyMCwyNCwxMDgwLFtvYmplY3QgU2NyZWVuT3JpZW50YXRpb25dLDI0LDE5MjAsW29iamVjdCBET01TdHJpbmdMaXN0XSxmdW5jdGlvbiBhc3NpZ24oKSB7IFtuYXRpdmUgY29kZV0gfSwsbWF0Y2gueXVhbnJlbnh1ZS5jbixtYXRjaC55dWFucmVueHVlLmNuLGh0dHBzOi8vbWF0Y2gueXVhbnJlbnh1ZS5jbi9tYXRjaC8xNCxodHRwczovL21hdGNoLnl1YW5yZW54dWUuY24sL21hdGNoLzE0LCxodHRwczosZnVuY3Rpb24gcmVsb2FkKCkgeyBbbmF0aXZlIGNvZGVdIH0sZnVuY3Rpb24gcmVwbGFjZSgpIHsgW25hdGl2ZSBjb2RlXSB9LCxmdW5jdGlvbiB0b1N0cmluZygpIHsgW25hdGl2ZSBjb2RlXSB9LGZ1bmN0aW9uIHZhbHVlT2YoKSB7IFtuYXRpdmUgY29kZV0gfQ==
m的值
定位&参数组成
继续使用油猴hook cookie
跟栈
将try代码块简单处理下
try {
if (Object["defineProperty"]()) {
document["cookie"] = G["ROwxM"](G["zWYmB"](G["zWYmB"](G["ycfRT"](G["qfSxT"](G["ydZhv"](G["fixAu"]("m=", G["tlpBr"](m5, G["Jhspr"](gee, e, d, c, bb, aa, b64_zw))) + "|", d), "|"), a), "|"), window.n), G["ZDKbv"]);
} else {
document["cookie"] = G["fixAu"](G["OoepU"](G["OoepU"](G["MQOJb"](G["JEyfp"](G["JEyfp"](G["LnlnO"]("m=", G["tlpBr"](m5, G["CdSNM"](gee, aa, bb, c, d, e, b64_zw))), "|"), b), "|") + a, "|"), window.n), G["ZDKbv"]);
}
} catch (K) {
console.log(K);
alert("仅支持chrome浏览器,如果您看到这个提示条。请使用chrome尝试打开页面");
}
进一步处理,因为Object["defineProperty"]()
返回空字符串
所以会执行else逻辑
document["cookie"] = "m=" + m5(gee(aa, bb, c, d, e, b64_zw)) + "|" + b + "|" + a + "|" + window.n + ';path=/'
需要的参数有
aa、bb、c、d、e、b64_zw、b、a
他们的定义位置在上面
b64_zw = "TW96aWxsYSxOZXRzY2FwZSw1LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzExNC4wLjAuMCBTYWZhcmkvNTM3LjM2IEVkZy8xMTQuMC4xODIzLjgyLFtvYmplY3QgTmV0d29ya0luZm9ybWF0aW9uXSx0cnVlLCxbb2JqZWN0IEdlb2xvY2F0aW9uXSwyMCx6aC1DTix6aC1DTixlbixlbi1HQixlbi1VUywwLFtvYmplY3QgTWVkaWFDYXBhYmlsaXRpZXNdLFtvYmplY3QgTWVkaWFTZXNzaW9uXSxbb2JqZWN0IE1pbWVUeXBlQXJyYXldLHRydWUsW29iamVjdCBQZXJtaXNzaW9uc10sV2luMzIsW29iamVjdCBQbHVnaW5BcnJheV0sR2Vja28sMjAwMzAxMDcsW29iamVjdCBVc2VyQWN0aXZhdGlvbl0sTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzExNC4wLjAuMCBTYWZhcmkvNTM3LjM2IEVkZy8xMTQuMC4xODIzLjgyLEdvb2dsZSBJbmMuLCxbb2JqZWN0IERlcHJlY2F0ZWRTdG9yYWdlUXVvdGFdLFtvYmplY3QgRGVwcmVjYXRlZFN0b3JhZ2VRdW90YV0sMTAzMiwwLDAsMTkyMCwyNCwxMDgwLFtvYmplY3QgU2NyZWVuT3JpZW50YXRpb25dLDI0LDE5MjAsW29iamVjdCBET01TdHJpbmdMaXN0XSxmdW5jdGlvbiBhc3NpZ24oKSB7IFtuYXRpdmUgY29kZV0gfSwsbWF0Y2gueXVhbnJlbnh1ZS5jbixtYXRjaC55dWFucmVueHVlLmNuLGh0dHBzOi8vbWF0Y2gueXVhbnJlbnh1ZS5jbi9tYXRjaC8xNCxodHRwczovL21hdGNoLnl1YW5yZW54dWUuY24sL21hdGNoLzE0LCxodHRwczosZnVuY3Rpb24gcmVsb2FkKCkgeyBbbmF0aXZlIGNvZGVdIH0sZnVuY3Rpb24gcmVwbGFjZSgpIHsgW25hdGl2ZSBjb2RlXSB9LCxmdW5jdGlvbiB0b1N0cmluZygpIHsgW25hdGl2ZSBjb2RlXSB9LGZ1bmN0aW9uIHZhbHVlT2YoKSB7IFtuYXRpdmUgY29kZV0gfQ=="//环境字符串进行base64
a = 8 * Date.parse(new Date()); // 时间戳相关
b = Date.parse(new Date()); //时间戳
c = window.v14; //全局变量,目前未知
d = 'Mozilla,Netscape,5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.82,[object NetworkInformation],true,,[object Geolocation],20,zh-CN,zh-CN,en,en-GB,en-US,0,[object MediaCapabilities],[object MediaSession],[object MimeTypeArray],true,[object Permissions],Win32,[object PluginArray],Gecko,20030107,[object UserActivation],Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.82,Google Inc.,,[object DeprecatedStorageQuota],[object DeprecatedStorageQuota],1032,0,0,1920,24,1080,[object ScreenOrientation],24,1920,[object DOMStringList],function assign() { [native code] },,match.yuanrenxue.cn,match.yuanrenxue.cn,https://match.yuanrenxue.cn/match/14,https://match.yuanrenxue.cn,/match/14,,https:,function reload() { [native code] },function replace() { [native code] },,function toString() { [native code] },function valueOf() { [native code] }';//环境,可固定
e = window.v142; //全局变量,目前未知
p = E(parseInt(a / 8)); //时间*8,然后进行rsa加密
aa = m5(p);
bb = m5(b);
window.n += 1;
补环境
接下来就是补环境
本来想通过扣代码解决,但是扣着扣着发现几乎扣完了全部的代码,索性代码全部拿下来,直接补环境
首先简单处理下十六进制编码问题
然后将最后的try-catch改写下,我们知道会走else的逻辑
提示:ReferenceError: window is not defined
window = global;
没有错误提示了,接下来执行下sp函数,提示navigator未定义
我们知道z是环境相关数组,b64_zw和d
都会用到z
,并且btoa
执行时,也会隐式调用z.toString()
b64_zw = G["cWQTT"](btoa, z);
d = z["toString"]();
所以我们可以将z定义语句改写为
提示:document is not defined
补
document = {
cookie:""
}
提示:$ is not defined
这是ajax相关的代码,我们先将这个语句注释掉
ASN1 is not defined
错误位置如下
ASN1是在上面赋值的,按理说应该存在ASN1的,如果按照之前的补环境,window=global
,那么global
应该存在ASN1,但是实际上并不存在
我们查看下window是什么
是一个普通的对象,显然不对,按照经验,是代码中某个地方对window进行了重新赋值(这也是浏览器和node补环境容易被检测的地方,浏览器的window、location等对象的值不能被覆盖,而node可以)
我们搜索一下window =
,一共两个结果,第一个是我们自己补充的代码,第二个是一个eval执行
找到了检测位置,我们就将其注释即可
无限输出:生而为虫,我很抱歉
搜索一下:虫
(hook一下console.log也可以,没有解混淆的话,搜索汉字的\x编码也可以),是下面这段代码输出的
if (x["CuLuB"](m5[x["OPnPG"](x["PtKem"](x["eZkFz"]("to", "St"), "ri"), "ng")]()[x["kXFxj"](x["AKZTZ"]("inde", "xO"), "f")]("\n"), -(x["JYVAM"](1507, x["gJsFT"](-311, -11)) + -4927))) while (!![]) {
console["log"](x["xiQWv"](x["pSnMY"](x["pSnMY"](x["pSnMY"]("生而", "为虫"), ",我"), "很抱"), "歉"));
}
continue;
这段代码只有一个if分支,所以直接注释即可
提示:Cannot read properties of undefined (reading ‘length’)
下断点在13161行
可以发现cY是undefined,追栈发现是c参数为undefind
而c来自window的全局变量,e也是一样,我们先将这两个值固定,在这里我们记录下[aa, bb, c, d, e, b64_zw]这几个值和对应的函数计算结果
[aa, bb, c, d, e, b64_zw] = [
"0155ed5622d95ab34d887752bd98abdd",
"e5776e77448b293fb7784e07d16e9bcf",
"y8w9t43xesmfvc6",
"Mozilla,Netscape,5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.82,[object NetworkInformation],true,,[object Geolocation],20,zh-CN,zh-CN,en,en-GB,en-US,0,[object MediaCapabilities],[object MediaSession],[object MimeTypeArray],true,[object Permissions],Win32,[object PluginArray],Gecko,20030107,[object UserActivation],Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.82,Google Inc.,,[object DeprecatedStorageQuota],[object DeprecatedStorageQuota],1032,0,0,1920,24,1080,[object ScreenOrientation],24,1920,[object DOMStringList],function assign() { [native code] },,match.yuanrenxue.cn,match.yuanrenxue.cn,https://match.yuanrenxue.cn/match/14,https://match.yuanrenxue.cn,/match/14,,https:,function reload() { [native code] },function replace() { [native code] },,function toString() { [native code] },function valueOf() { [native code] }",
"12606447793",
"TW96aWxsYSxOZXRzY2FwZSw1LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzExNC4wLjAuMCBTYWZhcmkvNTM3LjM2IEVkZy8xMTQuMC4xODIzLjgyLFtvYmplY3QgTmV0d29ya0luZm9ybWF0aW9uXSx0cnVlLCxbb2JqZWN0IEdlb2xvY2F0aW9uXSwyMCx6aC1DTix6aC1DTixlbixlbi1HQixlbi1VUywwLFtvYmplY3QgTWVkaWFDYXBhYmlsaXRpZXNdLFtvYmplY3QgTWVkaWFTZXNzaW9uXSxbb2JqZWN0IE1pbWVUeXBlQXJyYXldLHRydWUsW29iamVjdCBQZXJtaXNzaW9uc10sV2luMzIsW29iamVjdCBQbHVnaW5BcnJheV0sR2Vja28sMjAwMzAxMDcsW29iamVjdCBVc2VyQWN0aXZhdGlvbl0sTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzExNC4wLjAuMCBTYWZhcmkvNTM3LjM2IEVkZy8xMTQuMC4xODIzLjgyLEdvb2dsZSBJbmMuLCxbb2JqZWN0IERlcHJlY2F0ZWRTdG9yYWdlUXVvdGFdLFtvYmplY3QgRGVwcmVjYXRlZFN0b3JhZ2VRdW90YV0sMTAzMiwwLDAsMTkyMCwyNCwxMDgwLFtvYmplY3QgU2NyZWVuT3JpZW50YXRpb25dLDI0LDE5MjAsW29iamVjdCBET01TdHJpbmdMaXN0XSxmdW5jdGlvbiBhc3NpZ24oKSB7IFtuYXRpdmUgY29kZV0gfSwsbWF0Y2gueXVhbnJlbnh1ZS5jbixtYXRjaC55dWFucmVueHVlLmNuLGh0dHBzOi8vbWF0Y2gueXVhbnJlbnh1ZS5jbi9tYXRjaC8xNCxodHRwczovL21hdGNoLnl1YW5yZW54dWUuY24sL21hdGNoLzE0LCxodHRwczosZnVuY3Rpb24gcmVsb2FkKCkgeyBbbmF0aXZlIGNvZGVdIH0sZnVuY3Rpb24gcmVwbGFjZSgpIHsgW25hdGl2ZSBjb2RlXSB9LCxmdW5jdGlvbiB0b1N0cmluZygpIHsgW25hdGl2ZSBjb2RlXSB9LGZ1bmN0aW9uIHZhbHVlT2YoKSB7IFtuYXRpdmUgY29kZV0gfQ=="
]
/
gee(aa, bb, c, d, e, b64_zw) =
'Et90anhIF41pKgJzICd0UHMnXBqqAdw01MSKmaow0o4rRpsQPP9KXJLiLReWwdD(kFBEUZ4cMW9zH4YEBVKRYHl5qOIDzu3fpSk)7pBaFwfXublJ3z2TBqf7WPqW4ebzTEe8apCXZXjLzeWNFbHKrMnqKwaCz9npxGWpHd)zi)c2y6aR5VqnJ38tB0ogWw9ouVDf0Wu7uk6IhJGT5BI2m8ABY9JXXfA5DjqdPwvR9bqCBSvy4cwcbkwUzTpG20kSbNN16s0w)j2kJ5jy5rRovkhNDJZ(KJJ4TGe2pnT(0WXY76FgYIRz1IUg8egsR4wXOVa16hLMgjE8cpj46k4(q)S5U5VXXs1H9kupJbiCzv4)AAT28oQtMUIvV1lUI3syzGgOJJYMmmvAoI9bjy2GrDx1pCpt2(0j03ZB2mtdn33BsO4jBF6t7UJeHTfZbgg(2vYyV58uutJpvH)qgUQNToNT)l27jOXPIbB9lZUCxWhqCWtSSuSAF7HYpZ0ghb1KjCgd5LiDOgTQJff3kDAQ7ls8knD9nOC0FAsmrcX(Uq9c53PdIhdm)GWm8ba64QRFgE4aKUM5NFo6UNT)KFlGNYxFe2Gp1FKLTKkhU9OrNiVQ9wX80YNRwKmlEzcTixhP6iel4tKihwfrmCAUJ386zD)fV6LpvUKYC5N4RQiaWhMbFigl)Z6qZGI3RG2)gAd9h4Nova8zMfA0ExOrcr8M(63LjY5JdJnvRZJteFdqHEiyvWfIdA0T1Enc6brpG19WRPyYZZsYztyRC)8RrfXCTDzx2KssfWqn0wS1xteYOJdfhMFG0hkSzQMeLUIi9dxloXGyQhkSbcBNTAN9zD3Kkr0Ht1gc2nofjxbNQ2B0bNwpt8AVx9QVb9VgtKrSsYQPa7cad368ee2cd6d3f411f22cd081ab62ec5ba8d2665491beb80d1e6a43bd5a5c71ecd6e092aef32c2400a5d3b962a3d0191c44da7b2254c399a47eda251e4dcc5dca6862c564f233cadd01522f829da1ad44a5bcf764ab422c36ea84bf2db1b4af46e26e9510863718f4fbba84a2e40bded7a38f00625f021620e5463f0fdee1'
///
m5(gee(aa, bb, c, d, e, b64_zw)) = 'cd0e6de991034a34a4171323a5b7ef63'
ReferenceError: CanvasCaptureMediaStreamTrack is not defined
看堆栈,发现这个报错来自eval
我们全局搜索下eval,这些eval调用的地方很可能是检测点,下断点后,debug模式执行
首先第一个eval位置
将navigator置空,利用了node和浏览器差异检测,我们注释掉
因为我们一开始没有补navigator,代码中又将navigator赋值空对象,所以后续用到了navigator没有报错,此时我们删掉了赋值代码,我们就要在开头手动补充navigator
再次重启调试,第二个eval位置,删除了document,注释掉
第三个eval位置,删除了window,注释掉
再次重启调试
补充CanvasCaptureMediaStreamTrack函数
这时候发现结果出来了
m=208daf93dcdb4b7aafb805a0d0ecedeb|1690000814000|211250101750|1;path=/
浏览器结果:
m=cd0e6de991034a34a4171323a5b7ef63|1690000814000|211250101750|1;path=/
会发现第一段不一致
刚刚我们补了navigator = {},并且navigator确实在代码中使用了某些属性,所以我们从navigator开始补充
上代理
navigator = {}
navigator = new Proxy(navigator, {
get(target, propKey, receiver) {
console.log("调用了",propKey)
return Reflect.get(target, propKey, receiver)
}
})
直接运行
将这些属性进行补充
navigator = {
appName: "Netscape",//必须相等
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.82",
cookieEnabled: true,//开启cookie,true
appCodeName: "Mozilla",//检测是否存在,随便写也可以
}
运行结果
m=969c0cdf7b5e21e4a58d0849143f2146|1690000814000|211250101750|1;path=/
此时结果还是不一致,为了验证是否是环境被检测了,我们将代码放到浏览器执行试试
可以发现执行结果和真实结果一致
剩余检测点寻找
一般的监测会使用try-catch包裹,防止报错,或者使用&&、使用typeof检测
我们先搜索try-catch
首先开头有一个try
查看浏览器发现,最终执行的是try中的代码,所以将代码修改为
将下面的try都打断点,在此过程中发现一个检测
这里检测了global,在浏览器中10227行代码肯定会报错,执行catch逻辑,代码删掉,改写如下
再次执行,和浏览器结果一致了
在所有需要的参数中,还有两个参数是未知的,即:window["v14"]
、window["v142"]
window["v14"]
、window["v142"]
由来
我们记得每翻一页都会发送两个请求
先看一下第一个请求发起的位置
进入m.js
这个地方就是前面我们注释掉的和ajax有关的代码部分,可以猜测,第一个请求返回的js执行后,window["v14"]
、window["v142"]
两个变量就生成了
从这里也可以看出,success回调执行了eval
观察代码发现,给window两个变量赋值的地方就在这里
直接运行代码,程序会卡住,无法结束,所以hook一下setInterval即可,并且不要格式化(格式化检测)
随便补一下,结果就出来了
在修改一下,封装一个函数便于调用