android 逆向 19 / 38
- app OAuth api_sign 分析
- app sig 参数加密分析 unidbg 模拟黑盒调用
- app sign so 加密参数破解|unidbg
- sgmain x-sign 分析 - unidbg
- androidAsync fridaManager sgmain 70102 rpc 远程调用
- app edata 参数 so aes 加密分析破解|unidbg
- frida 加载 sekiro dex 文件 实现与服务端交互
- frida sekiro 实现 sgmain 70102 远程 rpc 调用
- xposed sekiro hook 获取 wx 万能 key
- unidbg console debugger 使用
- unidbg hook inline hook 使用
- app 公众号文章列表 so 加解密算法分析还原 | 简单分析
- app 公众号文章列表 so 加解密算法分析还原 | 加密 rsa base64 分析
- app 公众号文章列表 so 加解密算法分析还原 | 加密 zip aes 分析
- app 公众号文章列表 so 加解密算法分析还原 | response 内容解密分析
- app sign so 加密算法分析还原|简单分析
- app sign so 加密算法分析还原|so 算法分析
- app sign so 加密算法分析还原|so sub_126AC 函数算法还原
- app so signkeyV1 参数分析
- ida 动态调试 android so 文件|基础入门环境搭建
- app so newSign 参数分析破解
- app tzRgz52a 参数分析破解
- app sign-v2 签名算法 aes 加解密分析
- app so 加密参数分析|protocbuf 分析
- mxtakatak android app 加解密分析
- android app so 加密算法分析破解|mtgsig unidbg
- android app so 加密算法分析破解|siua unidbg
- android app nsign so 加密算法分析
- android app sig 参数 so 加密逻辑逆向分析
- android app so sig 加密参数 unidbg
- 狗狗音乐登陆协议加密参数逆向分析
- android sign so 加密参数分析|unidbg
- android app X-SS-QUERIES 参数分析
- unidbg android app xgorgon 加密参数 leviathan
- sgmain 6.4.x xsign 加密算法分析研究
- sgmain 6.4.x xminiwua 加密算法分析研究
- 某 app mas 算法分析还原 cms so
- 某东登陆协议 tlv 逻辑分析
前言
某东到家 app signKeyv1 参数分析,版本 8.14.0
charles 抓包
就是 djencrypt
这个参数,是一个加密串,分析一下
java 层分析
全局搜索定位到这个函数 base.net.volley.BaseStringRequest.getParams
,跟进 DaojiaAesUtil.encrypt
看看
在跟进 AesCbcCrypto.encrypt
这个函数
里面写的还是比较清楚的,加密方式是 AES/CBC/PKCS5Padding
使用 cyberchef
解密试试
解密成功,主要是分析这个 signKeyV1
参数,看长度是 64
,猜测是 sha256
加密,分析一下
全局搜索定位到这里,调用 k2 native
函数获取的,在 libjdpdj.so
文件里
打开 so
进入 JNI_OnLoad
函数,这里是动态注册的,点击 off_117004
这里看到,函数注册列表,点进 gk2
函数
前面是一些数据处理,下面有个 j_hmac_sha256
函数,可以确实是用的 hmac sha256
算法
这里的符号都没去掉,init update final
函数都能看到,这里应该是标准的算法,因为使用的是 openssl
库,先写个 frida hook
一下
frida hook
function hook() {
var javaString = Java.use('java.lang.String');
var zCls = Java.use('jd.net.z');
zCls.k2.implementation = function (a) {
console.log('zCls.k2.a: ', javaString.$new(a));
var res = this.k2(a);
console.log('zCls.k2.res: ', res);
return res;
}
}
这里 hook java k2
函数的输入输出
function hookSo1() {
var hmac_sha256 = Module.findExportByName('libjdpdj.so', 'hmac_sha256')
var HMAC_CTX_init = Module.findExportByName('libjdpdj.so', 'HMAC_CTX_init')
var HMAC_Update = Module.findExportByName('libjdpdj.so', 'HMAC_Update')
var HMAC_Init_ex = Module.findExportByName('libjdpdj.so', 'HMAC_Init_ex')
Interceptor.attach(hmac_sha256, {
onEnter: function (args) {
console.log('hmac_sha256 参数 1: ', hexdump(args[0]));
console.log('hmac_sha256 参数 2: ', hexdump(args[1]));
console.log('hmac_sha256 参数 3: ', hexdump(args[2]));
console.log('hmac_sha256 参数 4: ', hexdump(args[3]));
},
onLeave: function (retValue) {
}
})
Interceptor.attach(HMAC_CTX_init, {
onEnter: function (args) {
console.log('HMAC_CTX_init 参数 1: ', hexdump(args[0]));
},
onLeave: function (retValue) {
}
})
Interceptor.attach(HMAC_Update, {
onEnter: function (args) {
console.log('HMAC_Update 参数 1: ', hexdump(args[0]));
console.log('HMAC_Update 参数 2: ', hexdump(args[1], {length: 1200}));
console.log('HMAC_Update 参数 3: ', hexdump(args[2]));
},
onLeave: function (retValue) {
}
})
Interceptor.attach(HMAC_Init_ex, {
onEnter: function (args) {
console.log('HMAC_Init_ex 参数 1: ', hexdump(args[0]));
console.log('HMAC_Init_ex 参数 2: ', hexdump(args[1]));
console.log('HMAC_Init_ex 参数 3: ', hexdump(args[2]));
console.log('HMAC_Init_ex 参数 4: ', hexdump(args[3]));
console.log('HMAC_Init_ex 参数 5: ', hexdump(args[4]));
},
onLeave: function (retValue) {
}
})
}
这里在 hook
一些 so
函数,hamc
会有个 key
一般在 init
的时候初始化
function main() {
Java.perform(function () {
hook();
hookSo1();
})
}
启动脚本 frida -UF -l hook.js | tee hook.log
k2
函数的输入是请求参数
HMAC_Init_ex so
函数的参数二,长度 32
猜测是 hamc key
HMAC_Update
函数是请求参数
最后的加密结果 ae07cde50402ef91660dea93dc196f7f82e7bc04322baf4022dc2879434f3fae
是这个,来验证一下
使用 cyberchef
加密,结果一样,正是 hmac sha256
Tips: 下面在使用 unidbg 跑起来,毕竟多掌握一些工具总有用处
unidbg
package com.xiayu.jingdongdaojia;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.LibraryResolver;
import com.github.unidbg.Module;
import com.github.unidbg.debugger.Debugger;
import com.github.unidbg.debugger.DebuggerType;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.*;
import com.github.unidbg.linux.android.dvm.array.ByteArray;
import com.github.unidbg.memory.Memory;
import java.io.File;
import java.io.IOException;
public class SignKeyV1Test extends AbstractJni {
private final AndroidEmulator emulator;
private final Module module;
private final VM vm;
public String apkPath = "apk path";
public String soPath = "so path";
private static LibraryResolver createLibraryResolver() {
return new AndroidResolver(23);
}
private static AndroidEmulator createARMEmulator() {
return AndroidEmulatorBuilder.for32Bit().build();
}
public SignKeyV1Test() {
emulator = createARMEmulator();
final Memory memory = emulator.getMemory();
memory.setLibraryResolver(createLibraryResolver());
vm = emulator.createDalvikVM(new File(apkPath));
vm.setVerbose(true);
DalvikModule dm = vm.loadLibrary(new File(soPath), false);
vm.setJni(this);
dm.callJNI_OnLoad(emulator);
module = dm.getModule();
}
public void callGetSignKeyV1() {
DvmClass zClass = vm.resolveClass("jd/net/z");
DvmObject<?> strRc = zClass.callStaticJniMethodObject(
emulator,
"k2([B)Ljava/lang/String;",
new ByteArray(vm, "参数".getBytes())
);
System.out.println("callGetSignKeyV1: " + strRc.getValue());
}
public static void main(String[] args) throws IOException {
SignKeyV1Test signKeyV1 = new SignKeyV1Test();
signKeyV1.callGetSignKeyV1();
signKeyV1.destroy();
}
private void destroy() throws IOException {
emulator.close();
}
}
代码写完跑起来
这报错了,缺少函数 jd/utils/StatisticsReportUtil->getSign()Ljava/lang/String;
调用 apk
的 java
代码
点进来看一下,打开逻辑是获取 apk
的签名之类的,这里的依赖比较多,不是很好补,一般签名啥的都是固定,直接 frida call
一下,获取返回值
function callGetSign() {
var StatisticsReportUtil = Java.use('jd.utils.StatisticsReportUtil');
var res = StatisticsReportUtil.getSign();
console.log(res)
}
运行成功,获取返回值
unidbg
补一下,直接写死字符串
再次运行结果出来了,结果相同
Tips: 后面在打算学习学习 ida gdb 动态调试,暂时留空
IDA 动态调试
// TODO
GDB 动态调试
// TODO
嗄嗄
2021-11-23patch frida-server 0002-frida-server.patch报Hunk #1 FAILED是什么情况呢?网上找半天没找到结果,本机mac
会爬山的小脑虎
2021-11-23@嗄嗄 你这个看不出来啥问题,方便的话可以加微信讨论哦
123
2021-11-14老哥,这个app检测frida啊
会爬山的小脑虎
2021-11-15@123 对,用葫芦娃 frida 可以过检测
123
2021-11-16@会爬山的小脑虎 1
会爬山的小脑虎
2021-11-16@123 巨佬牛逼