某税务app登录接口逆向--获取长效ck

某税务app登录接口逆向–获取长效ck

前言:之前分析了web版本的登录接口,各参数都很简单 。有朋友私信我说app登录有意外惊喜,俺们做学术研究的不就是喜欢发掘惊喜么,鉴于此有了此文分析

一、目的

​ 1.1、实现完整登录接口(账号登录、短信登录)

​ 1.2、实现免短信登录接口

​ 1.3、定位算法

二、硬件准备

​ 一部使用magisk(面具)root过的真机,强烈建议直接去某鱼某宝买一个!!!我这边用的是pixel3

三、反编译

3.1、apk本质

​ 我们要知道一个apk文件其实就是一个代码包,把下载下来的apk文件改成zip文件,然后用工具反编译下即可,然后进行初步的分析

3.2、本质

​ 反编译是逆向dex文件,得到的是所用语言的源代码

3.3、工具

​ jd、jadx都可以,我觉得jadx好用些,后来发现pycharm有个插件也挺好用

在这里插入图片描述
在这里插入图片描述

反编译后的文件结构:

在这里插入图片描述

四、反汇编

4.1、本质

​ 反汇编和反编译是两码事,反汇编可以理解为逆向so文件,得到的是汇编代码

4.2、工具

在这里插入图片描述

五、了解apk包结构

在这里插入图片描述

so文件为动态链接库(一种二进制文件、c\c++代码文件)一般存放着通用的底层算法库

六、分析加固方式

6.1 第一代 动态加载类

Apk中没有完整原始的Dex,需要运行时动态的加载到内存中

原理

• 落地加载
我们拿到需要加密的Apk和自己的壳程序Apk,然后用加密算法对源Apk进行加密再将壳Apk进行合并得到新的Dex文件,最后替换壳程序中的dex文件即可,得到新的Apk,那么这个新的Apk我们也叫作脱壳程序Apk.他已经不是一个完整意义上的Apk程序了,他的主要工作是:负责解密源Apk.然后加载Apk,让其正常运行起来。运行时首先将我们的Dex文件或者Apk文件解密,然后利用DexClassLoader加载器将其加载进内存中,然后利用反射加载待加固的Apk的Appkication,然后运行待加固程序即可。
img
img

• 不落地加载
落地加载将Dex文件解密出来会保存到文件中,再通过DexClassLoader加载进内存中,而不落地加载直接重写DexClassLoader使其可以直接加载字节数组,避免写入文件中。我们要做的是重写DexClassLoader,而这涉及到三个函数defineClass、findClass、loadClass,在一个类被加载的时候,会先后调用这三个函数加载一个类,所以我们需要重写这三个函数。系统的DexClassLoader加载Dex进入内存的也必然是通过字节加载的,而在系统so中的libdvm.so中的openDexFile可以直接加载Dex文件,那么现在清楚了,我们可以通过编写so文件调用openDexFile函数加载Dex字节数组,值得注意的是,openDexFile函数返回值为一个int类型的cookie,可以简单理解成一个dex文件的’身份码’,通过该’身份码’即可操控这个dex文件,至于怎么调用该函数,可以通过dlopen和dlsym函数调用。
img

• 优点
比较容易实现,无明显的兼容性问题 能有效对抗静态分析和二次打包

• 缺点
启动时需要进行大量的解密运算,容易造成卡死的情况 在内存中的数据为完整的Dex,通过动态调试Dump内存即可获取完整的Dex

img
Dex字符串加密 资源加密 对抗反编译 对抗调试 Dex动态加载 so加密

6.2 第二代 函数抽取类
原理

主要分为两个步骤指令抽取和指令还原

• 指令抽取
解析原始Dex文件格式,保存所有方法的代码结构体信息,通过传入需要置空指令的方法和类名,检索到其代码结构体信息。通过方法的代码结构体信息获取指令个数和偏移地址,构造空指令集,然后覆盖原始指令,重新计算dex文件的checksum和signature信息,回写到头部信息中。
img
img

