li083m 发表于 2025-5-15 20:20

Tk-验证码hashcash之answer参数详解

本帖最后由 li083m 于 2025-5-15 20:57 编辑

## 前言

在游客状态下,访问用户主页,可能会有概率触发hashcash的旋转类型滑块,他与旋转(whirl)稍微不同,多了一个answer的函数,其他轨迹和参数值大致相同,此处分析answer参数,根据堆栈下断,最后得知是由jsvmp实现。

## 分析

千篇一律的,函数调用处(apply,call)插桩和运算符 `+ - * / % ^ * >> <<` 处插桩。

示例如下:

`"对象E: ", JSON.stringify(E,function(k, v) {if (v === window) {return 'window'} return v}), "函数w: ", w.toString(), "参数_: ", JSON.stringify(_,function(k, v) {if (v === window) {return 'window'} return v}), "结果k: ", k`

`'p',p ,'+=' ,'t',t`

将日志保存下来,随后观察日志发现

!(https://image.3001.net/images/20250515/1747309200_6825d2903ead4050711db.png)



发现首先创建了 ``
然后 看到了一个 关键 `3773868340 >>> n 24= 224`
接着 生成了8个随机数`随机数*9007199254740992(固定值) *=7147027398806892 `接着调用取整函数`floor()`
最后在 `7147027398806892 %= 52(固定值) = 12 `
下面逻辑也是同上。

对于上述固定值的结论,我们这里最好的是打印一份相同的日志,看看是否真的是一样的值,对比发现,是一样的,所以我们可以大胆确定就是固定的。也是最简单粗暴的方法了。

现在已知的得到了,未知的是什么呢,`3773868340?`
这里不卖官子,实际上这个值是get请求包中的`["data"]["challenges"]["question"]["stamp"]`值。

既然有数组中有8个元素,自然也是8次运算结果,最后得到了一个新的数组,且称为数组1.

`["data"]["challenges"]["question"]prefix` 且称为时间戳。

现在得到

```
数组1 =
时间戳 = 1747284377
stamp = 3773868340
临界值=stamp >>>24 = 224
```

继续观察日志

!(https://image.3001.net/images/20250515/1747310102_6825d616a50b2da7ae3f6.png)

`码表 ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"`
根据上面数组1 map 取 charAt 后得到 meSxHCmZ 这个值
然后在拼接时间戳得到 1747284377meSxHCmZ 现在经过一个匿名函数 得到 1192275636
这里直接去搜索然后把js抠出来即可。具体给出

```javascript
const chars = currentArray.map(index => alphabet.charAt(index)).join('');
```

接着继续观察日志

!(https://image.3001.net/images/20250515/1747310477_6825d78d3931044756792.png)



```
现在根据 1192275636来观察
第一步
1192275636 >>>24 = 7124位固定值
71 ^224 = 167224是上述临界值 167结果无用,后续经过了一个log2函数,发现没用用到结果,暂时当作临界值判断。
现在取出 数组1第一位 12
12 +=1 = 13    1为固定值
13 %= t 52 = 1352为固定值
现在得到13 ,然后替换列表第一位得到一个新数组2

数组2 = 接着继续浏览日志

发现数组2的操作同上,先是数组2 map后码表charAt后,得到 neSxHCmZ 拼接时间戳1747284377neSxHCmZ 进入hashFunction得到-912283305

-912283305 >>> 24 = 20124位固定值
201 ^ 224 = 41171是上述临界值
现在取出 数组2第一位 13
13 +=1 = 14 1位固定值
14 %= t 52 = 14
```

发现接下来还说相同操作,这时候我们就要考虑,什么时候或者说符合什么样的条件才会让这个循环停止,这次我们倒推一下日志。

!(https://image.3001.net/images/20250515/1747310917_6825d945ce349762990b3.png)

我们发现两处重要运算

`-525809933 >>> 24= 224`

`224 ^ n 224 = 1`

根据上面的结论可以知道,当结果与匿名函数运算结果`>>> 24` 的结果与 临界值相等时,停止运算,且码表`charAt`的最后一轮拼接时间戳即为最后的结果。

和一个关键数组

``

发现他与数组2 ``的不同是前2位,所以我们继续倒推

!(https://image.3001.net/images/20250515/1747313610_6825e3ca069914121e8ca.png)

发现当数组的第一位 等于 52 时候

即``第一位清0 即``

然后数组第二位加1即`[1,7,44,23,33,28,12,51`然后继续重复运算。

理清楚上述逻辑,交给gpt完成代码。

!(https://image.3001.net/images/20250515/1747293368_682594b82ce03645bc279.png)

## 结果

!(https://image.3001.net/images/20250515/1747311410_6825db322353afea43823.png)

滑块结果

!(https://image.3001.net/images/20250515/1747295244_68259c0cd6e56b469aec3.png)

## 代码

```javascript
/*
hashFunction 为匿名函数,希望各位小宝能够自己动手实现一下,也不枉费我写文章的目的,就不提供出来了。
*/

const timestamp = 1747291859;
const stamp = 1629880938;
function answer(timestamp, stamp) {
    const initialArray = ;
    const critical = stamp >>> 24;
    const t = 52;
    let currentArray = [...initialArray];
    const alphabet = 'abcdefghijxxxxx(脱敏)xxxxxxNOPQRSTUVWXYZ';

    while (true) {
      // 生成当前字符串
      const chars = currentArray.map(index => alphabet.charAt(index)).join('');
      const str = String(timestamp) + chars;
      const hash = hashFunction(str);
      // 检查是否满足终止条件
      if ((hash >>> 24) === critical) {
            return chars;
      }
      // 递增数组(进位逻辑)
      let i = 0;
      while (i < currentArray.length) {
            currentArray = (currentArray + 1) % t;
            if (currentArray !== 0) {
                break;
            }
            i++;
      }
    }
}
const result = answer(timestamp, stamp);
console.log(timestamp+result);
```

wzlb3344 发表于 2025-5-16 09:14

学到了,谢谢楼主

linix 发表于 2025-5-16 09:51

厉害厉害,膜拜大佬

wsck63304521 发表于 2025-5-16 10:38

膜拜大佬膜拜大佬

lufenfei147 发表于 2025-5-16 18:18

感谢大佬分享!

shanhu5235 发表于 2025-5-16 21:37

辛苦了,谢谢分享

小坏坏 发表于 2025-5-17 08:23

谢谢分享。

chathack 发表于 2025-5-17 14:31

很有想法,厉害

lyyzs7742 发表于 2025-5-18 00:29

感谢分享

gongjunwei 发表于 2025-5-26 10:43

有简易的工具吗
页: [1] 2
查看完整版本: Tk-验证码hashcash之answer参数详解