最近大家都在抢茅台酒,我也来凑凑热闹,我也好想抢到一瓶~,上次也发过一个酒仙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"
,
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!