Hook技术在安卓安全领域的应用
2023-3-9 17:49:1 Author: www.freebuf.com(查看原文) 阅读量:35 收藏

大家好,我是观宇战队的Yorikiko,今天为大家分享Hook技术在安卓安全领域的应用,无论是在渗透攻防还是安全分析与测试,Hook技术都可以提供非常有价值的支撑,可以说是安全研究人员必备的一项技能。

Hook 技术是一种能够劫持函数调用,改变函数执行结果的技术。中文译为“钩子”,即在事件开始到结束之间,截获并监控事件,并实现一些自定义的事件操作功能,达到想要的结果。无论是在渗透攻防还是安全分析与测试,Hook技术都可以提供非常有价值的支撑。例如能绕过系统检测、获取函数关键参数、辅助病毒木马分析以及APP隐私数据合规检测等。

1.1 Hook原理介绍

Hook技术的本质就是劫持函数调用。在应用程序还没有调用该函数之前,Hook代码先于函数代码执行,这样既可以改变函数的执行结果,也可以强制结束函数的执行。

由于Android系统中,每个APP的进程空间是独立的,且互相不能访问,因此就需要进行so动态注入,将用于Hook的so注入到目标进程中,实现对目标进程空间的访问,修改目标进程空间中的代码,从而实现Hook的目的。动态注入一般使用ptrace函数来实现。

1.1.1ptrace函数

ptrace函数是一个系统调用,可以监控程序执行,查看或更改被监控程序的内存和寄存器,包括其指令空间、数据空间、堆栈以及所有的寄存器,通常用于软件的开发调试,gdb就是使用ptrace来实现软件调试功能的。在C语言标准库中,ptrace实际调用的是系统调用__NR_ptrace,在Android Kernel 4.4版本中,系统调用号为117。

/* kernel/ptrace.c */
#define __NR_ptrace 117
__SYSCALL(__NR_ptrace, sys_ptrace)

C语言中函数调用方式如下:

#include <sys/ptrace.h> 
int ptrace(int request, int pid, int addr, int data);
4个参数的含义分别为:
1、request:指示了ptrace要执行的命令;
2、pid: 指示ptrace要跟踪的进程;
3、addr: 指示要监控的内存地址;
4、data: 存放读取出的或者要写入的数据。

1.1.2so动态注入

动态注入的方法主要分为6步:

1、获取目标APP的pid,并且关联到进程。程序中可以通过遍历查找“/proc/{pid}/cmdline”文件中是否包含目标进程名,APP一般是包名,如有则得到APP的pid值,然后调用ptrace(PTRACE_ATTACH)即可关联到目标进程。

2、获取并保存APP进程当前所有寄存器的值和堆栈,保存现场,调用ptrace(PTRACE_GETREGS, pid, NULL, &saved_regs)即可实现。

3、获取目标APP进程的dlopen和dlsym函数的绝对地址。这里需要了解dlopen函数绝对地址的计算方法,首先了解一下函数偏移的关系,由于同一个系统,使用的linker相同,因此在当前进程中dlopen函数偏移和目标进程中的偏移是相等的,如下图所示。

1678353238_6409a35673e42e91b3737.jpg!small?1678353232813

图1.1 dlopen函数偏移关系

因此,计算目标进程dlopen函数绝对地址的大致思路为,从/proc/{pid}/maps文件中分别获取到当前进程中linker的基地址base1和目标进程linker的基地址base2,然后获取当前进程dlopen函数的绝对地址local_dlopen,最后计算出目标进程dlopen的绝对地址target_dlopen=local_dlopen – base1 + base2,计算dlsym函数绝对地址同理。

4、将hook.so的绝对路径压栈,因为在调用dlopen函数时需要将参数压栈,这里和ROP的使用方式类似。

5、调用dlopen函数加载hook.so,调用dlsym函数获取hook.so的入口函数地址,并执行。

