首页
社区
课程
招聘
[原创]小米APP登录接口env、envkey、sign、hash算法
发表于: 2021-3-7 16:30 19477

[原创]小米APP登录接口env、envkey、sign、hash算法

2021-3-7 16:30
19477

最近大家都在抢茅台酒,我也来凑凑热闹,我也好想抢到一瓶~,上次也发过一个酒仙APP的分析帖子了 上次分析贴;这次正好又碰到了一个小米有品的登录接口,碰到有好几个加密的数据,这次我们继续本着技术学习的方向去研究一下。


这就是登录时发送的登录数据接口传递的参数,其中我们看到加密数据包括:HASH、envKey、env、_sign 这四项,我们逐一进行查找

首先第一步就是接口的定位,我们可以通过搜索接口名称(serviceLoginAuth2)或者搜索它传递的参数名称进行查找,这得看搜索的结果来决定用哪种好了; 这里我直接搜索名称serviceLoginAuth2

这里一共3条结果,明显最后1条并不是,因为多了几个字符,然而前面2条是一样的,我们随便点进去,然后进行引用跟踪

我们直接选择最后一条,进去查看

这条函数简直是非常的清晰,我们可以看到几乎这里做的操作跟接口传的参数都差不多都有,这里我把代码复制到vscode里面进行重命名修改,以便方便阅读。

接下来就要证实它是不是确实调用这个接口,我们有请frida登场(frida:“低调,低调”)。接下来编写hook代码~

因为这个APP正好使用了阿里的json,所以我就直接调用它的方法来格式化输出整个类的属性,就非常方便!后面我们开启HOOK输入账号密码登录一下~

成功拿到数据了,证明该方法确实被触发,我们整理一下代码:

这里我们直接把刚刚复制的代码全部重命名,然后设置固定的值,这样方便我们进行阅读。

这里我们慢慢的进行按需分析,我们目前就想知道HASH、envKey、env、_sign这四项参数,首先第一项HASH,我们看到VSCODE上的第17行代码

经过手动MD5签名对比了一下确实如此,由此得知HASH = 大写MD5(密码)。
接下来我们发现代码中并未出现envKey,env以及_sign。

至于_sign我也不想卖关子了。。其实我也是经过各种查找无果,发现居然这是服务器返回的包里面包含的,天呐~


所以我们得知经过了几小时的不懈努力的无脑搜关键字,最终知道_sign是在服务器的接口内返回,由此得知

HASH = MD5(密码)
_SIGN = 服务器接口返回

最终我们还需要查找env以及envKey,我们从当前的方法看不出有直接赋值,但是我们发现。它是通过新建easyPut一个类,把参数都传进去;所以我们发现它还把easyPut传到了一个addEnvToParams方法里面(第23行代码)

所以我们只能切换到jadx界面,跟进addEnvToParams看看在作何操作~

我们发现了一个醒目的字眼,envKey,它也同样是调用easyPutOpt方法进行插入,我们看到在它上面也进行了一次插入,名字是个变量,我们跟进去看看

终于,我们看到了env和envkey是这样赋值的,但这并没有结束,因为我们知道,它传入了一个string数组进去处理。 所以即使我们知道了env和envKey的加密方法,但还需要知道传进去的字符串数组,也就是hashedEnvFactors 是从何而赋值的。

我们暂且不管hashedEnvFactors从何而来,先看看env的算法

我们看到,它是调用PassportEnvEncryptUtils.encrypt(strArr);直接返回的encrypt,并且直接取出encrypt里的content(对应env)和encryptedKey(对应envKey)得到的结果。所以直接跟进encrypt方法里面查看

第一层跟进

第二层跟进

发现一个常量,去看下是什么值

发现值:"0102030405060708",继续返回跟进

最终我们看到它是进行的一个ASE算法,整个结果其实也是相当简单的了,我们把代码抠出来VSCODE分析下。

