飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 41486|回复: 78

[iOS] 极略三国-网络请求签名算法解析

    [复制链接]
  • TA的每日心情
    擦汗
    2024-4-25 16:03
  • 签到天数: 104 天

    [LV.6]常住居民II

    发表于 2020-11-26 22:07:12 | 显示全部楼层 |阅读模式
    本帖最后由 echowxsy 于 2021-1-19 22:31 编辑

    想要对一个 app 搞事情,首先就要分析它的流量情况,直接祭出 Charles 。
    Untitled.png
    我们看到所有的大部分请求都有 seed、sign、user_id、dy_udid等字段。将请求导入到 Paw  中,重试几次发现可以正常通过。
    Untitled 1.png
    从这简单的几步,我们已经知道了如下信息:
    • 每个请求都有时间戳和签名
    • 服务器只判断请求本身合不合法,不检查请求时间戳是否在允许范围内
    现在我们要从 app 入手看签名算法了。
    将砸壳后的 app 拖到 Hopper Disassembler 中,搜寻字符串。这里提示一个小技巧,从请求上分析我们知道有很多字段可以用来定位,稍稍思考一下,就知道 sign、user_id、dy_udid 的使用场景比seed 多很多,所以这里我们搜索 seed 来定位。
    Untitled 2.png
    这一搜很快啊,马上就看到了目标:
    Untitled 3.png
    查找 References 看看有哪些地方用到了:
    Untitled 4.png
    这里可以看到类似 sub_1004acbf4 等函数名,这告诉我们,代码经过了混淆,之后的分析会比较麻烦。随手点进一个看看实现,好家伙,我直接好家伙,这就是我们要找的代码。
    Untitled 5.png
    在这附近能看到 sign ,看到 sign 我就兴奋起来,当时我就念了两句诗。
    还没来分析算法呢,我就看到了一串奇怪的字符串出现在sign的附近,没错,就是 N@ZRYhAj7~),@fcz.Sntz87*pn0uu=G6。男人的第六感告诉我,这个东西不对劲,很有问题。
    6.png
    让我们来全局搜索一下这个字符串,发现有另外一个类似的字符串 79w+RI4O(khk.#]$SJZo$VJ@pP-M,)GQ。
    Untitled 7.png
    这不是我们的目标,暂时放过它,我们查看 N@ZRYhAj7~),@fcz.Sntz87*pn0uu=G6 的References。
    Untitled 8.png
    嘿,巧了,有一个 显示了类名的方法,直接点进去看看。
    Untitled 9.png
    看到了 signatureWithDictionary:secretKey 和 sign ,我说这个是签名算法的密钥,谁赞同,谁反对?
    将这段转义伪码,我们看到结构很清晰:
    [Objective-C] 纯文本查看 复制代码
    loc_100c5fe84:
        r26 = r4;
        r25 = r3;
        r20 = r0;
        if ([r4 objectForKey:r2] == 0x0) {
                objc_msgSend([NSDate date], *(&@selector(setHidesWhenStopped:) + 0xcd0));
                asm { fcvtzs     x8, d0 };
                [*(r27 + 0xfe8) stringWithFormat:r2];
                [r26 setObject:r2 forKey:r3];
        }
        r21 = @selector(setObject:forKey:);
        [r20 signatureWithDictionary:r26 secretKey:[NSString stringWithUTF8String:*0x1016282b0]];
        objc_msgSend(r26, r21);
        r26 = [r20 convertRequestToStringWithDictionary:r26];
        if (r25 != 0x0) {
                r0 = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@"]]];
                r24 = r0;
                r1 = @selector(setHTTPMethod:);
        }
        else {
                r0 = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:r24]];
                r24 = r0;
                [r0 setHTTPMethod:@"POST"];
                [r26 dataUsingEncoding:0x4];
                r1 = @selector(setHTTPBody:);
                r0 = r24;
        }
        objc_msgSend(r0, r1);
        r0 = [NSURLConnection sendSynchronousRequest:r2 returningResponse:r3 error:r4];
        if (r0 == 0x0) goto loc_100c601f0;

    其中 signatureWithDictionary: 的伪码如下:
    [Objective-C] 纯文本查看 复制代码
    /* @class DYCocoaHelper_objc */
    +(void *)signatureWithDictionary:(void *)arg2 secretKey:(void *)arg3 {
                    // ignore useless code
        r0 = [arg2 allKeys];
        r20 = [r0 sortedArrayUsingSelector:@selector(compare:)];
        r23 = [NSMutableArray arrayWithCapacity:[r0 count]];
        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:);
                                [var_128 urlEncodedString:[var_130 objectForKey:*(var_118 + r21 * 0x8)]];
                                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 = [var_128 signatureWithString:[r23 componentsJoinedByString:@"&"] secretKey:var_148];
        if (**___stack_chk_guard != var_60) {
                r0 = __stack_chk_fail();
        }
        return r0;
    }

    signatureWithString: 伪码如下
    [Objective-C] 纯文本查看 复制代码
    /* @class DYCocoaHelper_objc */
    +(void *)signatureWithString:(void *)arg2 secretKey:(void *)arg3 {
        [NSString stringWithFormat:@"%@%@"];
        r0 = [self md5:r2];
        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 写了一个实现: sgk-test.zip (1.16 KB, 下载次数: 8)
    分析暂时告一段落,传统逆向讲究点到为止。被我们放过的目标 79w+RI4O(khk.#]$SJZo$VJ@pP-M,)GQ ,是 Response 的签名算法。同样的 md5 加盐,对结构体的处理和 Request 一样。这里就留给大家自己分析啦。


    评分

    参与人数 5威望 +9 飘云币 +8 收起 理由
    yp124202453 + 1 + 1 万水千山总是情,给个评分最贴心!
    pwn3rzs + 1 + 1
    AlvinGYS + 1 PYG有你更精彩!
    tree_fly + 5 + 5 原创精品 感谢分享!
    tiantian89 + 1 + 1 PYG有你更精彩!

    查看全部评分

    本帖被以下淘专辑推荐:

    PYG19周年生日快乐!
  • TA的每日心情
    难过
    2024-4-22 14:49
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    发表于 2020-11-27 15:41:51 | 显示全部楼层
    好文,感谢分享
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    18 小时前
  • 签到天数: 1572 天

    [LV.Master]伴坛终老

    发表于 2020-11-28 09:43:02 | 显示全部楼层
    学习了 感谢分享
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    前天 10:18
  • 签到天数: 1344 天

    [LV.10]以坛为家III

    发表于 2020-11-28 11:20:33 | 显示全部楼层
    good 非常的棒&#128077;
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-3-17 22:44
  • 签到天数: 132 天

    [LV.7]常住居民III

    发表于 2020-11-28 14:04:21 | 显示全部楼层
    请接受我的膝盖~ ,好家伙,直接好家伙。好文!
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    5 天前
  • 签到天数: 683 天

    [LV.9]以坛为家II

    发表于 2020-12-2 14:04:21 | 显示全部楼层
    情景中有美女用绳子套鳄鱼,箭射梅花鹿,游戏真正的名字叫什么,
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2024-7-18 08:23
  • 签到天数: 109 天

    [LV.6]常住居民II

    发表于 2020-12-4 08:49:20 | 显示全部楼层
    这个 额 怎么说呢 ··得这样弄 那样弄
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    5 天前
  • 签到天数: 683 天

    [LV.9]以坛为家II

    发表于 2020-12-4 12:00:27 | 显示全部楼层

    谢谢楼主分享
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2022-4-24 09:11
  • 签到天数: 36 天

    [LV.5]常住居民I

    发表于 2020-12-15 22:48:08 | 显示全部楼层
    非常感谢楼主分享
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2021-1-3 16:09
  • 签到天数: 16 天

    [LV.4]偶尔看看III

    发表于 2021-1-3 17:49:29 | 显示全部楼层
    感谢分享。分析的流程很清晰
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表