抓包后需要对params,pk,t1,t2,t3,key这几个参数进行分析

搜索字段关键词后得到t1(token) t2(machineIdCode) clienttime_ms这三个参数是在com.kugou.common.useraccount.entity.q中生成的

t3是在com.kugou.framework.specialradio.d.b.a中生成的

dfid plat pk username support_third support_multi support_verify key dev gitversion params是在com.kugou.common.useraccount.b.ad$b.rW_中生成的

t1
t1是调用getToken生成的,此函数最后会调用一个native函数com.kugou.common.player.kugouplayer.j._d

对应的是libj.so在JNI_Onload中调用register_kugou_player_mediautilsextra注册的,对应的函数就是cc::d(_JNIEnv *,_jobject *,_jobject *)

cc::d会调用f4函数,并且f4传入的参数v5是一个std::string类型,随后调用std::string::c_str()并传入NewStringUTF返回一个jstring,对应的就是t1的值

参照cc::d调用std::string::c_str()的方式用frida实现
function std_string_c_str(std_string){
var ret
if ((std_string.readU64() & 1) != 0 ){
ret = std_string.add(8 * 2).readPointer()
}
else{
ret = std_string.add(1)
}
return ret
}
经过对f4的分析后对各个关键函数进行hook和打印,最后的t1生成过程如下。
- 尝试打开
/data/user/0/com.kugou.android/files/test.txt文件失败 - 调用
f5返回时间戳 - 调用
h15并将"|" + 时间戳作为参数传入 - 调用
h14进行aes加密,input为"|" + 时间戳,key为fd387891254e6cedc4019ca0061ea6d9,iv为c4019ca0061ea6d9,输出为aes加密 f4的返回值就是aes加密的结果,也就是t1的值

验证一下算法

t2
t2也是调用native函数生成的,对应的是cc::e(_JNIEnv *,_jobject *,_jobject *),同样对各个关键函数进行hook,t2的生成过程如下。
- 调用
getAndroidId返回androidId并进行md5 - 调用
getSafeDeviceId返回SafeDeviceId并进行md5 - 获取
android.os.Build.MODEL - 获取时间戳
- 调用
h14进行aes加密,key为ce1e88d78dff2132dbfbb91af0ea9ca7,iv为dbfbb91af0ea9ca7,输入为之前获取信息拼接的结果,输出为aes加密结果也就是t2的值

验证一下算法

t3
t3就是将输入的一些值进行base64

key
key是通过传入一个字符串进行rsa加密得到的

hook 整个生成过程如下,其会将appid,appkey,versionCode和时间戳进行连接后进行md5,md5结果就是key的值

pk
pk是将一个字符串进行rsa加密

hook 整个生成过程如下,待加密数据是一个时间戳和一个8个字节的key的js的格式,rsa公钥是MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIAG7QOELSYoIJvTFJhMpe1s/gbjDJX51HBNnEl5HXqTW6lQ7LC8jr9fWZTwusknp+sVGzwd40MwP6U5yDE27M/X1+UR4tvOGOqp94TJtQ1EPnWGWXngpeIW5GxoQGao1rmYWAu6oi1z9XkChrsUdC6DJE5E221wf/4WLFxwAtRQIDAQAB,加密结果就是pk的值

params
params是通过AES加密生成的

hook 整个生成过程如下,待加密数据是username,clienttime_ms和pwd的js的格式,aes的key是pk.key的md5值,iv是pk.key的md5值得后16个字节,最后得加密结果就是params的值