首先参数1则是我们第一层看到它,他是把hashedEnvFactors 数组用:分割连接起来了,所以我们写死他。
而参数2就是第三层看到的DEFAULT_IV,我们也写死

所以它的传参应该是这样的;接着我们可以看到,它new了自己封装的一个ASE的EncryptResultWithIv类,然后赋值参数2给iv,估计就是加密的KEY。

关键在于它又调用了这行代码,generateSymmetricKey(),我们进去看一下~

好像也并不是很关键0.0,就是随机初始化了一个ASE然后返回它的key。那么我们继续阅读刚刚的代码,因为它连接的有一点长,我们把他格式处理一下。


因为这里的计算感觉有点绕,前3行代码图片已经打出注释了,我们看下第接下来一行就是赋值跟env结果的关键代码,它又跑去执行了一个aesEncrypt方法,并且我们看到传入的正是hashedEnvFactors以及随机证书的KEY以及刚刚看到的0102030405060708的IV进行调用的,所以我们还需要跟进aesEncrypt查看一下都是怎么处理的。

这里我们看到它以随机生成的证书作为构造类定义,然后在传入要加密的
hashedEnvFactors以及IV,我们在进去看看。

这里跟进去后发现就是调用encryptWithIv进行ASE签名的,然后在转成BASE64完成env的加密!!

至此我们已经完成了4项参数的算法~
HASH = 大写MD5(密码)
_SIGN = 来自服务器返回
ENVKEY = BASE64编码(RSA(一个随机证书,公共密钥))
ENV = BASE64编码(ASE(hashedEnvFactors,"0102030405060708"))

这些完全可以直接扣掉它自己定义的ASE类来放到JAVA独立调用的,就不再作演示,由于文章挺长了,下次在讲一讲hashedEnvFactors这10几个字符串的定义来源

{
  "returnStsUrl": false,
  "password": "11112222",
  "deviceId": "g7bqCchccIn5oue0",
  "captCode": "",
  "userId": "1376764646",
  "serviceId": "miotstore",
  "hashedEnvFactors": [
    "UzqtqM",
    "FtRqzw",
    "EsfzyR#UzqtqM",
    "MQ==",
    "TmV4dXMgNlA=",
    "RU5VN04xNjMyMzU0Njk3OA==",
    "XqFbOh",
    "g7bqCc",
    "OdHsAk",
    "1abbBq",
    "null",
    "null",
    "",
    "",
    "",
    "TmV4dXMgNlA="
  ],
  "captIck": "",
  "needProcessNotification": true
}
{
  "returnStsUrl": false,
  "password": "11112222",
  "deviceId": "g7bqCchccIn5oue0",
  "captCode": "",
  "userId": "1376764646",
  "serviceId": "miotstore",
  "hashedEnvFactors": [
    "UzqtqM",
    "FtRqzw",
    "EsfzyR#UzqtqM",
    "MQ==",
    "TmV4dXMgNlA=",
    "RU5VN04xNjMyMzU0Njk3OA==",
    "XqFbOh",

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 10
支持
分享
最新回复 (9)
雪    币: 864
活跃值: (5124)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
优秀!
2021-3-9 09:46
0
雪    币: 18
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
大佬,小米有品的壳是咋去的啊
2021-3-9 11:07
0
雪    币: 1507
活跃值: (853)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
实用。有基础才能看懂
2021-3-9 17:00
0
雪    币: 0
活跃值: (675)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6


非常感谢,有前人铺路,节省了大量时间,已经还原出来了。

2023-2-17 17:03
0
雪    币: 0
活跃值: (675)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
小米的
signature、externalId、type=、userId
这种,我也解出来了。
2023-2-20 03:26
0
雪    币: 861
活跃值: (69)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
@樟树,请联系我。15992918067
2023-2-24 17:00
0
雪    币: 197
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
学习
2023-3-2 22:09
0
游客
登录 | 注册 方可回帖
返回
//