frida - frida 一个超强的钩子工具,可以任意篡改程序返回的数据. 安装 和使用 (绕过https ssl )

访问量: 837

参考: https://frida.re/docs/

frida可以监控某个进程,修改进程的入口, 修改执行的内容. 特别强大

在反编译的过程中会被使用. 

例子不说了.

不过在我的本机上, 运行前面的单机例子没问题, 运行 Android的例子就不行了. 

安装 : 要使用pip3 来安装

PC端:

$ pip3 install frida-tools (需要先安装好python 3 )

C:\Users\luelue>pip3 install frida-tools
Collecting frida-tools
  Downloading frida-tools-10.4.1.tar.gz (43 kB)
     |████████████████████████████████| 43 kB 212 kB/s
Collecting colorama<1.0.0,>=0.2.7
  Downloading colorama-0.4.4-py2.py3-none-any.whl (16 kB)
Collecting frida<16.0.0,>=15.0.0
  Downloading frida-15.1.8.tar.gz (9.1 kB)
Collecting prompt-toolkit<4.0.0,>=2.0.0
  Downloading prompt_toolkit-3.0.21-py3-none-any.whl (374 kB)
     |████████████████████████████████| 374 kB 312 kB/s
Collecting pygments<3.0.0,>=2.0.2
  Downloading Pygments-2.10.0-py3-none-any.whl (1.0 MB)
     |████████████████████████████████| 1.0 MB 467 kB/s
Requirement already satisfied: setuptools in c:\users\luelue\appdata\local\programs\python\python39\lib\site-packages (from frida<16.0.0,>=15.0.0->frida-tools) (49.2.1)
Collecting wcwidth
  Downloading wcwidth-0.2.5-py2.py3-none-any.whl (30 kB)
Using legacy 'setup.py install' for frida-tools, since package 'wheel' is not installed.
Using legacy 'setup.py install' for frida, since package 'wheel' is not installed.
Installing collected packages: colorama, frida, wcwidth, prompt-toolkit, pygments, frida-tools
    Running setup.py install for frida ... done
    Running setup.py install for frida-tools ... done
Successfully installed colorama-0.4.4 frida-15.1.8 frida-tools-10.4.1 prompt-toolkit-3.0.21 pygments-2.10.0 wcwidth-0.2.5

然后下载  frida-server: (注意,这个frida-server是安装到安卓端的,并且需要跟 PC端的frida的版本相对应)

https://github.com/frida/frida/releases/download/15.1.8/frida-core-devkit-15.1.8-android-arm64.tar.xz

下载后解压缩,  然后 

$ 解压缩,把里面的文件 拿出来,例如叫  frida-server-android    

$ unxz  frida-server ..xz 

$ adb push frida-server-android /data/local/tmp/

$ adb root   (这里见我另外一篇文章 挨着本文) 

$ cd /data/local/tmp 

merlin:/data/local/tmp # su root  (这一步特别关键! 否则会server 启动失败) 

merlin:/data/local/tmp # chmod 755 frida-server-14.2.13-android-arm64 

merlin:/data/local/tmp # ./frida-server-14.2.13-android-arm64  -v  (建议首次运行时,一定要输入  -v ,  verbose 的意思)

总之就是执行上面的文件. 

然后在PC端 直接 : 

$ frida-ps -U 就可以看到结果

问题3. 如果frida-ps -U 不好用的话,就参考这里:https://github.com/frida/frida/issues/582

1. 在server端(android端),运行时,每次都要 su root  再运行

2. 在server端,ifconfig, 查看当前 android的ip, 然后  ./frida-server-15.1.8-android-arm64 -l 192.168.0.101 -v

3. 保证 client(windows/linux) 跟android在同一个局域网内.  然后 frida-ps --host 192.168.0.101

就可以了。

问题1:  提示: Failed to enumerate processes: unable to connect to remote frida-server: Unexpected lack of content trying to read a line

参考:https://stackoverflow.com/questions/62171745/frida-server-unable-to-connect/66652303#66652303

或者参考: https://github.com/frida/frida/issues/764

解决办法:  执行 frida-server 之前,务必 # su root  ,  (你可以先试着ifconfig , 看看是否有权限,不要相信你安装的adb root ) 

问题2  unable to access zygote64 while preparing for app launch; try disabling Magisk Hide in case it is active

参考: https://stackoverflow.com/questions/56316329/frida-failed-to-spawn-unable-to-access-zygote64-while-preparing-for-app-launc

1. magisk -> settings -> Magisk -> MagiskHide , 要关掉.  否则会引起:

2. 无论你是否在magisk 中安装了 magisk adb root,  在进入到adb shell 之后, 执行 frida-server之前,都需要手动切换成root:  $ su root 

之后再执行 frida-server -v 

在我的机器上, frida-ps -U的结果如下:

$ frida-ps -U
  PID  Name
-----  ---------------------------------------------------
14312  adbd
  412  aee_aed
  413  aee_aed64
  414  aee_aedv
  415  aee_aedv64
 9175  android.ext.services
 8444  android.hardware.audio@5.0-service-mediatek
  766  android.hardware.biometrics.fingerprint@2.1-service
  576  android.hardware.bluetooth@1.0-service-mediatek
  577  android.hardware.cas@1.1-service
  578  android.hardware.configstore@1.1-service
  579  android.hardware.drm@1.0-service
  580  android.hardware.drm@1.2-service.clearkey
  581  android.hardware.drm@1.2-service.widevine
  582  android.hardware.gatekeeper@1.0-service
  583  android.hardware.gnss@2.0-service-mediatek
  .... 还有好多

使用: 绕过android https ( ssl 的验证)

假设,我们通过安卓逆向, 获得了目标app 的源代码, 对应校验证书的代码为: 

package com.<target>.utilslibrary.retrofit;

import android.content.Context;
import java.io.BufferedInputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import okhttp3.at;

public class a { 
  public static void a(Context paramContext, at paramat) {
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    BufferedInputStream bufferedInputStream = new BufferedInputStream(paramContext.getAssets().open("certs/cert.crt"));
    Certificate certificate = certificateFactory.generateCertificate(bufferedInputStream);
    bufferedInputStream.close();
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", certificate);
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(keyStore);
    SSLContext sSLContext = SSLContext.getInstance("TLS");
    sSLContext.init(null, trustManagerFactory.getTrustManagers(), null);
    paramat.a(sSLContext.getSocketFactory(), new b(certificate));
  }
}


创建一个脚本

import frida, sys, time

# 该方法仅仅用于调试
def on_message(message, data):
    print("=== in on_message")
    print(message)
    print(data)

# 这段是核心代码,多行javascript.
jscode = """
Java.perform(function () {
  // 这里用的是class 的全名(package + class)
  var target_class = Java.use('com.target.utilslibrary.retrofit.a');

  // 这里的 target_class.a 就是我们需要绕过的方法
  var the_method = target_class.a;

  // 这里是对方法进行实现
  the_method.implementation = function (p1, p2) {
    // 该方法的实现中,没有任何内容.也就是说, 不做任何SSL证书的校验
  };
});
"""

device = frida.get_usb_device()

# 根据android package名字来唤醒对应的app

pid = device.spawn(["com.target.wallets"])  // 修改成你的目标app package
device.resume(pid)

# 进程停止1秒钟.让该APP启动
time.sleep(1)

script = device.attach(pid).create_script(jscode)

script.on('message', on_message)
print('==== script start ...')

script.load()
sys.stdin.read()

订阅/RSS Feed

Subscribe