用OSINT的方法逆向加密算法 - WxIsaac64

前言

书接上回 微信视频号视频加密逆向。在之前的一篇文章中,我们留下了一个问题,就是WxIsacc64这个加密算法到底是怎么个回事捏。

虽然名字已经很清楚了,必然是ISAAC64算法,但是他具体是怎么生成的捏,今天我们就来一起逆向吧。

具体过程

那么要怎么开始呢。

在机缘巧合之下(fuzzy testing),我把一个巨大的值作为seed传入了生成解密序列的函数,然后我就得到了一个很有用的报错 stoull: out of range

image-20240130005313592

stoull是啥,简单来说就是把字符串变成一个unsigned long long。从这边我们其实可以得到几个非常重要的信息。

  1. 他的isaac64有很大的概率是通过一个c(或者类c的语言,比如c++)程序实现的。通过把c程序编译成wasm来让网页调用
  2. 在传入seed的时候,seed有很大的可能会被变成unsigned long long然后再传入。
  3. 他给了我们一个call stack,我们可以根据这个call stack来寻找相对应的函数

那么在了解了这些信息后,我们就可以开始进一步逆向啦。

Wasm侦探,认真办案!

在这个call stack中有一个非常重要的函数,就是$688。这个函数不仅在名字上和他的callee差了一个数字,更是报错开始的地方。

image-20240130012444924

如果我们使用一个正常的seed,也就是12312312。 在$688函数中,程序会调用$3478,他的返回值正好是数字12312312

但如果我们使用一个不正常的seed,比如"9" * 100。程序在调用$3478函数的时候就会报错,完全走不到下一步。

由此,我们可以合理推测 $3478就是stoull函数。

Screenshot_20240130_011941

接着,我们继续往下翻,发现$688,调用了另外一个有趣的函数$687。他给$687传了一个地址。

如果我们在内存中查看这个地址,可以发现他正好代表了我们输入的数字。比如在这就是123123123 = 0x0756b5b3。

他把转换成的数字的地址传给了$687,很明显,这就是在传我们的seed啊!

Screenshot_20240130_014211

我们把$687函数单独提出来运行看看

1
2
3
4
5
let HEAP32 = new Int32Array(new ArrayBuffer(1 << 24));
// 18446744073709551615 = 0xffffffffffffffff
HEAP32[0] = -1;
HEAP32[1] = -1;
$687(0,1)

诶,0x7c = 124, 0x38 = 56, 0xf9 = 253。这不是我们的的解密序列嘛!

看起来我们找到关键函数了,就是$687

image-20240130015427371

重生之我是OSINT大神

$687中有一些非常有有趣的值

1
2
3
4
5
6
7
8
9
10
function $687($0_1, $1_1) {
$0_1 = $0_1 | 0;
$1_1 = $1_1 | 0;
var i64toi32_i32$1 = 0,// ........ ignored;
// ......
i64toi32_i32$0 = 1685866103;
$177_1 = -1568126084;
$177$hi = i64toi32_i32$0;
i64toi32_i32$0 = -1174883550;
//... ignored

比如通过1685866103,我们可以知道stack上存在一连串非常有特点的值。我的直觉告诉我,这些值很有可能和加密算法有关。

比如这个 0x647c4677a2884b7c

Screenshot_20240130_020213

那么,开始OSINT

啊这................

Screenshot_20240130_020649

啊这这这这这这这这这这。。。。。。。。。。。。。。

image-20240130021256004

这不是一模一样嘛啊喂喂喂喂喂喂喂喂喂喂喂喂喂喂喂喂喂喂!!!!!!!!!11

好了,这下直接复制粘贴代码就好了

写在后面

其实这个算法我在写完那篇文章后就逆向出来,但是由于各种原因一直没时间写。

今天总算是挤出来一些时间把这篇博客写了。也算是把这个逆向计划补完了。

不过这篇确实有点点水,因为大部分时间都花在debugging上了,就是找哪个函数是关键函数。这部分要是写进博客里就太无聊了,于是我就没写。

不管怎么样,完结散花 ~~~~~

一些杂七杂八的东西:

0x647c4677a2884b7c其实是golden ratio constant的一部分。很多别的isaa64算法用了近似值也就是0x9e3779b97f4a7c13来计算。这导致了算法生成的结果不太一样。

Reference

  1. coreutils: https://github.com/coreutils/coreutils