Android逆向及渗透测试相关技术总结

本文主要介绍使用一些工具对apk进行逆向获取部分源代码,并通过frida对函数进行Hook并修改其值;使用Burpsuite对app请求进行抓包并进行渗透测试,本文仅供交流学习。

1、逆向

先查看apk是否进行加壳,若加壳则需要使用脱壳工具进行脱壳,脱壳后拿到dex文件使用反编译工具对dex文件进行反编译获取源码进行分析。

1.1 壳分类

加壳技术 特点 脱壳难度 描述
第一代:dex 整体加密型壳 采用 dex 整体加密,动态加载运行的机制 较容易被还原,通过自动化脱壳工具或脚本即可从内存中 dump 出 dex 文件 隐藏 dex 文件
第二代:dex 函数抽取型壳 粒度更细,将方法单独抽取出来,加密保存,解密执行 可以从根本上进行还原的,dump 出所有的运行时的方法体,填充到 dump 下来的 dex 中去的,这也是 fart 的核心原理 隐藏 dex 并下沉其中部分方法
第三代:vmp、dex2C 壳 独立虚拟机解释执行、语义等价语法迁移,强度最高 dex2C 目前是没有办法还原的,只能跟踪进行分析; vmp虚拟机解释执行保护的是映射表,只要心思细、功夫深,是可以将映射表还原 虚拟机里跑虚拟机

1.2 脱壳工具

工具 描述
BlackDex github上开源项目,是一个运行在Android手机上的脱壳工具,支持5.0~12,无需依赖任何环境任何手机(无需root)都可以使用,包括模拟器。只需几秒,即可对已安装包括未安装的APK进行脱壳。 其只能脱第一代的壳,但也可拿到不少源代码进行分析。
Fart 需刷入定制rom,不过其也提供了frida_frat供使用,均在其github中;详情可参见ART环境下基于主动调用的自动化脱壳方案。
frida-dexdump 需依赖frida框架,安装及命令均在 github中。

以上为比较常用的脱壳工具,还有很多其他工具如FDex2、FUPK3等就不再赘述了,需要的可以网上搜索使用教程。

1.3 反编译工具

工具 描述
jadx 本人常用的反编译工具,可直接使用jadx-gui打开apk、aar、jar、dex、aab、zip文件查看源代码
dex2jar 把dex文件转换成jar的工具,有的时候jadx反编译失败可以尝试使用dex2jar来进行反编译,反编译后用jd-gui或者jadx查看源码。

以上为我常用的反编译工具,还有很多其他如CFR 、Procyon 等由于使用比较麻烦,只进行了了解未真正使用。
注:有的时候jadx加载脱壳后的dex文件时会发现缺少类(特别是各种Activity),并且jadx会提示错误jadx.plugins.input.dex.DexException: Bad checksum: 0xf0d8fef6, expected: 0xa2ffe277,此时进入jadx文件加后使用jadx-gui -Pdex-input.verify-checksum=no指令运行jadx后就会正常显示,相应的内存增量也会较大。

2、Hook与动态调试

Hook俗称钩子,本质是当调用某段代码时同时会执行Hook代码,这样可以读取输入输出,也可以修改输入输出,使用到的技术包含了反射、动态代理等,也分java层Hook与native层Hook等多种形式。Hook框架也分为root与非root两种,非root框架只能Hook本app内相关函数如epicsandhook等便于开发,而需root框架则可以Hook系统调试其他app的框架,就是接下来要介绍的重点。

2.1 Hook调试框架

框架 描述
frida 一款基于 Python + JavaScriptHook 与调试框架;易用的跨平 Hook 工具, Java 层到 Native 层的 Hook 无所不能,是一种动态的插桩工具,可以插入代码到原生 App 的内存空间中,动态的去监视和修改行为,原生平台包括 Win、Mac、Linux、Android、iOS 全平台,是目前主流的hook及动态注入框架。
xposed 一款可以在不修改apk的情况下影响程序运行(修改系统)的框架服务,基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。由于使用起来颇为复杂,所以其使用率已经较少了。

2.2 Frida安装

