昨日在浏览论坛的时候,发现大牛 发了一个帖子 猿人学第二题 手把手补环境
链接地址:猿人学第2题手把手补环境 - 『脱壳破解区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

image.png (76.3 KB, 下载次数: 2)
下载附件
2022-12-13 16:57 上传
依照Anekys 大牛提供的地址,进入之后返现者的是个练手的好地方,哈哈哈,js解密过程中,能遇到的问题,几乎在这边全部遇到了。并且还有解题排名,膜拜各种大牛的机会。
二、 正式开始
2.1 过掉debugger 分析页面
首先看第一题

image.png (32.73 KB, 下载次数: 1)
下载附件
2022-12-13 19:40 上传
要求是获取机票的平均价格,填入答案。
依照国际管理,F12,开发者工具,ctrl+shift+r 重新加载页面,不出意外的界面停止在debugger

image.png (11.37 KB, 下载次数: 2)
下载附件
2022-12-13 19:45 上传
直接在第二行除邮件编辑断点 值填写false,过掉debugger。
2.2 依次点击每一页的值查看,请求值变化
第一页 /api/match/1?m=5c70fb1948228fdf84f74568b037fa11|81671008953
第二页 /api/match/1?page=2&m=922c0993d9df7bc038a09470c17d5901|81671009628
第三页 api/match/1?page=3&m=e9526008c0fde5ba4e4499ec78289239|81671032379
不难看出请求不能的页面出了添加了page的参数外,m的值发生了变化,如果在全局搜索里面搜索m的话,这个值太多了直接去启动器中查看堆栈调用

forum.png (37.66 KB, 下载次数: 1)
下载附件
2022-12-13 19:59 上传
排除掉ajax 后,第一个就是request函数了,点击函数进入源代码区查看。