• 指令还原
native层hook系统函数dexFindClass,获取类结构体信息(dexFindClass函数用于查找类的DexClassDef结构),获取类中所有的方法信息,通过指定方法名进行过滤,获取该方法的代码结构体信息,获取该方法被抽取的指令集,修改方法对应的内存地址为可读属性,直接进行指令还原。

• 优点
加密粒度变小,加密技术从Dex文件级变为方法级 按需解密,解密操作延迟到某类方法被执行前,如果方法不被执行,则不被解密 解密后的代码在内存不连续,克服了内存被Dump的缺点,有效保护了移动客户端的Java代码

• 缺点
使用大量的虚拟机内部结构,会出现兼容性问题,无法保护所有方法 无法对抗自定义虚拟机 它跟虚拟机的JIT优化出现冲突,达不到最佳的性能表现

img
除一代有的特点外 内存中无完整、连续的Dex so代码混淆、膨胀

6.3 第三代:vpm版本
原理

• VMP
执行到关键代码时进入壳so执行,关于这一点,不同的厂商有着不同的做法,比如把关键函数变成native函数,在壳so中动态或者静态注册
img
再比如更改关键方法的方法体
img
无论哪种方法其实都是为了能让壳函数代替原函数去执行 当执行该函数的指令时,解析出指令的OpCode,通过一个巨大的switch case找到处理对应OpCode的函数,然后执行
img
简单讲就是壳将原本的指令进行一次封装,将原本的指令转换为另一种表现形式

• Dex2C
首先也是将关键代码注册为native函数,主要借助于JNI反射技术,将Java层的方法全部反射为native层,增大分析难度。之后再通过混淆、字符串加密等操作生成so,最后将so进行加固保护。

• 优点
加固强度高,目前没有公开的脱壳工具 经过混淆加密后很难还原原函数

• 缺点
效率较低,启动、运行时都比较耗时稳定性、可控性差,容易产生崩溃

img
除一、二代全部特点外 so代码虚拟化 对抗之前所有的脱壳方法

七、抓包

7.1、本地抓包
7.1.1、网络证书配置

​ 确保PC和手机端在同一个局域网下,开个热点一起连,谷歌手机在连接wifi后出现不能连接网络的情况

​ 直接使用以下命令:

adb devices//查看是否连接到测试机
 
adb shell settings put global captive_portal_use_https 1
adb shell settings put global captive_portal_http_url http://captive.v2ex.co/generate_204
adb shell settings put global captive_portal_https_url https://captive.v2ex.co/generate_204
adb shell settings put global captive_portal_mode 0

​ 手动设置代理地址为PC的ip和抓包软件设置的端口号(默认8888),手机访问地址安装证书,默认证书是安装在用户列表里

在这里插入图片描述

在这里插入图片描述

抓包结果:

在这里插入图片描述

在这里插入图片描述

7.1.2、root检测

​ 现象就是检测到该应用在root环境下运行,闪退

​ 解决方案:magisk中模块shamiko,有时候高版本不行,那就降版本
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

7.1.3、网络异常

在这里插入图片描述

​ 怀疑是app对抓包的反检测,当前的android12对用户安装的证书不信任导致的,建议直接使用magisk的三方模块将证书转移至系统目录,安装完模块直接重启设备,证书就自动移到系统目录了

在这里插入图片描述

7.1.4、证书错误

​ 中途更换了抓包工具亦如此,系统证书检测、app证书检测,怀疑后者,但是后来换热点、换设备就可以了(第一点换热点也可以解 决),无解

​ 这个问题目前没有根治

7.2、远程抓包

​ 部署个远程服务器,在上面装个抓包软件,手机连接wifi手动设置代理地址为服务器端的ip和抓包软件设置的端口号

八、脱壳准备

8.1、了解frida框架
8.2、两端(PC、DEVICE)环境搭建
8.2.1、PC

在这里插入图片描述

8.2.2、设备端

​ 安装与之版本匹配的frida-server,后面的代码注入都依赖他,先在PC端下载好,再用adb推送过去

