前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Crack App | 某赢+ 二手车 App 登录参数加密逻辑分析

Crack App | 某赢+ 二手车 App 登录参数加密逻辑分析

作者头像
咸鱼学Python
发布2022-12-10 16:13:20
3430
发布2022-12-10 16:13:20
举报
文章被收录于专栏:咸鱼学Python咸鱼学Python

包名

v1.9.67.1

6L2m5pm66LWiKw==

加固

经过查壳,没有发现加固

抓包分析

打开 app ,进入登录界面

随便输入账号密码,点击登录,提示版本过低,虽然提示这个但是并不妨碍我们抓包

打开小黄鸟,重新登录一下,可以看到下面的结果包

请求提交的参数如下

除了 username 之外这里还对 password 加密了

目前未知的参数有 udid、_sign、pwd 这三个参数

加密参数定位与分析

使用 jadx 直接打开 apk

udid

直接搜索关键字 udid

搜索关键词类似的结果很多

可以全部都打开看看

基本都类似下面的代码

而且可以看到,所有生成 udid 的方法都使用了 encode3Des 加密了这么一大串的值getIMEI(context) + "|" + System.nanoTime() + "|" + SPUtils.getDeviceId()

找到离加密最近的地方才有机会看到真相

所以直接 hook encode3Des这个加密的方法,先拿到加密的 str 和结果看看

代码语言:javascript
复制
function main(){
    Java.perform(function () {
        var EncryptUtil = Java.use("com.xx.xx.xx.SecurityUtil");
        EncryptUtil.encode3Des.implementation = function (arg1, arg2) {
            console.log("参数 str2 ==> " + arg2);
            var result = this.encode3Des(arg1,arg2);
            console.log("result ==> " + result);
            return result;
        }
    })
}
setImmediate(main)

然后使用命令运行 hook 脚本

代码语言:javascript
复制
frida -U -F xx.xx.xx-l hook.js 

hook 结果如下

多次尝试下,

参数 2 的第一部分是getIMEI,中间部分是动态时间戳,第三部分是getDeviceId

只有中间部分是动态的

接下来可以看看 encode3Des 的加密部分了

这里可以看到加密使用的是 CBC 加密模式,然后这里的 iv 就在 class 的上方,也是一个固定值

看过之前文章的朋友应该知道,现在就缺少 key,我们就可以直接复现 udid 的加密了

这里的 key 由String desKey = AHAPIHelper.getDesKey(context);生成

跟进去可以看到加密由 native方法生成

直接 hook 一下看看

代码语言:javascript
复制
function main(){
    Java.perform(function () {
        var EncryptUtil = Java.use("com.xxx.xxx.xxx.xxx");
        EncryptUtil.encode3Des.implementation = function (arg1, arg2) {
            console.log("参数 arg2 ==> " + arg2);
            var result = this.encode3Des(arg1,arg2);
            console.log("result ==> " + result);
            return result;
        }
        
        var deskey = Java.use('com.xxx.xxx');
        deskey.getDesKey.implementation=function (arg1){
            var result = this.getDesKey(arg1);
            console.log("deskey result ==> " + result);
            return result;
        }

        var jni_check = Java.use("com.xxx.xxx.xxx.xxx");
        jni_check.checkSignimplementation = function (arg1) {
            var result = this.encode3Des(arg1);
            console.log("jni_check result ==> " + result);
            return result;
        }
    })
}
setImmediate(main)

然后再运行一下,打印结果如下

注意这里 jni_check 想要 hook 上记得使用 spawn 模式,上面的两个方法可以使用 attach 模式直接hook

以上就获取到了udid加密的 key iv mod 和加密的内容和结果,可以直接使用 Python 复现一下

代码语言:javascript
复制
import pyDes
import base64

def decrypt_response(data):
    secretkey = "这里key"[:-8]
    iv = "appapich"
    des_obj = pyDes.triple_des(key=secretkey, IV=iv, padmode=pyDes.PAD_PKCS5, mode=pyDes.CBC)
    print(base64.b64encode(des_obj.encrypt(data)).decode())


if __name__ == '__main__':
    decrypt_response("351615080737802|16936902758945|332220")

输出结果如下

和 hook 的结果一样,这样就完成了 udid 的生成

pwd

pwd 的结果是一串 32 位的字符串

同样的搜索一下,可以搜索 pwd 得到的结果有很多

但是搜索"pwd"

结果如下,而且所在位置也是请求登录的逻辑中,所以大胆猜测就是这里了

可以看到这里使用 encodeMD5

我输入的结果是12345678,通过抓包可以知道,pwd加密好的结果是25d55ad283aa400af464c76d713c07ad

直接扔到加密站里测试一下,看看结果是不是标准的 MD5 ,是的话连分析都免了

和标准的 MD5 加密结果相同

_sign

同样的搜索一下关键字

找到下面这段逻辑,是生成请求参数的逻辑

这里的 toSign 方法继续追进去

用到了上面 pwd 相同的 encodeMD5 逻辑

不过这里就需要 hook 一下 encodeMD5看一下入参

代码语言:javascript
复制
function main(){
    Java.perform(function () {
        var EncryptUtil = Java.use("com.xxx.xxx.xxx.xxx");
        EncryptUtil.encode3Des.implementation = function (arg1, arg2) {
            console.log("参数 arg2 ==> " + arg2);
            var result = this.encode3Des(arg1,arg2);
            console.log("result ==> " + result);
            return result;
        }
        
        EncryptUtil.encodeMD5.implementation = function (arg1) {
            console.log("encodeMD5 参数 arg1 ==> " + arg1);
            var result = this.encodeMD5(arg1);
            console.log("result ==> " + result);
            return result;
        }
        
        var deskey = Java.use('com.xxx.xxx.xxx');
        deskey.getDesKey.implementation=function (arg1){
            var result = this.getDesKey(arg1);
            console.log("deskey result ==> " + result);
            return result;
        }
    })
}
setImmediate(main)

hook 结果如下

对比一下抓包,大致就清楚了,这里的hash 内容就是请求提交的参数,做这个 sign 就是防止改包的

到这里我们就完成了这个 app 请求包中所有加密参数的分析

我们试着用 Python 复现一下请求流程

Python 实现请求全流程

结果和抓包是一样的

这次研究的样本是网上找的旧版样本,之后有机会试试新版的

End.

以上就是全部的内容了,咱们下次再会~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-11-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 咸鱼学Python 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 包名
  • 加固
  • 抓包分析
  • 加密参数定位与分析
    • udid
      • pwd
        • _sign
        • Python 实现请求全流程
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档