6、恢复目标进程的堆栈及所有寄存器的值,然后解除关联,这样就完成了so的动态注入。整个注入流程如下图所示:

1678353248_6409a36065f38e7c7d489.jpg!small?1678353243290

图1.2 动态注入流程图

1.2 Hook技术应用

Hook技术功能十分强大,通过Hook大量的系统函数,可以监控病毒木马的文件操作行为、网络行为等,实现一个沙箱的功能,为分析提供辅助作用。

在逆向分析时配合Hook技术,可以实现加密算法的快速解密,修改函数的返回结果,破解软件等目的。

不仅如此,在当下的攻防实战中,移动端往往也存在很多的攻击面。但是大部分APP进行了各种加固处理,如请求数据全文加密、开启证书校验、root检测等复杂的情况。为了绕过这些复杂的检测逻辑,加密逻辑,降低我们测试的成本。我们可以运用Hook技术,通过Hook关键函数,在保证前后端代码正常运行的情况下,注入我们的Hook脚本,让测试过程只需关注输入输出即可,以此帮助我们更高效的发现安全问题。

2.1主流框架

Hook主流框架包括Xposed框架、Frida框架、Cydia Substrate框架、ADBI/DDI框架。其中Frida采用动态二进制插桩技术来实现,在目标程序运行时,动态注入frida-agent.so到目标进程中,该so内含js引擎,可以执行各种Hook操作。主要由PC控制端和frida_server两部分组成,frida_server运行在手机或者模拟器中,Hook代码运行在PC端。因此Frida框架相比其他框架较为较量级,下面针对轻量级Hook框架展开介绍。

2.2 轻量级Hook框架Frida

2.2.1 Frida原理介绍

Frida是一款基于Python + JavaScript的Hook框架, Frida的主要工作方式是将代码注入到目标进程中,架构图如图所示。

1678353273_6409a37908a368e67c76f.jpg!small?1678353267333

图2.1 Frida架构图

2.2.1.1 Dalvik虚拟机中Hook实现方式

Frida兼容了低版本的Android系统,当Android版本低于5.0时,则在Dalvik虚拟机中实现Hook,这时,Hook的实现和Xposed原理相同,都是把被Hook的Java函数转为native函数,并修改函数的入口代码为自定义的代码,使得函数执行时跳转到我们自定义的代码里执行,实现Hook的目的。

在Android系统执行函数的过程中,系统函数dvmCallMethodV会根据该函数的accessFlags值判断是native函数还是Java函数,因此可以通过修改accessFlags的值来实现将Java函数转为native函数,从而进入native函数调用流程,跳转到Hook代码里执行。

为了更好的理解函数转换过程,这里分析一下Dalvik源码中Method结构体源码,代码如下:

struct Method {   
   ClassObject*    clazz;   /* method所属的类对象*/
  u4         accessFlags; /* 访问标记,表示为native函数还是java函数 */
    u2         methodIndex; /* method索引 */
//三个size为边界值,对于native函数,这3个size均等于参数列表的size
  u2         registersSize;  /* ins + locals */
  u2         outsSize;
  u2         insSize;
  const char*     name;//函数名称
  DexProto      prototype;
  const char*     shorty;
  const u2*      insns;
  int         jniArgInfo;
  DalvikBridgeFunc   nativeFunc;  /* native函数指针 */
  bool fastJni;
  bool noRef;
  bool shouldTrace;
  const RegisterMap* registerMap;
  bool inProfile;
};

Frida修改了被Hook函数中的accessFlags、registersSize、outsSize、insSize和jniArgInfo,将原来的Java函数修改为native函数,并调用dvmUseJNIBridge函数为这个函数设置一个JNI bridge,将nativeFunc指向自定义的函数。Frida源代码如下:

function replaceDalvikImplementation (fn) {
  if (fn === null && dalvikOriginalMethod === null) {
    return;
  }
//备份原来的method,
  if (dalvikOriginalMethod === null) {
    dalvikOriginalMethod = Memory.dup(methodId, DVM_METHOD_SIZE);
    dalvikTargetMethodId = Memory.dup(methodId, DVM_METHOD_SIZE);
  }
  if (fn !== null) {
   //自定的代码
    implementation = implement(f, fn);
    let argsSize = argTypes.reduce((acc, t) => (acc + t.size), 0);
    if (type === INSTANCE_METHOD) {
      argsSize++;
    }
    // 把method变成native函数
    /*
     * make method native (with kAccNative)
     * insSize and registersSize are set to arguments size
     */
    const accessFlags = (Memory.readU32(methodId.add(DVM_METHOD_OFFSET_ACCESS_FLAGS)) | kAccNative) >>> 0;
    const registersSize = argsSize;
    const outsSize = 0;
    const insSize = argsSize;
    Memory.writeU32(methodId.add(DVM_METHOD_OFFSET_ACCESS_FLAGS), accessFlags);
    Memory.writeU16(methodId.add(DVM_METHOD_OFFSET_REGISTERS_SIZE), registersSize);
    Memory.writeU16(methodId.add(DVM_METHOD_OFFSET_OUTS_SIZE), outsSize);
    Memory.writeU16(methodId.add(DVM_METHOD_OFFSET_INS_SIZE), insSize);
    Memory.writeU32(methodId.add(DVM_METHOD_OFFSET_JNI_ARG_INFO), computeDalvikJniArgInfo(methodId));
    //调用dvmUseJNIBridge为这个Method设置一个Bridge,本质上是修改结构体中的nativeFunc为自定义的implementation函数
    api.dvmUseJNIBridge(methodId, implementation);
    patchedMethods.add(f);
  } else {
    patchedMethods.delete(f);
    Memory.copy(methodId, dalvikOriginalMethod, DVM_METHOD_SIZE);
    implementation = null;
  }
}

2.2.1.2ART虚拟机中Hook实现方式

ART虚拟机和Dalvik虚拟机原理相同,也是将Java函数转为native函数,但ART虚拟机的运行机制较为复杂,实现也更复杂。ART虚拟机有两种函数执行模式,一种是quick code模式,该模式直接执行arm汇编指令,另一种是Interpreter模式,由解释器解释执行Dalvik字节码。

ART虚拟机源码中也定义了ARTMethod类,其中entry_point_from_quick_compiled_code_表示以quick code模式执行时的函数入口。

class ArtMethod {
  GcRoot<mirror::Class> declaring_class_; //method所属的class
  std::atomic<std::uint32_t> access_flags_;//访问标记,表示为native函数还是java函数
  uint32_t dex_code_item_offset_;
  uint32_t dex_method_index_;
  uint16_t method_index_;
  uint16_t hotness_count_;
  struct PtrSizedFields {
    ArtMethod** dex_cache_resolved_methods_;
    void* data_;
    void* entry_point_from_quick_compiled_code_; // 以quick code模式执行时的函数入口
  } ptr_sized_fields_;
}

在ART虚拟机中,对每个函数,首先会尝试以quick code模式执行,并检查entry_point_from_quick_compiled_code_的值,这里有3中情况:

一、如果Java函数已经存在quick code, 则转到这个函数对应的quick code的起始地址执行;

二、如果Java函数不存在quick code,该值为 artQuickToInterpreterBridge函数地址,用以切换到 Interpreter 模式来解释执行;

三、如果native函数不存在quick code时,该值为 art_quick_generic_jni_trampoline函数地址,用以执行没有quick code的 native函数。

因此,如果Frida将Java函数修改为native函数时是不存在quick code的,需要将entry_point_from_quick_compiled_code_的值修改为art_quick_generic_jni_trampoline函数地址。同时,修改access_flags_的值为native,Frida源码如下。