在这里插入图片描述

8.2.3、常见问题及解决策略

​ 1、推送的是文件,而不是目录,否则在启动的时候会出现以下情况

在这里插入图片描述

​ 2、赋予文件最高权限

在这里插入图片描述

​ 3、修改文件名避免基本的frida检测

在这里插入图片描述

​ 4、frida-server版本不对,会出现以下情况

在这里插入图片描述

8.3、启动、测试连接
8.3.1、查看当前设备运行进程 frida-ps -U

在这里插入图片描述

8.3.2、先启动设备端frida-server

在这里插入图片描述

8.3.3、pc端建立连接

在这里插入图片描述

在这里插入图片描述

8.3.4、常见问题及解决策略

​ 1、进程异常退出

连接过程进程会异常退出,强行启动app依然如此,发现app可能对frida的特性进行了检测

使用魔改版本的frida——hluda

在这里插入图片描述

再次下载、推送、启动并指定端口

在这里插入图片描述

​ 2、再次连接依然报错

在这里插入图片描述

在这里插入图片描述

端口转发过后,就ok了

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

至此,PC端与设备端正式建立了frida服务框架,确保frida的正确运行

九、so脱壳

​ 反编译之后,在lib库里面发现一堆so文件,当即对其进行了反汇编,发现大部分文件都损坏了,打不开

在这里插入图片描述

请教业内前辈,才知道so文件是加固过的,可以尝试从内存中dump出来,原理就是,设备端运行app,会自动对加壳的文件进行脱壳,再加载到内存中,基于此,可以直接从内存中读取

9.1、编写准备注入的js
function dump_so(so_name) {
    Java.perform(function () {
        var currentApplication = Java.use("android.app.ActivityThread").currentApplication();
        console.log("活动进程:", currentApplication)
        var dir = currentApplication.getApplicationContext().getFilesDir().getPath();
        console.log("目录:", dir)
        var libso = Process.getModuleByName(so_name);
        console.log("目标so文件路径:", libso)
        console.log("[name]:", libso.name);
        console.log("[base]:", libso.base);
        console.log("[size]:", ptr(libso.size));
        console.log("[path]:", libso.path);
        var file_path = dir + "/" + libso.name + "_" + libso.base + "_" + ptr(libso.size) + ".so";
        var file_handle = new File(file_path, "wb");
        if (file_handle && file_handle != null) {
            Memory.protect(ptr(libso.base), libso.size, 'rwx');
            var libso_buffer = ptr(libso.base).readByteArray(libso.size);
            file_handle.write(libso_buffer);
            file_handle.flush();
            file_handle.close();
            console.log("[dump]:", file_path);
        }
    });
}

console.log("js注入成功, 准备dump!!!")
9.2、连接、启动、注入

在这里插入图片描述

在这里插入图片描述

9.3、锁定so文件位置

在这里插入图片描述

9.4、导出

在这里插入图片描述

在这里插入图片描述

9.5、查找算法

在这里插入图片描述

至此,so文件全部脱壳完成,也仍然存在小部分文件损坏了,这个也可以用脚本进行修复

十、dex脱壳

10.1、下载frida_dexdump

在这里插入图片描述

在这里插入图片描述

10.2、启动frida-server

在这里插入图片描述

10.3、导出

在这里插入图片描述

导出重新扔到jadx里编译,发现也没找到与包名类似的文件夹,怀疑没脱全

在这里插入图片描述

10.4、二次导出

切换app到登录页面,使用深度搜索
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

看着比之前文件多了一倍,重新扔到jadx里面,发现有报错,仍然没看到类似的文件夹,尝试用pycharm里的插件jadx打开
在这里插入图片描述

在这里插入图片描述

看着比之前文件多了一倍,重新扔到jadx里面,发现有报错,仍然没看到类似的文件夹,尝试用pycharm里的插件jadx打开

至此,dex文件全部脱壳完成,接下来就是找寻各个接口中参数加密的地方

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值