image.png (102.36 KB, 下载次数: 1)
下载附件
2022-12-13 20:02 上传
2.3 解密混淆和加密得js代码
js代码被加密混淆了,在线搜索js解密工具,其实不解密也能看,但是阅读的难度就比较高了。
解码后得到
[JavaScript] 纯文本查看 复制代码window['url'] = '/api/' + 'match' + '/1',
request = function() {
var _0x2268f9 = Date['parse'](new Date()) + (16798545 + -72936737 + 156138192),
_0x57feae = oo0O0(_0x2268f9['toStr' + 'ing']()) + window['f'];
const _0x5d83a3 = {};
_0x5d83a3['page'] = window['page'],
_0x5d83a3['m'] = _0x57feae + '丨' + _0x2268f9 / (-1 * 3483 + -9059 + 13542); // 看到m出现了
var _0xb89747 = _0x5d83a3;
$['ajax']({
'url': window['url'],
'dataType': 'json',
'async': ![],
'data': _0xb89747,
'type': 'GET',
'beforeSend': function(_0x4c488e) {},
'success': function(_0x131e59) {
_0x131e59 = _0x131e59['data'];
let _0x354583 = '',
_0x1b89ba = '' + '中国联合航' + '空' + 'KN591' + '1波' + '音737(' + '中)' + '' + '' + '13:50' + '' + '大兴' + '国际机场' + '' + '3' + '小时40分' + '钟' + '' + '17:' + '30' + '宝安机场
' + '' + '&' + 'yen;' + 'p' + 'rice_' + 'sole' + '
' + '' + '' + '收起' + '
' + ''),
_0x548377 = ['中国南方航' + '空', '吉祥航空', '奥凯航空', '九元航空', '长龙航空', '东方航空', '中国国际航' + '空', '深圳航空', '海南航空', '春秋航空', '上海航空', '西部航空', '重庆航空', '西藏航空', '中国联合航' + '空', '云南祥鹏航' + '空', '云南英安航' + '空', '厦门航空', '天津航空', '山东航空', '四川航空', '华夏航空', '长城航空', '成都航空有', '北京首都航' + '空', '中华航空', '意大利国家' + '航空公司', '印度百捷航' + '空', '越南航空', '远东航空', '印度航空公' + '司', '印度捷特航' + '空有限公司', '以色列航空' + '公司', '意大利航空', '伊朗航空公' + '司', '印度尼西亚' + '鹰航空公司', '英国航空公' + '司', '西方天空航' + '空', '西捷航空', '西班牙欧洲' + '航空公司', '西班牙航空' + '公司', '中国南方航' + '空', '吉祥航空', '奥凯航空', '九元航空', '长龙航空', '东方航空', '中国国际航' + '空', '深圳航空', '海南航空', '春秋航空', '上海航空', '西部航空', '重庆航空', '西藏航空', '中国联合航' + '空', '云南祥鹏航' + '空', '云南英安航' + '空', '厦门航空', '天津航空', '山东航空', '四川航空', '华夏航空', '长城航空', '成都航空有', '北京首都航' + '空', '中华航空', '意大利国家' + '航空公司', '印度百捷航' + '空', '越南航空', '远东航空', '印度航空公' + '司', '印度捷特航' + '空有限公司', '以色列航空' + '公司', '意大利航空', '伊朗航空公' + '司', '印度尼西亚' + '鹰航空公司', '英国航空公' + '司', '西方天空航' + '空', '西捷航空', '西班牙欧洲' + '航空公司', '西班牙航空' + '公司'],
_0x5286d2 = 22 * 251 + -1721 + -3800,
_0xa24ff9 = ['北京首都国' + '际机场', '上海虹桥国' + '际机场', '上海浦东国' + '际机场', '天津滨海国' + '际机场', '太原武宿机' + '场', '呼和浩特白' + '塔机场', '沈阳桃仙国' + '际机场', '大连周水子' + '国际机场', '长春大房身' + '机场', '哈尔滨阎家' + '岗国际机场', '齐齐哈尔三' + '家子机场', '佳木斯东郊' + '机场', '厦门高崎国' + '际机场', '福州长乐国' + '际机场', '杭州萧山国' + '际机场', '合肥骆岗机' + '场', '宁波栎社机' + '场', '南京禄口国' + '际机场', '广州白云国' + '际机场', '深圳宝安国' + '际机场', '长沙黄花机' + '场', '海口美亚机' + '场', '武汉天河机' + '场', '济南遥墙机' + '场', '青岛流亭机' + '场', '南宁吴墟机' + '场', '三亚凤凰国' + '际机场', '重庆江北国' + '际机场', '成都双流国' + '际机场', '昆明巫家坝' + '国际机场', '昆明长水国' + '际机场', '桂林两江国' + '际机场', '西安咸阳国' + '际机场', '兰州中川机' + '场', '贵阳龙洞堡' + '机场', '拉萨贡嘎机' + '场', '乌鲁木齐地' + '窝堡机场', '南昌向塘机' + '场', '郑州新郑机' + '场', '北京首都国' + '际机场', '上海虹桥国' + '际机场', '上海浦东国' + '际机场', '天津滨海国' + '际机场', '太原武宿机' + '场', '呼和浩特白' + '塔机场', '沈阳桃仙国' + '际机场', '大连周水子' + '国际机场', '长春大房身' + '机场', '哈尔滨阎家' + '岗国际机场', '齐齐哈尔三' + '家子机场', '佳木斯东郊' + '机场', '厦门高崎国' + '际机场', '福州长乐国' + '际机场', '杭州萧山国' + '际机场', '合肥骆岗机' + '场', '宁波栎社机' + '场', '南京禄口国' + '际机场', '广州白云国' + '际机场', '深圳宝安国' + '际机场', '长沙黄花机' + '场', '海口美亚机' + '场', '武汉天河机' + '场', '济南遥墙机' + '场', '青岛流亭机' + '场', '南宁吴墟机' + '场', '三亚凤凰国' + '际机场', '重庆江北国' + '际机场', '成都双流国' + '际机场', '昆明巫家坝' + '国际机场', '昆明长水国' + '际机场', '桂林两江国' + '际机场', '西安咸阳国' + '际机场', '兰州中川机' + '场', '贵阳龙洞堡' + '机场', '拉萨贡嘎机' + '场', '乌鲁木齐地' + '窝堡机场', '南昌向塘机' + '场', '郑州新郑机' + '场'];
if (window['page']) {} else
window['page'] = 2333 * 3 + 458 * -5 + -4708;
$['each'](_0x131e59, function(_0x282f1d, _0x4e0853) {
_0x354583 += _0x1b89ba['repla' + 'ce']('price' + '_sole', _0x4e0853['value'])['repla' + 'ce']('中国联合航' + '空', _0x548377[_0x5286d2 * window['page']])['repla' + 'ce']('大兴国际', _0xa24ff9[parseInt(_0x5286d2 * window['page'] / (659 + 785 * -7 + 4838)) + (5666 * 1 + 2 * -4161 + 2657)])['repla' + 'ce']('宝安机场', _0xa24ff9[_0xa24ff9['lengt' + 'h'] - parseInt(_0x5286d2 * window['page'] / (8357 + -323 * 1 + -8032)) - (350 + -9 * 295 + 2306)]),
_0x5286d2 += -156 * -53 + -78 * -111 + -16925;
}),
$('.m-ai' + 'rfly-' + 'lst')['text']('')['appen' + 'd'](_0x354583);
},
'complete': function() {},
'error': function() {
alert('数据拉取失' + '败。可能是' + '触发了风控' + '系统,若您' + '是正常访问' + ',请使用谷' + '歌浏览器无' + '痕模式,并' + '且校准电脑' + '的系统时间' + '重新尝试'),
alert('生而为虫,' + '我很抱歉,' + '请刷新页面' + ',查看问题' + '是否存在'),
$('.page' + '-mess' + 'age')['eq'](17 * -94 + 1014 + -4 * -146)['addCl' + 'ass']('activ' + 'e'),
$('.page' + '-mess' + 'age')['remov' + 'eClas' + 's']('activ' + 'e');
}
});
},
request();
虽然还是有加密的内容,但是我们看到了需要的关键数据 page 和 m的出现 并且后面又是ajax,推断加密代码就在前面几行,对照加密数据设置断点。

