hook框架-frida绕过app签名校验

0x1 签名校验

  1.介绍

为了防止app被次打包,通常会进行签名校验,当app被修改并重新签名后,签名信息与原来的签名信息不一致,导致app不能正常运行

0x2 查看签名信息

  1.获取签名信息

keytool -printcert -jarfile app-debug.apk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

C:\Users\LENOVO\Desktop>keytool -printcert -jarfile app-debug.apk

签名者 #1:

签名:

所有者: C=US, O=Android, CN=Android Debug

发布者: C=US, O=Android, CN=Android Debug

序列号: 1

生效时间: Thu Dec 30 19:07:22 CST 2021, 失效时间: Sat Dec 23 19:07:22 CST 2051

证书指纹:

         SHA1: 4C:D7:B7:FB:D5:03:36:24:02:91:A4:55:3A:44:16:A9:DF:F1:56:09

         SHA256: 18:B9:03:E7:4C:51:A6:26:98:2B:C2:54:7A:9C:0E:69:BB:49:A3:D1:6F:00:B1:73:9C:89:8A:B5:21:F2:53:CA

签名算法名称: SHA1withRSA (弱)

主体公共密钥算法: 2048 位 RSA 密钥

版本: 1

Warning:

证书 使用的 SHA1withRSA 签名算法被视为存在安全风险。此算法将在未来的更新中被禁用。

  2.遇到这种有签名校验的,就不能通过修改代码,重新编译对它进行篡改了,这个时候就需要使用frida对它动态修改了。

0x3 绕过签名校验

  1.反编译找到签名校验的关键点

反编译apk文件,来找到签名校验的关键点,也就是它使用了哪个函数来实现的这个签名校验.

  2.编写hook代码

找到这个类和函数之后就可以编写hook代码对它的函数进行一个动态的修改.

  3.注入js

最后就可以通过frida来加载我们的js脚本对app进行注入达到绕过签名校验的目的.

0x4 实战

  1.安装vs code,点扩展,搜索frida Workbench安装,然后新建一个js文件,就可以开始编写hook代码了。

  2.frida官网js hook安卓的例子.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

Java.perform(function () {

  // Create an instance of java.lang.String and initialize it with a string

  var JavaString = Java.use('java.lang.String');

  var exampleString1 = JavaString.$new('Hello World, this is an example string in Java.');

  console.log('[+] exampleString1: ' + exampleString1);

  console.log('[+] exampleString1.length(): ' + exampleString1.length());

  // Create an instance of java.nio.charset.Charset, and initialize the default character set

  var Charset = Java.use('java.nio.charset.Charset');

  var charset = Charset.defaultCharset();

  // Create a byte array of a Javascript string

  var charArray = 'This is a Javascript string converted to a byte array.'.split('').map(function(c) {

    return c.charCodeAt(0);

  });

  // Create an instance of java.lang.String and initialize it through an overloaded $new,

  // with a byte array and a instance of java.nio.charset.Charset

  var exampleString2 = JavaString.$new.overload('[B', 'java.nio.charset.Charset').call(JavaString, charArray, charset)

  console.log('[+] exampleString2: ' + exampleString2);

  console.log('[+] exampleString2.length(): ' + exampleString2.length());

  // Intercept the initialization of java.lang.Stringbuilder's overloaded constructor,

  // and write the partial argument to the console

  var StringBuilder = Java.use('java.lang.StringBuilder');

  // We need to replace .$init() instead of .$new(), since .$new() = .alloc() + .init()

  var ctor = StringBuilder.$init.overload('java.lang.String');

  ctor.implementation = function (arg) {

    var partial = '';

    var result = ctor.call(this, arg);

    if (arg !== null) {

      partial = arg.toString().replace('\n', '').slice(0, 10);

    }

    // console.log('new StringBuilder(java.lang.String); => ' + result);

    console.log('new StringBuilder("' + partial + '");');

    return result;

  };

  console.log('[+] new StringBuilder(java.lang.String) hooked');

  // Intercept the toString() method of java.lang.StringBuilder and write its partial contents to the console.

  var toString = StringBuilder.toString;

  toString.implementation = function () {

    var result = toString.call(this);

    var partial = '';

    if (result !== null) {

      partial = result.toString().replace('\n', '').slice(0, 10);

    }

    console.log('StringBuilder.toString(); => ' + partial);

    return result;

  };

  console.log('[+] StringBuilder.toString() hooked');

});

  3.使用Androidkiller反编译一下,打开Androidmanifest.xml文件,找到主界面,搜索一下MainActivity主界面.

  4.在smali代码中看到了两个关键的函数调用.

1

2

invoke-static {}, Lcom/example/kctf_frida/rootcheck;->checkRootPathSU()Z

invoke-virtual {v0}, Lcom/example/kctf_frida/SignCheck;->check()Z

  5.接下来仿照示例编写js脚本:

1

2

3

4

5

6

7

8

9

10

11

12

Java.perform(function ()  //固定格式

{

    var hook = Java.use('com.example.kctf_frida.rootcheck');//先找到hook的类

    hook.checkRootPathSU.implementation = function () {//在找到hook的方法

        return false;//修改返回值

    }

    var hook = Java.use('com.example.kctf_frida.SignCheck');//先找到hook的类

    hook.check.implementation = function () {//在找到hook的方法

        return true;//修改返回值

    }

})

  6.按照上节课的方法进行注入:

1)打开shell窗口

1

2

3

4

5

mount -o rw,remount /

chmod +x /sbin/frida-server

frida-server

2)打开cmd窗口

1

2

3

adb push frida-server /sbin

frida -U -f com.example.kctf_frida --no-pause -l new_file.js

  7.成功绕过签名校验和root检测。

<think>嗯,用户想知道如何绕过APK签名校验机制。首先,我得回忆一下APK签名的作用。APK签名主要是为了验证应用在发布后没有被篡改,确保应用的完整性。如果用户想绕过这个机制,可能有几种方法,比如修改APK后重新签名,但系统会测到签名不一致,导致安装失败或者运行时校验失败。 根据提供的引用内容,引用[1]提到verifiedEntries找不到新添加的文件,导致返回null。这可能涉及到在签名后添加文件,从而绕过签名查。另外,引用[2]和[3]提到了替换public_key的方法,可能是在反编译后的代码中找到签名相关的部分,替换正确的公钥,或者通过抓包修改网络请求中的验证信息。引用[4]和[5]则涉及重打包和修改返回值,比如hook方法返回特定的路径,欺骗签名查。 首先,我需要整理这些方法。可能的方法包括:重打包时处理签名校验逻辑、修改验证相关的代码或资源、网络验证的中间人攻击、动态Hook技术,以及通过注入文件来绕过校验。每种方法的具体步骤需要详细说明,比如反编译APK、定位签名校验代码、修改smali代码或资源文件,然后重新打包签名。同时,需要注意这些方法的实现细节,比如如何找到关键代码位置,如何处理签名后的文件添加,或者如何Hook系统方法返回伪造的信息。 另外,用户可能需要了解这些方法的原理和潜在风险,比如可能违反法律法规,或导致应用不稳定。因此,在回答中需要强调这些注意事项,并建议仅用于合法授权的研究。同时,要确保步骤清晰,比如分步骤说明如何反编译、修改、重打包,以及可能用到的工具如apktool、Frida等。 还需要考虑用户的实际操作中可能遇到的问题,比如如何定位签名校验的代码位置,如何正确替换公钥,或者如何配置抓包工具来拦截和修改网络请求。引用中的例子提供了具体的代码修改点,比如修改getPackageCodePath的返回值,这需要用户具备一定的逆向工程和编程能力。 总结起来,回答需要分步骤介绍不同方法,结合引用中的具体案例,说明每种方法的操作流程,并提醒用户注意法律和安全问题。同时,生成的相关问题要围绕这些方法的应用、测和防御展开,帮助用户进一步理解相关技术。</think>### 绕过APK签名校验的常见方法 #### 1. **修改签名校验逻辑(代码层绕过)** - **原理**:APK签名校验通常通过对比当前APK签名与预置的合法签名是否一致来实现。若直接修改校验逻辑(例如强制返回`true`),可绕过测。 - **步骤**: 1. 使用反编译工具(如`apktool`)解包APK,定位签名校验代码。通常搜索关键词如`signatures`、`getPackageInfo`、`verify`等[^2]。 2. 修改`smali`代码或`Java`逻辑,使校验函数直接返回合法值。例如: ```smali # 原代码:if-eqz v0, :cond_0 (签名是否为空) # 修改为:if-nez v0, :cond_0 (反向条件) ``` - **风险**:部分应用会在多个位置校验签名,需全面覆盖。 #### 2. **注入合法公钥(资源替换)** - **原理**:若应用使用预埋的公钥验证签名,可通过反编译替换合法公钥。 - **步骤**: 1. 反编译APK后,搜索`public_key`或`signature`相关资源文件。 2. 将合法APK的公钥替换到目标APK中,确保验证逻辑匹配[^3]。 - **案例**:通过抓包对比正常APK与篡改APK的`public_key`差异,替换后绕过网络验证[^3]。 #### 3. **动态Hook绕过(运行时拦截)** - **原理**:使用`Frida`或`Xposed`等工具,在运行时修改关键函数返回值。 - **步骤**: 1. Hook签名校验函数(如`getPackageCodePath`),强制返回合法APK路径: ```javascript // Frida脚本示例[^5] Java.perform(function () { Java.use("android.content.ContextWrapper").getPackageCodePath.implementation = function () { return "/data/app/合法APK路径/base.apk"; }; }); ``` 2. 绕过校验后加载篡改后的APK。 #### 4. **签名后注入文件(Jar漏洞利用)** - **原理**:Android的`JarVerifier`在校验时依赖`verifiedEntries`列表。若在签名后添加新文件,该校验会失败但可能被忽略[^1]。 - **步骤**: 1. 对已签名APK追加新文件(如`assets/`目录下的资源)。 2. 修改代码逻辑,使应用加载新增文件时不触发校验。 #### 5. **网络验证中间人攻击** - **原理**:若签名校验依赖服务端验证,可通过抓包篡改响应。 - **步骤**: 1. 使用抓包工具(如`Charles`)拦截验证请求。 2. 替换响应中的签名验证结果字段(如`"valid": true`)[^3]。 --- ### 注意事项 1. **法律风险**:绕过签名校验可能违反《计算机软件保护条例》,仅限合法授权场景使用。 2. **兼容性问题**:修改后的APK可能因签名失效导致部分功能异常(如支付、地图SDK)。 3. **对抗加固**:若APK被混淆或加固(如360加固),需先脱壳再修改。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值