App逆向百例|13|某段子App参数分析

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: App逆向百例|13|某段子App参数分析

观前提示:

本文章仅供学习交流,切勿用于非法通途,如有侵犯贵司请及时联系删除

样本:aHR0cHM6Ly9wYW4uYmFpZHUuY29tL3MvMXl5N2Rtd1YtcEEtS1B3WmUtN3FRNlE/cHdkPWxpbm4=

0x1 抓包&定位

打开App可以直接抓包

可以看到链接的sign以及request dataresponse data都被加密需要分析

直接jadx-gui搜索sign=结果不多

跳转过来 还不清楚传入内容是什么 查找用例看调用处

从这里可知request data是AES加密后的密文 sign是对AES加密后的密文进行一个签名

从代码可知 具体sign加密调用的是net_crypto.so的一个native方法

同样的实现AES加解密的是encodeAESdecodeAES

并且可知 在加载so的时候调用了一次初始化方法

0x2 Unidbg黑盒调用

简简单单造轮子 造完直接运行 目前还未有需要补的环境

加载完后 需要主动调用native_init方法

public void native_init() {
    ArrayList<Object> args = new ArrayList<>(3);
    args.add(vm.getJNIEnv());
    args.add(0);
    module.callFunction(emulator, 0x4a069, args.toArray());
}

开始报错 提示缺少一些环境

根据报错把缺少环境补上即可

vm.resolveClass("android/content/Context").newObject(null)

补完这个初始化方法就不报错了

接着主动调用sign方法 这里图方便 直接将第二个传入参数改为了123456 只追求算法

public String sign() {
        ArrayList<Object> args = new ArrayList<>(3);
        args.add(vm.getJNIEnv());
        args.add(0);
        String str = "http://api.xxxxx.com/account/login";
        args.add(vm.addLocalObject(new StringObject(vm, str)));
        ByteArray byteArray = new ByteArray(vm, "123456".getBytes(StandardCharsets.UTF_8));
        args.add(vm.addLocalObject(byteArray));
        Number number = module.callFunction(emulator, 0x4a28d, args.toArray());
        String result = vm.getObject(number.intValue()).getValue().toString();
        return result;
    }

运行看报错接着补环境

case "android/content/Context->getClass()Ljava/lang/Class;": {
    return dvmObject.getObjectType();
}

case "java/lang/Class->getSimpleName()Ljava/lang/String;": {
    return new StringObject(vm, "AppController");
}

case "android/content/Context->getFilesDir()Ljava/io/File;": {
    return new StringObject(vm, "/data/user/0/cn.xxxx.tieba/files");
}

case "java/lang/String->getAbsolutePath()Ljava/lang/String;": {
    return new StringObject(vm, "/data/user/0/cn.xxxx.tieba/files");
}

case "android/os/Debug->isDebuggerConnected()Z": {
  return false;
}

case "android/os/Process->myPid()I": {
    return emulator.getPid();
}

补到这里 成功出值 可以为所欲为了

算法分析

sign

根据Unidbg输出的动态注册偏移跳转到0x4a28d

看到方法很多 不知道都做了些什么

回到Unidbg 根据JNI输出可以得到很多信息

这里取了一些基本信息 又进行了MD5 那可以猜测这里可能是进行签名验证

这里是对运行环境的一个检测 前面补的环境就是Pass掉这些检测

往下看 这里就出现了加密的结果 根据偏移跳转过来

所以先把目光放在sub_4A9D8(v15, v17)

进入sub_4A9D8->sub_4AA00

sub_4AAB4就是申请内存

由于样本被ollvm混淆过 所以变得罗里吧嗦

整段下来其实就只是一个内存拷贝

回到上层 现在关注的就是v17

0x4A9D8处下个console断点

根据代码可知 这里的a2需要再偏移

这里已经存在有结果 所以还得继续找

忽视那些检测代码 剩下的代码并不多

sub_4B458就是做一个拼接操作

byte_1C91B0对应的就是v2-

最后猜测具体的算法就在sub_655DC

进入sub_655DC 只有俩方法 先看sub_65540

这熟悉的数组 实锤MD5

但是 仔细观察 这个md5的魔数和我们普通的貌似不一样

确实不一样 实锤了魔改 先尝试拿MD5修改看看能不能对应得上

和主动调用的对比 确定了仅仅是改了魔数

在后在拼接上v2-就完成这一个sign的加密

encodeAES

先主动调用 方便后面调试

public byte[] encodeAES() {
    ArrayList<Object> args = new ArrayList<>(3);
    args.add(vm.getJNIEnv());
    args.add(0);
    String str = "123456";
    args.add(vm.addLocalObject(new ByteArray(vm, str.getBytes(StandardCharsets.UTF_8))));
    Number number = module.callFunction(emulator, 0x4a0b9, args.toArray());
    Inspector.inspect((byte[]) vm.getObject(number.intValue()).getValue(), "AESencode");
    return (byte[]) vm.getObject(number.intValue()).getValue();
}

接着根据偏移跳转0x4a0b9

sub_67178作用为GetByteArrayElements

进入sub_5E0E0->sub_5E0F8

看到这是一个标准的AES\CBC\128加密 那么接下来的目标就是找出KEY和IV

IV生成位置在sub_5D090

进入sub_5D090发现就是一个随机方法

拿到随机IV后 根据传入明文的长度进行计算出一个校验位 放在第2位中

根据hook结果可得到验证

