【Re】JS 逆向实战:深入解析 JS 源码混淆案例

2024-08-11 18:46:52 浏览数 (4)

声明

本博文所讨论的技术仅用于研究学习,旨在增强读者的信息安全意识,提高信息安全防护技能,严禁用于非法活动。任何个人、团体、组织不得用于非法目的,违法犯罪必将受到法律的严厉制裁。

流量分析,数据接口均已做脱敏处理,若造成侵权,请立即联系博主删除!

逆向目标

目标:计算所有机票价格的平均值;

链接:BRWJ2YmdUFp1VdEyUbAcWGW4cfrjRrTLmWwfZZTiEvmN1ikY;

简介:获取所有页面中机票的价格,并计算所有机票价格的平均值,需注意数据均为模拟数据,请正确识别

逆向分析

0x01 跳过断点

当我们按 F12 进入调试控制台时,发现此处有 debugger,直接右键将其 nop 掉。

0x02 分析接口

通过 API 接口我们能够发现,数据内容没有被加密,因此,我们只需要遍历所有页面的 API 接口,即可获取到全部机票价格,那么,我们的目标就是逆向 API 接口上的参数 m

代码语言:javascript复制
page: 2
m: 9ded2bedaa92ac18c32ce095e44a6765丨1723437277

根据观察推测 m 应该分为两部分:cipher | timestamp,接下来去请求调用堆栈中寻找蛛丝马迹。

发现一个 request 函数,步入相应位置,映入眼帘的就是时间戳的计算,应该就是我们要找寻的关键函数了。

由上图可知,JS 代码被略微混淆了,通过 JS 在线解密工具来进行解密:

一眼就看到了 m 参数:

代码语言:javascript复制
_0x5d83a3['m'] = _0x57feae   '丨'   _0x2268f9 / ( - 1 * 3483   -9059   13542);

接下来,我们就开始分析 ciphertimestamp 部分。

0x03 timestamp 分析

柿子要挑软的捏,我们先来研究时间戳这块,主要就是由两个步骤构成,转换后的代码如下所示:

代码语言:javascript复制
function getTimestamp() {
    const _0x2268f9 = Date['parse'](new Date())   (16798545   -72936737   156138192)
    return _0x2268f9 / (-1 * 3483   -9059   13542)
}

验证一下没啥问题,继续往下走。

0x04 cipher 分析

根据代码分析,cipheroo0O0() 函数与 window['f'] 参数构成:

代码语言:javascript复制
_0x57feae = oo0O0(_0x2268f9['toStr'   'ing']())   window['f'];

全局搜索 oo0O0() 函数,如下图所示:

oo0O0() 函数的主要目的是隐藏和执行某些动态生成的 JavaScript 代码,可以分为以下三个部分进行理解:

第一部分的主要作用是构建 window.b

代码语言:javascript复制
for (var i = 0, len = window.a.length; i < len; i  ) {
    console.log(window.a[i]);
    window.b  = String[document.e   document.g](window.a[i][document.f   document.h]() - i - window.c)
}

上述代码通过 window.a 的每个元素,计算一个字符的 ASCII 值,减去一个值,并将结果拼接到 window.b 中。这里使用了动态属性名来访问 String 对象的 fromCharCode 方法。

第二部分的主要作用是定义和使用 J 函数。J 是一个用于解码和处理字符串的函数,这个函数利用了 Base64 解码和 RC4 加密算法来解密字符串。

第三部分的主要作用是解密和执行代码:

代码语言:javascript复制
eval(atob(window['b'])[J('0x0', ']dQW')](J('0x1', 'GTu!'), 'x27'   mw   'x27'));

上述代码的解释如下:

  • atob(window['b']):对 window.b 进行 Base64 解码。
  • J('0x0', ']dQW')J('0x1', 'GTu!'):解码后的字符串通过 J 函数进一步处理。
  • eval(...):执行解密后的 JavaScript 代码。

其中,J('0x0', ']dQW')J('0x1', 'GTu!') 是固定的,直接通过动调获取返回值,如下图所示:

因此,第三部分代码可以转换为:

代码语言:javascript复制
eval(atob(window['b'])['replace']('mwqqppz', 'x27'   mw   'x27'));

atob(window['b']) 也可以直接解码,其实际作用是给 window.f 赋值,window.f = hex_md5(mwqqppz) 如下图所示:

在上述代码中还用到了几个常量,通过全局搜索即可获得,代码如下所示:

代码语言:javascript复制
document.e = 'fromC';
document.f = 'charCo';
document.g = 'harCode';
document.h = 'deAt';

window.a = '...'
window.c = 5

window.a 太大了,这里就不做展示了。

0x05 验证结果

将我们上述的所有分析进行整理,代码如下所示:

代码语言:javascript复制
window = {
    a: '...',
    c: 5,
}

document = {
    e: 'fromC',
    f: 'charCo',
    g: 'harCode',
    h: 'deAt',
}

function oo0O0(mw) {...}

然后再来验证一下,通过动调获取到当前的一个加密结果,如下图所示:

我们也将时间戳改成 1723453378000,代码如下所示:

代码语言:javascript复制
function results() {
    // const _0x2268f9 = Date['parse'](new Date())   (16798545   -72936737   156138192)
    const _0x2268f9 = 1723453378000
    return {timestamp: _0x2268f9 / 1000, cipher: oo0O0(_0x2268f9)   window.f}
}

console.log(results())

运行结果如下所示:

与实际结果相符,证明我们逆向的没有问题。

最终利用

使用 Python 编写脚本去尝试请求数据,代码如下所示:

代码语言:javascript复制
import execjs
import requests

with open('CodeJs.js', 'r', encoding='utf8') as f:
    js_code = f.read()

context = execjs.compile(js_code).call('results')
m = f'{context["cipher"]}丨{context["timestamp"]}'

url = "..."
response = requests.get(f'{url}?page=1&m={m}')
print(response.text)

运行结果:

利用成功,那我们开始计算所有机票价格的平均值,代码如下所示:

代码语言:javascript复制
url = "..."
total_sum = 0
total_cnt = 0

for i in range(5):
    response = requests.get(f'{url}?page={i   1}&m={m}')
    data = response.json()["data"]
    cnt_ = len(data)
    sum_ = sum(item["value"] for item in data)
    total_sum  = sum_
    total_cnt  = cnt_
    print(f"P{i   1} sum is {sum_}, cnt is {cnt_}")

print("All:", total_sum)
print("Average:", total_sum / total_cnt)

运行结果:

至此,我们就成功完成了逆向目标。

后记

在本文中,我们深入探讨了混淆源码的逆向分析过程,通过一系列的步骤逐步破解了复杂的混淆技术。从跳过断点到分析接口,再到 timestamp 和 cipher 的深入研究,我们不仅掌握了如何应对复杂的 JS 混淆技术,也提供了针对性的解决策略。

以上就是博文 JS 逆向实战:深入解析 JS 源码混淆案例 的所有内容了,希望本篇博文对大家有所帮助!欢迎大家持续关注我的博客,一起分享学习和成长的乐趣!✨

严正声明:本博文所讨论的技术仅用于研究学习,旨在增强读者的信息安全意识,提高信息安全防护技能,严禁用于非法活动。任何个人、团体、组织不得用于非法目的,违法犯罪必将受到法律的严厉制裁。

1 人点赞