image.png (46.6 KB, 下载次数: 0)
下载附件
2022-12-13 20:10 上传
果然断在了断点处,步进查看变化。
小技巧:如果数值看不懂得,可以直接在控制台输入之后;

image.png (4.09 KB, 下载次数: 3)
下载附件
2022-12-13 20:24 上传
继续往下走,跳转到了第一页 页面自身得 javascript ,因为页面是一行超级长,复制出来,格式化以便理解。

image.png (86.39 KB, 下载次数: 2)
下载附件
2022-12-13 20:33 上传
继续安利,哈哈哈,我举得我更像一个分享up主。
删除掉不要得之后,发现了管家加密函数---------
[color=] oo0O0 是的就是这个狗东西。

image.png (36.14 KB, 下载次数: 1)
下载附件
2022-12-13 20:40 上传
请注意后面那个孤零零得箭头,就是她使我走向了一条没有尽头得路。
三、 解密关键函数
上文说到,window['\x66'] \x66 就是f啦,解密后的函数有表明,在跟进 关键解密函数
[color=]oo0O0
后,函数内容如下:
[JavaScript] 纯文本查看 复制代码
function oo0O0(mw) {
window.b = '';
for (var i = 0, len = window.a.length; i > (-0x2 * C & 0x6)) : 0x0) {
W = m['indexOf'](W)
}
return A
};
var t = function (w, m) {
var T = [],
A = 0x0,
C,
b = '',
W = '';
w = Y(w);
for (var R = 0x0, v = w['length']; R
看到函数定义后 马上定义了一个,window.b , window.b得值 是通过windows.a.length(长度)for 循环后计算得出,那么window.a的值是从哪里得来得呢,全局搜索后 window.a ,发现在自身页面得js中有定义。
嘿嘿,正道得光………………

image.png (34.35 KB, 下载次数: 0)
下载附件
2022-12-13 20:54 上传
第一个就在第一行,但是这一行也是超级长得,浏览器自带得格式化不管用,怎么操作不用我说了吧,嘿嘿,刚安利得工具。

image.png (18.22 KB, 下载次数: 1)
下载附件
2022-12-13 21:00 上传
看到了windows.a 但是貌似是乱码,控制台一下,window.a

image.png (73.34 KB, 下载次数: 1)
下载附件
2022-12-13 21:06 上传
也是存在各种各样得符号,监控一次此时得windows.b,

image.png (13.47 KB, 下载次数: 1)
下载附件
2022-12-13 21:26 上传
值越来越多了,哈哈哈,正道得光又要来了……
不仅仅在第一页找到了,window.a 连window.c 等等参与运算的,全部都找到了。

image.png (15.1 KB, 下载次数: 1)
下载附件
2022-12-13 21:29 上传
感觉自己离真相越来越近了。

image.png (12.84 KB, 下载次数: 2)
下载附件
2022-12-13 21:35 上传

image.png (21.58 KB, 下载次数: 2)
下载附件
2022-12-13 21:36 上传
在关键函数的下一行下断点,放开跑到断点之前,我们需要的m的值已经找到了。

image.png (42.17 KB, 下载次数: 1)
下载附件
2022-12-13 21:38 上传
此时我们也已经获得了window.b的全部值。
在我们解密后的关键函数中,看到window.b 有个atob ,百度一下
反正不懂就找百度,控制到运行 atob(windows['b'])

image.png (108.83 KB, 下载次数: 1)
下载附件
2022-12-13 21:51 上传
得到了另外一串js代码,观察发现貌似是md5加密的,放进wt里面跑一下(WT是个js调试工具,貌似也是吾爱大神弄出来的,在这里致敬一下,我等匹夫只能用下别人的工具了,做个工具小子吧)。
还记得那个孤独的箭头吗 ,对的,window['f']哪里。

image.png (16.65 KB, 下载次数: 1)
下载附件
2022-12-13 21:57 上传
至此我们终于找到了,真正的加密代码。
[JavaScript] 纯文本查看 复制代码var hexcase = 0;
var b64pad = "";
var chrsz = 16;
function hex_md5(a) {
return binl2hex(core_md5(str2binl(a), a.length * chrsz))
}
function b64_md5(a) {
return binl2b64(core_md5(str2binl(a), a.length * chrsz))
}
function str_md5(a) {
return binl2str(core_md5(str2binl(a), a.length * chrsz))
}
function hex_hmac_md5(a, b) {
return binl2hex(core_hmac_md5(a, b))
}
function b64_hmac_md5(a, b) {
return binl2b64(core_hmac_md5(a, b))
}
function str_hmac_md5(a, b) {
return binl2str(core_hmac_md5(a, b))
}
function md5_vm_test() {
return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"
}
function core_md5(p, k) {
p[k >> 5] |= 128 >> 9) 16) {
e = core_md5(e, c.length * chrsz)
}
var a = Array(16),
d = Array(16);
for (var b = 0; b > 16) + (d >> 16) + (c >> 16);
return (b >> (32 - b))
}
function str2binl(d) {
var c = Array();
var a = (1 > 5] |= (d.charCodeAt(b / chrsz) & a) > 5] >>> (b % 32)) & a)
}
return d
}
function binl2hex(c) {
var b = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var d = "";
for (var a = 0; a > 2] >> ((a % 4) * 8 + 4)) & 15) + b.charAt((c[a >> 2] >> ((a % 4) * 8)) & 15)
}
return d
}
function binl2b64(d) {
var c = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var f = "";
for (var b = 0; b > 2] >> 8 * (b % 4)) & 255) > 2] >> 8 * ((b + 1) % 4)) & 255) > 2] >> 8 * ((b + 2) % 4)) & 255);
for (var a = 0; a d.length * 32) {
f += b64pad
} else {
f += c.charAt((e >> 6 * (3 - a)) & 63)
}
}
}
return f
};
验证一下是否正确

image.png (15.27 KB, 下载次数: 1)
下载附件
2022-12-13 22:04 上传

image.png (20.48 KB, 下载次数: 1)
下载附件
2022-12-13 22:06 上传
哦吼,是一致的,那么说明,我们找的的加密函数是正确的,挖哈哈哈哈哈!!
四、关于算法
算法也是挺简单的,
1. 首先生成一个时间戳
2. 用hex_md5()函数加密时间戳,
3. 用时间戳除以1000 得到后面的值,
别问我为什么指导的,下一句就是,哈哈哈。

image.png (40.61 KB, 下载次数: 2)
下载附件
2022-12-13 22:14 上传
具体的就不写了哈,后续有时间在写python的实现。发现写文章还挺浪费时间,但是还是想把这些分享出来,给像我一样的小白避坑!!!