并且根据输出结果可知 随机生成的iv拼接在了密文的前面传回服务器

接下来就是KEY 回到上层看到a2存在dword_1CC3F0

拿到地址traceWrite

然后跳转偏移地址 跳转过来是一个内存拷贝操作

还得继续回到上层找

sub_5D090

所以KEY和IV一样是随机生成的 那么问题来了 随机生成的KEY怎么能让服务器知道呢 不像IV能拼接在密文前面

其实在native_init的时候就生成了随机的KEY 并且每次打开App都只生成一次后不变动

那猜测一定是在打开App的时候将KEY上传了

打开抓包 并重新打开App 通过观察 可以看到频繁出现了X-Xc-Proto-ReqX-Xc-Proto-Res

X-Xc-Proto-Req

X-Xc-Proto-Res

最终还得回到so分析

主动调用getProtocolKey

public void getProtocolKey() {
    ArrayList<Object> args = new ArrayList<>(2);
    args.add(vm.getJNIEnv());
    args.add(0);
    Number number = module.callFunction(emulator, 0x4a419, args.toArray());
    System.out.println(vm.getObject(number.intValue()).getValue().toString());
}

发现在native_init后就生成了X-Xc-Proto-Req 所以应该是在初始化的时候就生成了KEY顺便也生成了X-Xc-Proto-Req

进入sub_4A068->sub_5CD9C

进入sub_5D4D8 可以发现这是一个SHA256withRSA

asc_1C9E70为公钥

将随机的KEY进行加密后作为X-Xc-Proto-Req上传后即为成功上传KEY 然后会返回X-Xc-Proto-Res

在下次请求时作为标识带上即可

decodeAES

如名字所示 就是AES解密 KEY不变 IV为返回内容的前16位

自己实现AES解密后发现 返回的内容还是乱码 转为HEX时发现1F 8B 08字眼

这是GZIP的头部标识

此时 只需要再将解密出来的内容再进行GZIP解密即可

在Python中实现




感谢各位大佬观看

感谢大佬们的文章分享

如有错误 还请海涵

共同进步 带带弟弟


点赞 在看 分享是你对我最大的支持

逆向lin狗


相关文章
|
17天前
|
安全
【Azure App Service】App service无法使用的情况分析
App Service集成子网后,如果子网网段中的剩余IP地址非常少的情况下,会在App Service实例升级时( 先加入新实例,然后在移除老实例 )。新加入的实例不能被分配到正确的内网IP地址,无法成功的访问内网资源。 解决方法就是为App Service增加子网地址, 最少需要/26 子网网段地址。
|
26天前
【Azure Function App】本地运行的Function发布到Azure上无法运行的错误分析
【Azure Function App】本地运行的Function发布到Azure上无法运行的错误分析
|
27天前
|
Java
【Azure 应用服务】如何查看App Service Java堆栈JVM相关的参数默认配置值?
【Azure 应用服务】如何查看App Service Java堆栈JVM相关的参数默认配置值?
【Azure 应用服务】如何查看App Service Java堆栈JVM相关的参数默认配置值?
|
26天前
|
开发框架 缓存 .NET
【App Service】在Azure App Service中分析.NET应用程序的性能的好帮手(Review Stack Traces)
【App Service】在Azure App Service中分析.NET应用程序的性能的好帮手(Review Stack Traces)
|
27天前
|
缓存 前端开发 Java
【Azure 应用服务】App Service 使用Tomcat运行Java应用,如何设置前端网页缓存的相应参数呢(-Xms512m -Xmx1204m)?
【Azure 应用服务】App Service 使用Tomcat运行Java应用,如何设置前端网页缓存的相应参数呢(-Xms512m -Xmx1204m)?
|
27天前
|
C# 开发工具
【Azure 应用服务】Azure Function App使用SendGrid发送邮件遇见异常消息The operation was canceled,分析源码渐入最源端
【Azure 应用服务】Azure Function App使用SendGrid发送邮件遇见异常消息The operation was canceled,分析源码渐入最源端
|
27天前
|
网络协议 NoSQL 网络安全
【Azure 应用服务】由Web App“无法连接数据库”而逐步分析到解析内网地址的办法(SQL和Redis开启private endpoint,只能通过内网访问,无法从公网访问的情况下)
【Azure 应用服务】由Web App“无法连接数据库”而逐步分析到解析内网地址的办法(SQL和Redis开启private endpoint,只能通过内网访问,无法从公网访问的情况下)
|
3月前
|
移动开发 小程序 开发工具
微信支付的类型分析(JSAPI+APP+H5+NATIVE+付款码+合单)
微信支付的类型分析(JSAPI+APP+H5+NATIVE+付款码+合单)
262 1
|
3月前
|
数据采集 JSON 算法
使用Python爬取华为市场APP应用进行分析
这个网站也是作者最近接触到的一个APP应用市场类网站。讲实话,还是蛮适合新手朋友去动手学习的。毕竟爬虫领域要想进步,还是需要多实战、多分析!该网站中的一些小细节也是能够锻炼分析能力的,也有反爬虫处理。甚至是下载APP的话在Web端是无法拿到APK下载的直链,需要去APP端接口数据获取
|
2月前
4. 解决uni-app开发过程中view、image等标签出现诸如“出现错误:类型“{ class: string; }”的参数不能赋给类型“.......”
4. 解决uni-app开发过程中view、image等标签出现诸如“出现错误:类型“{ class: string; }”的参数不能赋给类型“.......”
164 0

热门文章

最新文章