首页
社区
课程
招聘
[原创]某免费小说APP sign参数分析与实现
发表于: 2022-12-8 10:53 25031

[原创]某免费小说APP sign参数分析与实现

2022-12-8 10:53
25031

闲来无事,随便下载了个免费小说软件,对其中的登录时的参数进行了分析

在登录发送验证码时使用Charles抓包

根据关键词在Java层搜索
图片描述

查找用例,定位到函数

图片描述

可以看到将一些参数存入ArrayMap中传入j.addSign()函数中,这里的addSign是我自己手动修改的名字

传入的Key值对照数据包中的参数也都能够对的上

图片描述

继续跟进addSign函数中

图片描述
又添加了一个时间戳键值对后,经过getSortedParamStr后传给hash得到sign

图片描述

getSortedParamStr将键值对按键进行排序后,转成字符串返回。不同键值对之间用&连接,键与值之间用=连接

比如,对如下键值对进行转换

Securityhash函数调用了JNISecurityhash2函数,参数有SignatureSHA1WithRSAKeyFactoryRSA,字符串转成的字节

图片描述

JNISecurity里的hash2是一个native函数,可以看到类里加载了UiControl库,大概率就在libUiControl.so

图片描述

解压后在lib文件夹里找到libUiControl.so

先在Function搜索hash2,不出所料没有结果,所以这是动态注册的函数

图片描述

那么应该分析JNI_OnLoad函数

图片描述

GetEnv得知参数v26类型为JNIEnv*,另外看下面有调用固定常数偏移函数大概率都是JNIEnv*参数,重设类型后就能分析出JNI函数了

图片描述

往下分析,在sub_7A5A8函数中找到了调用了RegisterNatives函数,可能是我们要找的hash函数

图片描述

图片描述

RegisterNatives的定义可知,

第一个参数clazz是注册的函数所在的类

第二个参数methodsJNINativeMethod类型,里面包含了函数名、函数签名以及函数指针

不过这里的各个参数当前都是空的数据,需要先经过sub_78F54解密才能得到原本的数据。第二个参数是我们的结果

图片描述

sub_78F54函数的逻辑也比较简单,主要运算的部分也就只有中间这一句而已

图片描述

v9是第一个参数,结合具体值分析可以得到是取三位一组然后转成十进制数,和v12异或

v12是字符串"8080"

后面的v8 - (v10 & 0xFFFFFFFC)其实就相当于v8&3,只取了最后两位

可以得到一个简单的解密脚本

输出结果发现果然是我们想要找到的hash2函数

图片描述

重命名参数后,可以知道sub_877EChash函数的函数指针

sub_87324hash2函数的函数指针

图片描述

另外有个坑点,一开始分析的是arm64的so文件,可以看到反编译的结果不是很好分析,头脑有点迷糊没有对上哪个函数指针对应哪个函数

后面换了32位的so文件才发现反编译效果好的太多了,不仅methods数组各个参数排列的很整齐,甚至hash2函数名的符号表都还在:cry:

图片描述

让我想到了之前打的一个比赛中,两个不同架构的so文件,arm的反编译有问题,反而x86反编译的结果非常清晰

点进来同样发现调用了指针加偏移的函数,估计也是JNI函数,不过还是跟进分析一下sub_78EEC函数

图片描述

sub_78EEC也是这样的调用函数,惯性的改类型成JNIEnv*发现得到的是FindClass函数,显然不太对

图片描述

FindClass显然得不到JNIEnv*类型的变量

图片描述

交叉引用一下,发现在JNI_OnLoad里调用了这个变量,才发现原来是JavaVM*类型

图片描述

改成JavaVM*就得到了GetEnv函数

图片描述

sub_87324里的各个env变量修正后,JNI函数就都能正常显示了,

将其中的几个字符串写在了旁边的注释中

函数逻辑也比较清晰了

图片描述

比较常见的JNI层调用Java算法的过程

翻译成Java代码,一个比较常规的签名算法

typehash2的第一个参数,传入的是固定的2,因此这里使用的私钥是off_3BFC50+1=unk_2F5477

图片描述

长度为0x279

图片描述

hash2签名后再Base64一下即为sign参数值

使用python还原算法后验证,同时实现了发包请求

可以看到计算得到的sign值和抓包得到的sign值是一致的

图片描述

同时返回包也是成功

图片描述

手机上也是成功收到了短信

同样地该APP在登陆时的sign参数也是类似的逻辑

图片描述

图片描述

将之前的代码添加了登录的功能,实现了从获取验证码到登录的过程

图片描述

 
 
 
 
 
 
 
 
 
 
 
arraymap = {
    "flag": "1",
    "channelId": "1240202",
    "imei": "____7548",
    "device": "Nexus 5X",
}
 
channelId=1240202&device=Nxus 5X&flag=1&imei=___7548
arraymap = {
    "flag": "1",
    "channelId": "1240202",
    "imei": "____7548",
    "device": "Nexus 5X",
}
 
channelId=1240202&device=Nxus 5X&flag=1&imei=___7548
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,jint nMethods)
typedef struct {
    const char* name;
    const char* signature;
    void* fnPtr;
} JNINativeMethod;
jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,jint nMethods)
typedef struct {
    const char* name;
    const char* signature;
    void* fnPtr;
} JNINativeMethod;
 
 
 
 
 
 
 
def decrypt(start,size=0):
    if size == 0:
        size = get_item_end(start)-start
    data = get_bytes(start,size)
    key = [56,48]
    out = []
    for i in range(0,len(data),3):
        tmp  = data[i:i+3].decode()
        if tmp.startswith('\x00'):
            return out
        t = int(tmp)
        tmp = t^key[i//3%2]
        out.append(chr(tmp))
        s = ''.join(out)
    return s
addrs = [0x2F5008,0x2F5084,0x2F5130,0x2F513D,0x2F51EC]
for i in range(len(addrs)):
    if i !=len(addrs)-1:
        size = addrs[i+1]-addrs[i]
    else:
        size = 0x10
 
    s = decrypt(addrs[i])
    print(hex(addrs[i]),''.join(s))
def decrypt(start,size=0):
    if size == 0:
        size = get_item_end(start)-start
    data = get_bytes(start,size)
    key = [56,48]
    out = []
    for i in range(0,len(data),3):
        tmp  = data[i:i+3].decode()
        if tmp.startswith('\x00'):
            return out
        t = int(tmp)
        tmp = t^key[i//3%2]
        out.append(chr(tmp))
        s = ''.join(out)
    return s
addrs = [0x2F5008,0x2F5084,0x2F5130,0x2F513D,0x2F51EC]
for i in range(len(addrs)):

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2022-12-8 18:46 被si1enceZ编辑 ,原因:
收藏
免费 7
支持
分享
最新回复 (1)
雪    币: 482
活跃值: (1007)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
给个样本
2023-2-10 16:43
0
游客
登录 | 注册 方可回帖
返回
//