patchMethod(methodId, {
  //jnicode入口entry_point_from_jni_改为自定义的代码
  'jniCode': implementation,
  //修改为access_flags_为native
  'accessFlags': (Memory.readU32(methodId.add(artMethodOffset.accessFlags)) | kAccNative | kAccFastNative) >>> 0,
  //entry_point_from_quick_compiled_code_
  'quickCode': api.artQuickGenericJniTrampoline,
  //entry_point_from_interpreter_
  'interpreterCode': api.artInterpreterToCompiledCodeBridge
});

2.2.2 Frida使用介绍

一、PC机配置:

Python3

pip install Frida

pip install Frida-tools

二、移动端配置:

首先下载Frida-server,且和PC机的版本保持一致。这里选择Frida-server 15.1.16,目标系统为android 32位系统,然后使用adb push将下载好的Frida-server传入手机中。

所有环境搭建完成后,首先启动移动端Frida-server,然后再frida-ps -U查看手机内进程信息,如下图所示则搭建成功。

1678353652_6409a4f4a2ce8c0f422b9.jpg!small?1678353646892

图2.2:进程信息

由于Hook技术不仅可以劫持APP函数,还可以劫持Android系统函数,如果在没有任何防御措施的情况下,Hook技术几乎可以实现任何想要的结果,功能十分强大。如今Hook技术已经非常成熟,应用领域也十分广泛,如APP双开技术、敏感API监测以及分析加密算法等。

3.1APP双开技术(沙箱技术)

由于Android系统中不能同时运行两个相同的APP,但是很多时候我们需要多账号同时运行,因此APP双开技术就应运而生。但是传统的Hook框架都需要动态注入代码,这样就需要root权限才能实现,这大大增加了手机的安全风险,而且操作成本高,免root实现Hook便由此诞生。

该技术实现原理为将需要多开的APP以插件的方式运行,这样可以实现免安装运行任意应用。这里需要一个宿主APP,及为插件提供运行环境的应用软件,共涉及到Android系统的APP层、Framework层以及Native层。APP想要在Android系统中运行,就必须完成安装,系统才会接纳,但是不安装如何才能正常运行APP呢?答案只有“欺骗”系统,让系统认为已经安装了该应用,而实现“欺骗”系统的方法则通过实现一套虚拟化的Framework层和虚拟化的Native层,如图3.1所示。

1678353671_6409a50721b68ae9b26d6.jpg!small?1678353665427

图3.1 APP双开框架

虚拟化Framework层主要给Android Framework和插件APP做代理,这也是宿主APP的核心。宿主APP提供了一套自己的Framework,处于Android Framework与插件APP之间。

这样通过代理的方式,就可以实现APP双开的功能了,典型代表项目有360DroidPlugin、VirtualApp等。

3.2 敏感API监测

随着网络安全法的不断完善,法律对APP的隐私合规性进行了严格规定,为了满足法律要求,越来越多的APP敏感API调用不合规,其检测方法除了使用沙箱外,还可以使用Hook来实现,如Xposed实现方法代码如下。

public class XposedHook implements IXposedHookLoadPackage {
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
        if (lpparam == null) {
            return;
        }
        XposedHelpers.findAndHookMethod(
                android.net.wifi.WifiInfo.class.getName(),
                lpparam.classLoader,
                "getMacAddress",
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) {
                        XposedBridge.log("调用getMacAddress()获取了mac地址");
                    }
                }
        );
        XposedHelpers.findAndHookMethod(
                java.net.NetworkInterface.class.getName(),
                lpparam.classLoader,
                "getHardwareAddress",
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) {
                        XposedBridge.log("调用getHardwareAddress()获取了mac地址");
                    }
                }
        );
    }
}

这里使用findAndHookMethod检测获取手机MAC地址的getMacAddress和getHardwareAddress函数,如果检测到存在这两个函数的调用,并在日志中打印出检测结果。这里还可以增加其他获取用户敏感信息的API,实现全面监测。

3.3 分析加密算法

