首页 > 其他分享 >某税务app登录接口逆向--获取长效ck

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

时间:2024-09-03 17:53:44浏览次数:10  
标签:ck 文件 -- app Apk so Dex libso 加载

某税务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文件全部脱壳完成,接下来就是找寻各个接口中参数加密的地方

标签:ck,文件,--,app,Apk,so,Dex,libso,加载
From: https://blog.csdn.net/m0_75266682/article/details/141867426

相关文章

  • 开发一个直播插件,生成AI主播带货!
    在当今的数字时代,直播带货已成为电商领域的一大热门趋势,随着人工智能技术的不断发展,生成AI主播带货的想法正逐渐变为现实。本文将带您了解如何开发一个直播插件,并生成一个能够自主带货的AI主播,我们将通过分享七段源代码,来逐步揭示这一过程的技术实现。1、直播环境设置(使用Flask框......
  • 类和对象~
    类和对象1.类定义和使用2.类的实例化3.this引用1.类定义和使用1.1简单认识类  类是用来对一个实体(对象)来进行描述的,主要描述该实体(对象)具有那些属性(外观尺寸等),有那些功能(行为等)。比如:狗,他是一个动物,在java中可以看成一个类别属性:狗的名字,年龄,颜色行为:汪汪......
  • 高流畅的远程控制软件推荐
    在远程办公、跨地域协作日益普遍的今天,选择一款高性能、快速流畅的远程控制软件显得尤为重要。说到远程软件,我们可能首先希望它快速流畅,其次是安全性也要好。以下几款软件在性能、安全性和易用性方面表现出色,特别适合企业和个人用户。1.Splashtop高性能表现Splashtop以其卓......
  • python 面向对象语法进阶
    python语法面向对象进阶1.定义类的格式2.继承2.1单继承2.2多继承2.3方法重写2.3.1重写后-子类访问父类的成员-写法12.3.2重写后-子类访问父类的成员-写法2super3.多层继承4.封装4.1封装-私有化属性4.2封装-私有化方法5.多态5.1多态案例6.抽象类入门7.类属性与对......
  • 最近(2024.08.14-2024.08.25 )面试感悟
    简历最近(2024.08.14-2024.08.25)除了周末,都在面试的路上,平均每天3、4场面试,边面试边回顾知识点边完善简历,在哀鸿遍野的招聘市场里,简历做了调整,突出自己的优势,比如读过spring源码要能清楚的说出来、比如对jvm内存模型的了解,及为什么采用对应的垃圾回收算法;比如遇到的jvm内存及解决......
  • Java卷上天,可以转行干什么?
     小刚是某名企里的一位有5年经验的高级Java开发工程师,每天沉重的的工作让他疲惫不堪,让他萌生出想换工作的心理,但是转行其他工作他又不清楚该找什么样的工作因为JAVA这几年的更新实在是太太太……快了,JAVA8都还没用多久,16都已经发布了。自从JAVA8发布了Lambda和Stre......
  • ESP32 出现 failed to load RF 报错
    前言正文周五我测试程序没有问题,板子放在桌子上就没动过了。周一过来的时候,重新烧录程序,就发现出现如下报错。最终发现是电池过放导致电池损坏功率不够,因此RF无法启动,一直在重启。解决办法很简单,换一颗正常的电池即可。W(1446)phy_init:failedtol�ESP-ROM:esp8684-api2-20220......
  • 关于DID双重差分的几点说明
    在Stata中,diff命令和经典的回归方式(如xtreg)都可以用来估计DID模型,但它们在灵活性和适用场景上有所不同。1.diff命令:专门用于DIDdiff命令是Stata用户编写的一个扩展工具,专门用于执行Difference-in-Differences分析。它通过简单的语法直接估计DID,并自动提供多种常见的估计......
  • Java卷上天,可以转行干什么?
     小刚是某名企里的一位有5年经验的高级Java开发工程师,每天沉重的的工作让他疲惫不堪,让他萌生出想换工作的心理,但是转行其他工作他又不清楚该找什么样的工作因为JAVA这几年的更新实在是太太太……快了,JAVA8都还没用多久,16都已经发布了。自从JAVA8发布了Lambda和Stre......
  • 一文迅速上手 ESP32 bluedroid 蓝牙从机开发
    前言该博客主要针对希望迅速上手ESP32蓝牙从机开发人员,因此,很多蓝牙技术细节知识并不会进行介绍,仅仅介绍我认为需要了解的API函数和回调内容。本文主要是基于gatt_serverdemo来微调进行进行讲解。代码#include<stdio.h>#include<stdlib.h>#include<string.h>#include<i......