Frida分为客户端(即PC端)与服务端(即移动设备,也成为被控制端)。
hook流程大致是客户端通过编写的 Python代码(也可以通过指令直接注入js代码),用于连接服务端设备,提交要注入的 js代码到服务端,接受服务端发来的消息;服务端中需要用 js 代码注入到目标进程,操作内存数据,给客户端发送消息。

2.2.1 先安装Python

这里我使用的Python版本是3.11.0(由于我使用的frida版本比较新,所以无法使用Python2进行安装,若想使用Python2安装则需降低frida版本),可以去官网上下载。

安装Python

2.2.2 安装Frida

当Python安装好并配置好环境变量后,可通过如下指令安装Frida

客户端:
pip install frida
//指定版本指令 pip install frida==x.x.x
pip install frida-tools
//指定版本指令 pip install frida-tools==x.x.x

安装好后可以通过frida --version指令查看安装是否成功,这我安装的版本是16.0.2

Frida安装

服务端:

a、服务端去其官方github上下载与版本对应的server文件,不过server文件与系统架构也相互对应,若是跟我一样使用模拟器的,则可以下载16.0.2版本的x86架构sever,若是使用真机的则可以通过adb指令查询手机架构后寻找对应的进行下载即可。
注:若模拟器提示Failed to enumerate processes: unable to handle 64-bit processes due to build configuration,需下载x86_64位版本。

下载server

b、下载完文件以后解压出里面的server文件,使用adb链接模拟器(手机),若是夜神模拟器,可以通过adb connect 127.0.0.1:62001进行连接(不同模拟器端口号不同),连接后使用adb push sever文件 data/local/tmp 命令把文件push到手机data/local/tmp目录下
push文件

push搭配指定目录后,进入shell模式,提高server文件的权限

//进入shell模式
adb shell
//提高权限
chmod 777 xx-server
su -c xx-server &
//开启服务
./xx-server

指令

通过frida-ps -U可了解服务是否运行成功
打印server手机服务

以上均成功,说明环境已配置完成,下一步可编写一些js注入脚本等进行实测。

ADB指令
//查看当前连接设备
adb devices

//多个设备时指定设备
adb -s 设备号 其他指令
// adb -s 设备端口 shell
//127.0.0.1:5555 蓝叠
//127.0.0.1:7555 MUMU模拟器
//127.0.0.1:62001 夜游神模拟器
//127.0.0.1:21503 逍遥模拟器

//查看Android处理器架构
adb shell getprop ro.product.cpu.abi

//安装APP
adb install xxx.apk

//安装APP,已经存在,覆盖安装
adb install -r xxx.apk

//强制安装apk,可安装一些未签名debug包
adb install -t xxx.apk

//卸载APP
adb uninstall 包名

//卸载APP,保留数据
adb uninstall -k 包名

//往手机传递文件
adb push 本地文件 手机路径

//从手机端获取文件
adb pull 手机文件 本地路径

//移动文件
mv 文件 路径

//修改文件权限
chmod 777 xxx

//查看日志
adb logcat

//清日志
adb logcat -c

//手机端安装的所有app包名
adb shell pm list packages

//查看当前包名和主Activity
adb shell dumpsys window | findstr mCurrentFocus

//启动APP
adb shell am start 包名/主Activity
//adb shell am start xxx.xxx.XXActivity

//关闭App
adb shell am force-stop 包名

//屏幕截图
adb shell screencap 手机路径/xxx.png

//录制视频
adb shell screenrecord 手机路径/xxx.mp4

//转发端口,使用python调试需要使用
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
Frida指令
//列举出来所有连接到电脑上的设备
frida-ls-devices

//连接到指定设备
frida-ps -D tcp

//列举出来设备上的所有进程
frida-ps -U

//列举出来设备上的所有应用程序
frida-ps -Ua

//列举出来设备上的所有已安装应用程序和对应的名字
frida-ps -Uai

//跟踪某个函数
frida-trace -U -f Name -i "函数名"

//跟踪某个方法
frida-trace -U -f Name -m "方法名"

//执行js脚本
frida -U -l js脚本 -f packagename --no-pause

2.2.3 js注入hook函数实战

a、先编写一个简单的Demo,一个MainActivity,在onCreate初始化时打印一个toast,内容是测试Hook,代码如下