Hook技术对于Android应用逆向分析也有很好的辅助作用,遇到复杂加密算法时,如果采用传统的逆向分析方法,反编译出APP源码,阅读代码及代码调用关系来分析加密算法特征,找出使用的加密算法。如果是已知的AES、RC4以及RSA算法,解密相对来说比较简单,找出密钥即可,但是遇到用户自定义的加密算法,或者已知算法的变体,则分析起来特别的费时费力,并且可能会遇到写不出解密算法的问题。这个时候采用Hook技术则可以方便快捷的得到加密前或解密后的明文数据,只需要逆向找出加解密算法的代码,确定Hook的目标函数即可。

这里使用Xposed为例,合理使用beforeHookedMethod和afterHookedMethod函数,就可以很快获取加密前或者解密后的明文数据。示例代码如下。

public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
    //HOOK  doFinal
    XposedBridge.hookAllMethods(javax.crypto.Cipher.class, "doFinal", new XC_MethodHook() {
        @Override
        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
            //     super.beforeHookedMethod(param);
            Cipher cipher = (Cipher) param.thisObject;
            //获取加密的类型
            String type = cipher.getAlgorithm();
            //获取加密后的返回值
            byte[] res = (byte[]) param.getResult();
            String data = new String(res);
            Log.d("TAG", type + ":doFinal返回值:" + data);
        }
    });
}

这里使用hookAllMethods函数指定Hook的类为“javax.crypto.Cipher”,Hook的目标函数为“doFinal”函数,因为doFinal比较通用,Java层的DES和AES等算法都会调用该函数,如图3.2所示。

1678353782_6409a5767ffe84990e3f9.jpg!small?1678353777011

图3.2 AES加解密算法

这里也可以以decrypt或encrypt函数作为目标函数进行Hook,但是实际Hook过程中可能会出现选择的目标函数无效,不能获取想要的数据的情况,这里需要根据实际情况,灵活选择目标函数,来达到获取数据的目的。有了Hook技术的辅助,大大提升了逆向分析效率。

3.4示例分析

3.4.1绕过root检测

APP存在root检测,一旦见到root情况,则自动退出,检测root方法有很多,这里总结了以下三点

1.检测su等文件,这些二进制文件在root时会安装到手机中。

/sbin/su
/system/bin/su
/system/bin/failsafe/su
/system/xbin/su
/system/xbin/busybox
/system/sd/xbin/su
/data/local/su
/data/local/xbin/su
/data/local/bin/su

2.常见root权限的应用程序及其相关文件和目录的包文件。

/system/app/Superuser.apk
/system/etc/init.d/99SuperSUDaemon
/dev/com.koushikdutta.superuser.daemon/
/system/xbin/daemonsu

3.检查已安装的应程序包。

com.thirdparty.superuser
eu.chainfire.supersu
com.noshufou.android.su
com.koushikdutta.超级用户
com.zachspong.temprootremovejb
com.ramdroid.appquarantine
com.topjohnwu.magisk

这里可以使用Frida脚本进行绕过:

1678353840_6409a5b082f5520e57643.jpg!small?1678353835151

图3.3:frida脚本绕过

1678353856_6409a5c0681c5a796074e.jpg!small?1678353850989

图3.4:绕过成功

此外,还可以反编译分析源码,找到检测root的关键函数,编写Hook脚本进行绕过。如某银行app中提取到的root检测代码,可以看到如果检测到开启了root权限,则返回为true,因此可以修改函数返回值为false来绕过。

1678353868_6409a5ccb82a09fa704fd.jpg!small?1678353863086

图3.5:检测root代码

3.4.2APP请求体加密处理

项目中遇到了某金融APP,截取请求包,发现请求体部分进行了加密处理,如下图所示:

1678353891_6409a5e3a18bfdf610783.jpg!small?1678353886030

图3.6:请求体被加密

这种情况对渗透攻防来说,会非常困难,如果无法修改请求包数据,则不能进行深入测试和利用,所以需要解决请求数据加密问题。主要有2种方式:

第一种:反编译apk,找出加密函数,获取密钥,然后利用burp进行自动加解密操作;

第二种:Hook传递明文信息的函数(此处的Hook不一定非要找到加解密函数,只需要找到传递明文数据的某个函数即可)。

这里因为apk使用了某企业级加固,直接用脱壳机脱壳,过程就不阐述了,然后在adb shell中打印最顶层的activity,找到有关的activity类。

dumpsys activity | grep "mFocusedActivity"s  -------android8以下
dumpsys activity | grep "mResumedActivity"   ---------android8及以上

1678353902_6409a5eec0377bf72ad1e.jpg!small?1678353897049

图3.7:打印activity

在jadx里进行跟踪分析:

1678353911_6409a5f755e4bb8329c0f.jpg!small?1678353906350

图3.8:jadx跟踪分析

经过Hook测试,kk.c传递的是请求url,与加密无关,然后继续测试d.a方法,先查看d.a的声明处,里面有很多重载的方法,我们挑重要的内容看,当然不嫌麻烦可以挨个Hook确认,我们在图3.12这个a方法中看到了setbody函数,初步确定该方法是用于设置请求体的内容,而b2是b方法的返回值:

1678353921_6409a60133d0166b65b6a.jpg!small?1678353916274

图3.9:jadx跟踪分析

进一步查看b方法:

1678353927_6409a60795cfff4dd8f90.jpg!small?1678353922198

图3.10:jadx跟踪分析

编写Hook代码,打印b方法的两个参数,获取请求体明文数据。

1678353936_6409a610125bbd42a95ea.jpg!small?1678353930508

图3.11:Hook代码

1678353947_6409a61b7984c7ef8c7de.jpg!small?1678353942191

图3.12:打印明文

3.4.3 APP获取隐私数据合规检测

这里使用Frida来实现,因为Frida可以很方便的Hook Android系统的java层和Native层函数,因此可以总结出所有和隐私信息收集相关的系统函数,编写Frida脚本对APP进行行为监测,查看是否存在隐私信息收集行为。隐私收集API示例如下:

hook('android.telephony.TelephonyManager', [
        // Android 8.0
        {'methodName': 'getDeviceId', 'action': action, 'messages': '获取IMEI'},
        // Android 8.1、9   android 10获取不到
        {'methodName': 'getImei', 'action': action, 'messages': '获取IMEI'},
        {'methodName': 'getLine1Number', 'action': action, 'messages': '获取电话号码标识符'},
        {'methodName': 'getSimSerialNumber', 'action': action, 'messages': '获取IMSI/iccid'},
        {'methodName': 'getSubscriberId', 'action': action, 'messages': '获取IMSI'},
        {'methodName': 'getSimCountryIso', 'action': action, 'messages': '获取SIM卡国家代码'},
        {'methodName': 'getCellLocation', 'action': action, 'messages': '获取电话当前位置信息'},
        {'methodName': 'getAllCellInfo', 'action': action, 'messages': '获取电话当前位置信息'},
        {'methodName': 'requestCellInfoUpdate', 'action': action, 'messages': '获取基站信息'},
]);

以上只列举了部分隐私收集API,如常见的获取收集IMEI号的getDeviceId函数、获取本机号码的getLine1Number函数以及获取IMSI的getSubscriberId函数等,都可以通过Frida Hook来进行监测。在应用宝中任意下载一款APP,然后安装到模拟器中,如下图所示。

1678354046_6409a67e487c970459a74.jpg!small?1678354040558

图3.13 腾讯应用宝截图

然后在模拟器中启动frida_server,开启端口转发,运行Frida实现隐私函数调用监测。监测结果如下:

1678354057_6409a689eeb3dc210a352.jpg!small?1678354052228

图3.14 隐私函数API监测结果

