echowxsy 发表于 2020-11-26 22:45

极略三国请求签名算法解析

本帖最后由 echowxsy 于 2021-1-19 21:43 编辑

# 极略三国请求签名算法分析

想要对一个 app 搞事情,首先就要分析它的流量情况,直接祭出 Charles 。



我们看到~~所有的~~大部分请求都有 `seed`、`sign`、`user_id`、`dy_udid`等字段。
将请求导入到 Paw中,重试几次发现可以正常通过。



从这简单的几步,我们已经知道了如下信息:

- 每个请求都有时间戳和签名
- 服务器只判断请求本身合不合法,不检查请求时间戳是否在允许范围内

现在我们要从 app 入手看签名算法了。

将砸壳后的 app 拖到 Hopper Disassembler 中,搜寻字符串。这里提示一个小技巧,从请求上分析我们知道有很多字段可以用来定位,稍稍思考一下,就知道`sign`、`user_id`、`dy_udid`的使用场景比`seed`多很多,所以这里我们搜索`seed`来定位。



这一搜很快啊,马上就看到了目标:



查找 `References` 看看有哪些地方用到了:



这里可以看到类似 `sub_1004acbf4`等函数名,这告诉我们,代码经过了混淆,之后的分析会比较麻烦。随手点进一个看看实现,好家伙,我直接好家伙,这就是我们要找的代码。



在这附近能看到`sign`,看到`sign`我就兴奋起来,当时我就念了两句诗。

还没来分析算法呢,我就看到了一串奇怪的字符串出现在`sign`的附近,没错,就是`N@ZRYhAj7~),@fcz.Sntz87*pn0uu=G6`。男人的第六感告诉我,这个东西不对劲,很有问题。



让我们来全局搜索一下这个字符串,发现有另外一个类似的字符串`79w+RI4O(khk.#]$SJZo$VJ@pP-M,)GQ`。



这不是我们的目标,暂时放过它,我们查看`N@ZRYhAj7~),@fcz.Sntz87*pn0uu=G6` 的`References`。



嘿,巧了,有一个 显示了类名的方法,直接点进去看看。



看到了`signatureWithDictionary:secretKey`和`sign`,我说这个是签名算法的密钥,谁赞同,谁反对?

将这段转义伪码,我们看到结构很清晰:

```objectivec
loc_100c5fe84:
    r26 = r4;
    r25 = r3;
    r20 = r0;
    if ( == 0x0) {
            objc_msgSend(, *(&@selector(setHidesWhenStopped:) + 0xcd0));
            asm { fcvtzs   x8, d0 };
            [*(r27 + 0xfe8) stringWithFormat:r2];
            ;
    }
    r21 = @selector(setObject:forKey:);
    ];
    objc_msgSend(r26, r21);
    r26 = ;
    if (r25 != 0x0) {
            r0 = ]];
            r24 = r0;
            r1 = @selector(setHTTPMethod:);
    }
    else {
            r0 = ];
            r24 = r0;
            ;
            ;
            r1 = @selector(setHTTPBody:);
            r0 = r24;
    }
    objc_msgSend(r0, r1);
    r0 = ;
    if (r0 == 0x0) goto loc_100c601f0;
```

其中`signatureWithDictionary:`的伪码如下:

```objectivec
/* @Class DYCocoaHelper_objc */
+(void *)signatureWithDictionary:(void *)arg2 secretKey:(void *)arg3 {
                // ignore useless code
    r0 = ;
    r20 = ;
    r23 = ];
    var_110 = q0;
    r1 = @selector(countByEnumeratingWithState:objects:count:);
    var_140 = r1;
    var_138 = r20;
    r0 = objc_msgSend(r20, r1);
    if (r0 != 0x0) {
            r25 = r0;
            r20 = *var_110;
            do {
                  r21 = 0x0;
                  do {
                            if (*var_110 != r20) {
                                    objc_enumerationMutation(var_138);
                            }
                            r19 = @selector(stringWithFormat:);
                            ];
                            objc_msgSend(@class(NSString), r19);
                            objc_msgSend(r23, r24);
                            r21 = r21 + 0x1;
                  } while (r21 < r25);
                  r0 = objc_msgSend(var_138, var_140);
                  r25 = r0;
            } while (r0 != 0x0);
    }
    var_60 = **___stack_chk_guard;
    r0 = secretKey:var_148];
    if (**___stack_chk_guard != var_60) {
            r0 = __stack_chk_fail();
    }
    return r0;
}
```

`signatureWithString:`伪码如下

```objectivec
/* @class DYCocoaHelper_objc */
+(void *)signatureWithString:(void *)arg2 secretKey:(void *)arg3 {
    ;
    r0 = ;
    return r0;
}
```

下面就由我来给大家翻译翻译,什么叫签名算法:

- 首先有个等待加密的请求体,是个字典对象,我们暂时叫它`reqBody`
- 往`reqBody`里面塞一个时间戳`seed`,由当前时间格式化输出
- 用`signatureWithDictionary:`得到`sign`,并且把`sign`也塞到`reqBody`
    - 拿到`reqBody`的所有`key`
    - 将`key`按字典顺序排序
    - 用`urlEncodedString`输出`string`
    - 用`signatureWithString:`获取`sign`
      - 把 `string`和`N@ZRYhAj7~),@fcz.Sntz87*pn0uu=G6`做字符串合并
      - md5 加密
- 把`reqBody`转化为`String`,并发射出去

随手用 Node.js 写了一个实现:


分析暂时告一段落,传统逆向讲究点到为止。被我们放过的目标`79w+RI4O(khk.#]$SJZo$VJ@pP-M,)GQ`,是 Response 的签名算法。同样的 md5 加盐,对结构体的处理和 Request 一样。这里就留给大家自己分析啦。

拉玛西亚 发表于 2020-12-7 23:30

echowxsy 发表于 2020-11-26 23:06
通过自建服务器的方式可以直接改掉请求返回。
这个我修改包的一个示范:

貌似现在的版本虽然可以单机了,但是某个人物没有技能

吾爱po解 发表于 2022-1-6 19:56

分析的很厉害,支持大佬!{:1_921:}
另外大佬能否出一期分析 userdefault.xml 的文章,我看他的请求是:http://api.sanguoq.com:9090/sanguokill/app/downloadBackupFile.action,下载后是一个压缩文件,解压后是.UserDefault.xml文件,但都是加密的

拉玛西亚 发表于 2020-11-26 23:02

它一直都是联网的,这个联网验证怎么去掉

echowxsy 发表于 2020-11-26 23:06

拉玛西亚 发表于 2020-11-26 23:02
它一直都是联网的,这个联网验证怎么去掉

通过自建服务器的方式可以直接改掉请求返回。
这个我修改包的一个示范:

能动者与受动者 发表于 2020-11-26 23:20

这游戏立绘和语音和台词做的还是很好的,可惜大娱不管了

liuzhen86472796 发表于 2020-11-26 23:32

这游戏做的挺好

longling 发表于 2020-11-26 23:48

一起学习

crazysheep118 发表于 2020-11-27 00:15

一起学习啊

原创丶小生 发表于 2020-11-27 08:17

虽然不知道是什么,看看吧

okgjkk 发表于 2020-11-27 09:02

厉害了一起学习学习

jimoguying2020 发表于 2020-11-27 09:03

苹果的界面ui更新了,android还不更新
页: [1] 2 3 4 5 6 7 8
查看完整版本: 极略三国请求签名算法解析