Demo代码

安装到模拟器(手机)效果如下
原toast打印

b、现在要hook MainActivity的onCreate并修改toast打印内容为"hook后,内容已被修改",hook_toast_test.js注入代码如下

Java.perform(function () {
  // hook类: MainActivity
  var MainActivity = Java.use("cn.test.hook.MainActivity");
  // hook方法: MainActivity.onCreate
  MainActivity.onCreate.implementation = function (savedInstanceState) {
    //控制台输出log日志,方便监控程序运行
    console.log("执行onCreate");
    // 程序不被终端,继续执行
    this.onCreate(savedInstanceState);
  };

  // 获得Toast组件
  var Toast = Java.use("android.widget.Toast");
  var makeText = Toast.makeText;
  var String = Java.use("java.lang.String");
  // 函数重载, 设置参数类型
  makeText.overload("android.content.Context", "java.lang.CharSequence", "int").implementation = function (
    context,
    content,
    time
  ) {
    //控制台输出log日志,方便监控程序运行
    console.log("修改toast内容");
    // 设置新内容
    var content = "hook后,内容已被修改";
    // 实例化字符串
    var hookContent = String.$new(content);
    // 程序不被终端,继续执行
    return this.makeText(context, hookContent, time);
  };
});

注:如果需要了解更多的Api可去官方Frida JavaScript Api文档中学习。

c、直接通过指令运行js脚本frida -U -f cn.test.hook --pause -l F:\workspace\vshook\hook_toast_test.js来执行hook_toast_test.js脚本,模拟器会启动包名为cn.test.hook的应用程序,并执行hook与注入等

执行注入

效果

2.2.4 使用编辑器进行动态调试

我常用的编辑器是VS Code,安装扩展frida Workbench后会显示一个R的标志,当启动frida-server后并使用adb转发端口,VS Code中就可以显示相应的设备可直接进行动态调试,这样就可以使用VS Code来编写python脚本加载js注入代码来完成更多的功能,调试起来也相对方便。

VS Code进行动态调试

以上为一个hook注入操作的基本过程。

3、渗透测试

3.1、工具

常用Burpsuite,网上自取,安装教程可参见Burpsuite的超详细安装教程(图文版)。

3.1.1、抓数据

中间人攻击
步骤1:设置代理

步骤1

点击Add后操作
设置IP PORT

步骤2:开启intercept
步骤2

步骤3:模拟器手机设置代理
步骤3

步骤4:抓取数据
步骤4

3.1.2、https协议证书安装

由于有的app使用的https协议,抓包数据为密文数据,需要设置中间人证书,在步骤1中图示5导出证书cacert.der,由于android无法使用der证书,需要使用openssl指令对证书进行导出,可以使用mac、linux系统进行操作或者windows安装openssl也可以。6.0及以下系统可直接安装证书,7.0及以上系统由于不再信任非系统证书,所以需要把证书安装到系统证书中,模拟器(手机)需要有root权限

//der转pem
sudu openssl x509 --inform cacert.der -in cacert.der -put burp.pem
//显示pem详细信息
sudu openssl x509 -in burp.pem --subject_hash_old
//把pen转成9a5ba575.0证书
sudo cp burp.pem 9a5ba575.0

得到9a5ba575.0证书后,

//设置remount
adb remount
//把证书push到系统证书中
adb push 9a5ba575.0 /system/etc/security/cacerts/
//重启手机
adb shell reboot

模拟器(手机)重启后在设置->安全->信任的凭据->系统中查看是否有PowerSwigger,若存在说明证书安装成功,再抓取https协议请求后密文数据可显示为明文。

证书

注:有的人在正确配置各项后打开app依然无法抓取请求,甚至burp中没有相应的请求,但是app中显示数据已请求完成,这种情况可能是app在代码中设置了网络请求绕过proxy,遇到这种情况有两种解决方式:1、使用Proxifier开启一个代理通道,无需手机配置代理;2、反编译源码查看设置绕过proxy的代码部分,对proxy代码进行hook并绕过校验。

3.2、实际操作

待更新

你可能感兴趣的:(Android逆向及渗透测试相关技术总结)