不同的APP调用系统隐私数据收集函数的种类不同,但是都可以通过Frida框架来监测,从而检测APP是否合规。

3.4.4 病毒木马分析

Hook技术同样可以用于病毒木马分析,因为它不仅可以用于API监测,还可以用于加密算法解密,甚至可以用于制作沙箱。这在病毒木马分析中也非常有用,如果是锁屏勒索木马,则可以通过Hook来获取解锁密码,省去了逆向分析的繁琐过程,大大提升了解锁的效率。

这里以某锁屏病毒为例,用PKID查壳发现该病毒未使用加固保护,于是直接用jadx反编译得到源码,分析AndroidManifest.xml文件得到,该病毒入口为MainActivity,里面只启动了一个服务Myservice,继续分析该服务代码,找到解锁算法代码在m6L函数中,如下图所示:

1678354085_6409a6a52cc940eaf02bd.png!small?1678354079307

图3.15 Myservice的onCreate函数代码

继续分析发现使用了复杂的加密算法,但是设置了一个监听事件,并且在该监听事件中会校验输入的解锁密码是否正确,于是这里就可以编写Hook脚本获取解锁密码了。这里Hook到相应参数后,需要进行简单的运算,算法如下,this$0.f6ck为界面显示的识别码。

(this$0.f6ck除以val$Admin)异或m2sb(f37val$) 

1678354131_6409a6d3677ef68e4d832.jpg!small?1678354125706

图3.16 解锁密码验证代码

1678354139_6409a6dbaeafd5450cb81.jpg!small?1678354133867

图3.17 锁机病毒界面

m2sb函数源码如下所示:

public static int m2sb(int i) {
        int i2 = i;
        if (i2 < 2) {
            return i2;
        }
        int i3 = 1;
        int i4 = 65537 / i2;
        int i5 = 65537 % i2;
        while (i5 != 1) {
            int i6 = i2 / i5;
            i2 %= i5;
            i3 = (i3 + (i4 * i6)) & 65530;
            if (i2 == 1) {
                return i3;
            }
            int i7 = i5 / i2;
            i5 %= i2;
            i4 = (i4 + (i3 * i7)) & 65531;
        }
        return (1 - i4) & 65532;
}

最终Hook出解锁密码如下图所示。

1678354177_6409a70180c34fb81072c.jpg!small?1678354171626

图3.18 Hook结果

Hook还可以用于制作安卓沙箱,对获取root权限、sdcard操作以及获取用户敏感信息等系统函数进行监测,分析病毒木马的行为,类似于微步沙箱的功能。在纯逆向分析没有头绪时,可以带来意想不到的收获,对于病毒木马分析起到非常好的辅助作用。

根据对Hook技术的原理和框架的介绍,并结合示例分析,不难发现无论是在渗透攻防还是安全分析与测试过程中,Hook技术都可以提供非常有价值的支撑。不仅能绕过系统检测、获取函数关键参数,病毒木马分析方面也有着突出的贡献,而且在APP安全测试中,亦可用此方法对隐私数据收集函数进行监测,从而实现APP隐私数据合规检测。

《Android安全技术揭秘与防范》

《Android软件安全权威指南》

https://codeshare.Frida.re/@dzonerzy/Fridantiroot/

https://redfoxsec.com/blog/android-root-detection-bypass-using-frida/

https://www.cnblogs.com/xsj210/p/15774406.html

https://github.com/WooyunDota/DroidSSLUnpinning

https://mabin004.github.io/2018/07/31/Mac%E4%B8%8A%E7%BC%96%E8%AF%91Frida/

https://github.com/asLody/VirtualApp

观宇战队

新华三观宇战队,专注前沿防御技术研究,研究方向包括漏洞分析、攻击反制、病毒木马分析、APT分析等,长期招聘攻防研究员,简历投递:[email protected](请注明来自FreeBuf)


文章来源: https://www.freebuf.com/articles/mobile/359925.html
如有侵权请联系:admin#unsafe.sh