Android应用程序:绕过SSL pinning
2019-08-28 10:00:00 Author: xz.aliyun.com(查看原文) 阅读量:293 收藏

原文链接:https://medium.com/@ved_wayal/hail-frida-the-universal-ssl-pinning-bypass-for-android-e9e1d733d29

大家好,在这篇文章中,我将解释如何使用frida框架绕过任何Android应用程序的SSL pinning,我会尝试更详细地解释其中的细节。

本文将介绍:

  1. 介绍Frida和SSL pinning

  2. 要求

  3. 设置和安装

  4. Frida服务器设置

  5. 设置BurpSuite

  6. 配置代理的CA证书

  7. 脚本注入绕过SSL pinning

  8. 总结

  9. 故障排除

1. 介绍Frida和SSL pinning

Frida框架是SSL pinning绕过的最后一站。

根据frida 网站的描述:

对于应用程序来说,这是Greasemonkey,或者,在更多技术术语中,它是一个动态代码检测工具包。它允许你将JavaScript或你自己的库中的代码注入Windows,macOS,GNU/Linux,iOS,Android和QNX上的应用程序。Frida还为你提供了一些基于Frida API构建的简单工具。这些可以按原样使用,根据你的需要进行调整,或作为如何使用API​​的示例。

如今,大多数应用程序在其移动应用程序中实现SSL pinning技术。这是为什么?因为我们想要在我们的设备和服务器之间安全地交换一些数据,虽然,SSL传输层加密将使数据传输安全可靠?但是,有一个问题,在数据传输之前,如果服务器的SSL证书与请求的主机名和受信任的根证书匹配,则客户端会检查该证书。

它不能确保提供的证书是服务器为请求的主机名提供的实际证书。因此,依赖设备的可信存储证书不会使数据传输“安全”。

证书锁定是应用程序本身内远程服务器信任的硬编码证书,因此它将忽略设备证书存储,并将信任他自己的硬编码证书,进一步的应用程序将用于“安全地”与远程服务器通信。

当我们甚至开始对大多数移动应用程序的HTTP请求进行动态分析时,绕过SSL pinning是需要完成的主要步骤,因为我们更关注数据隐私以及通过网络从中间人(MiTM)攻击等线程安全传输数据。

Frida是一个框架,它为本机应用程序注入脚本,以便在运行时操作应用程序的逻辑,这对于测试移动应用程序来说是更具动态性的。

2. 要求

这种设置第一次需要一些时间,因为需求的信息很多。一旦我们完成所有设置,从下次开始它将是一件很简单的事情。如果你安装过程中出现问题,博客末尾会出现“ 疑难解答 ”部分。

I. Rooted device/emulator:

我们需要一个有rooted device或者是rooted emulator,因为我们需要将脚本注入设备的根目录。由于Genymotion易于设置和使用,所以,现在很多人都使用Genymotion,可以从下面下载。

https://www.genymotion.com/fun-zone/

一旦我们完成安装genymotion,我们需要安装一个Android设备。Android 7+版本将不错。我将使用具有以下配置的“ Google pixel XL”设备。

II. Python frida包安装

从这里安装Python for Windows

我们需要为frida服务器安装一些python包。为此在终端中输入以下命令:

python -m pip install Frida
python -m pip install objection
python -m pip install frida-tools
or
pip install Frida
pip install objection
pip install frida-tools

III.平台工具(adb)

从以下链接下载用于Windows的平台工具

IV.下载注入脚本:

我们需要从下面下载注入脚本,我们将把这个脚本注入目标应用程序的设备

或者你可以将此代码保存为与adb相同的文件夹中的fridascript.js。

/* 
   Android SSL Re-pinning frida script v0.2 030417-pier
$ adb push burpca-cert-der.crt /data/local/tmp/cert-der.crt
   $ frida -U -f it.app.mobile -l frida-android-repinning.js --no-pause
https://techblog.mediaservice.net/2017/07/universal-android-ssl-pinning-bypass-with-frida/

   UPDATE 20191605: Fixed undeclared var. Thanks to @oleavr and @ehsanpc9999 !
*/
setTimeout(function(){
Java.perform(function (){
 console.log("");
 console.log("[.] Cert Pinning Bypass/Re-Pinning");
var CertificateFactory = Java.use("java.security.cert.CertificateFactory");
 var FileInputStream = Java.use("java.io.FileInputStream");
 var BufferedInputStream = Java.use("java.io.BufferedInputStream");
 var X509Certificate = Java.use("java.security.cert.X509Certificate");
 var KeyStore = Java.use("java.security.KeyStore");
 var TrustManagerFactory = Java.use("javax.net.ssl.TrustManagerFactory");
 var SSLContext = Java.use("javax.net.ssl.SSLContext");
// Load CAs from an InputStream
 console.log("[+] Loading our CA...")
 var cf = CertificateFactory.getInstance("X.509");

 try {
  var fileInputStream = FileInputStream.$new("/data/local/tmp/cert-der.crt");
 }
 catch(err) {
  console.log("[o] " + err);
 }

 var bufferedInputStream = BufferedInputStream.$new(fileInputStream);
var ca = cf.generateCertificate(bufferedInputStream);
 bufferedInputStream.close();
var certInfo = Java.cast(ca, X509Certificate);
 console.log("[o] Our CA Info: " + certInfo.getSubjectDN());
// Create a KeyStore containing our trusted CAs
 console.log("[+] Creating a KeyStore for our CA...");
 var keyStoreType = KeyStore.getDefaultType();
 var keyStore = KeyStore.getInstance(keyStoreType);
 keyStore.load(null, null);
 keyStore.setCertificateEntry("ca", ca);

 // Create a TrustManager that trusts the CAs in our KeyStore
 console.log("[+] Creating a TrustManager that trusts the CA in our KeyStore...");
 var tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
 var tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
 tmf.init(keyStore);
 console.log("[+] Our TrustManager is ready...");
console.log("[+] Hijacking SSLContext methods now...")
 console.log("[-] Waiting for the app to invoke SSLContext.init()...")
SSLContext.init.overload("[Ljavax.net.ssl.KeyManager;", "[Ljavax.net.ssl.TrustManager;", "java.security.SecureRandom").implementation = function(a,b,c) {
  console.log("[o] App invoked javax.net.ssl.SSLContext.init...");
  SSLContext.init.overload("[Ljavax.net.ssl.KeyManager;", "[Ljavax.net.ssl.TrustManager;", "java.security.SecureRandom").call(this, a, tmf.getTrustManagers(), c);
  console.log("[+] SSLContext initialized with our custom TrustManager!");
 }
});
},0);

3. 设置和安装

I.将设备连接到adb:

我们需要将设备连接到adb上,可以在设备上运行命令。但首先转到设置--->开发人员选项并在设备中启用调试模式,以便adb可以与设备通信。
转到已提取平台工具的文件夹,然后运行以下命令将设备连接到adb

//adb connect <ip of device:port>
adb connect 192.168.1.190:5555

如果设备中出现弹出窗口,请单击“允许”。

要检查设备是否已连接到adb:adb devices

你可以看到设备的IP以及设备名称

II.下载frida服务器以获得支持的android设备的arch版本:

我们需要根据我们设备的arch版本为我们的Android设备下载frida服务器软件包

要查找设备的arch版本,请运行以下命令:adb shell getprop ro.product.cpu.abi

如果设备配置与上面提到的相同,请缩短下载时间:

frida-server-12.4.7-android-x86.xz
frida-server-12.4.7-android-x86_64.xz

IV. 在设备中安装目标应用程序

安装必须在我们的设备中绕过SSL pinning的应用程序。打开应用程序并使其在后台运行。

4. Frida服务器设置:

我们需要在注入脚本之前将frida服务器运行到设备中。请按照以下步骤操作:

I.将frida-server推入设备:

现在我们需要将我们的frida-server文件推送到设备中。复制adb文件夹中的“frida-server-12.4.7-android-x86.xz”文件并运行以下命令

//adb push <path_of_frida_server_folder><space></data/local/tmp>
adb push C:\ADB\frida-server /data/local/tmp

II. 授予frida-server权限:

adb shell chmod 777 /data/local/tmp/frida-server

5.设置BurpSuite:

按照这个很棒的指南在Android设备的burp中设置代理:

6.配置代理的CA证书:

为了能够拦截流量,frida需要访问我们的Burpsuite CA证书。我们将在BurpSuite Setup中配置与步骤5相同证书。

将证书推送到设备并进入与frida-server相同的位置,将其命名为cert-der.crt(因为此名称和路径已在fridascript.js中提及以避免任何问题)

// adb push <path to cacert.der> /data/local/tmp/cert-der.crt
adb push cacert.der /data/local/tmp/cert-der.crt

7.脚本注入绕过SSL pinning

我们将'fridascript.js'注入目标应用程序.

I.将fridascript.js推入设备:

将fridascript.js复制到adb文件夹并运行以下命令将fridascript.js推送到设备中。

//adb push <path_to_fridascript.js_folder> /data/local/tmp
adb push C:\ADB\fridascript.js /data/local/tmp

II.检查并运行设备中的frida服务器

adb shell /data/local/tmp/frida-server &

这将把frida-server运行到设备中。也许你不会在终端获得这个命令的任何输出。

III.列出设备上的所有正在运行的服务

现在,我们需要找出目标应用程序的ID。我们将列出设备上所有正在运行的服务,包括您的申请流程

打开新终端并输入以下命令:frida-ps -U

IV.找到您的应用程序包的名称

V.将fridascript.js注入到目标应用程序中:

最后,我们将使用以下命令将fridascript.js注入到本机应用程序中:

//frida -U -f <your_application_package_name> <path_to_fridascript.js_on_your_computer> --no-paus
frida -U -f com.twitter.com D:\ADB\fridascript.js --no-paus

VI. Bypassed!!

一旦所有事情顺利进行,目标应用程序的所有流量都将被拦截到BurpSuite中。只要我们拦截进入BurpSuite的流量,我们就需要保持frida服务器的运行。

8.总结

  1. 在genymotion上下载并安装设备
  2. 安装frida和主要工具

    python -m pip install Frida
    python -m pip install frida-tools
    python -m pip install objection
    or
    pip install Frida
    pip install frida-tools
    pip install objection

  3. 下载adb​​平台工具

  4. 下载frida注入脚本
  5. 将设备连接到adb

    //adb connect <ip of device:port>

  6. 下载frida服务器以获取支持的Android设备的arch版本

  7. 找出设备的arch版本

adb shell getprop ro.product.cpu.abi
  1. 在设备中安装目标应用程序。
  2. 将frida-server推入设备:

    //adb push <path folder="" frida-server="" of=""><space></data/local/tmp></space></path>

  3. 授予frida-server权限:

    adb shell chmod 777 /data/local/tmp/frida-server

  4. 设置burpsuite

  5. 推送代理的CA证书

    // adb push <path to cacert.der> /data/local/tmp/cert-der.crt

  6. 将fridascript.js推入设备:

    //adb push <path to fridascript.js folder> /data/local/tmp

  7. 检查并运行设备中的frida服务器

    adb shell /data/local/tmp/frida-server &

  8. 列出设备上所有正在运行的进程:

    frida-ps -U

  9. 找到应用程序的包名

  10. 将fridascript.js注入到目标应用程序中

    //frida -U -f <your_application_package_name> <path_to_fridascript.js_on_your_computer> — no-paus</your_application_package_name>

  11. 拦截BurpSuite的流量

9.故障排除

1.ADB连接失败

如果你收到这样的错误:

adb devices
adb server is out of date. killing...
cannot bind 'tcp:5037'
ADB server didn't ACK
*failed to start daemon*
error:

i. 打开环境系统属性--->高级--->环境变量

ii.单击路径并删除 C:/Android或adb工具指向的路径

iii.将所有平台工具复制到genymotion--->tools文件夹中
。创建新路径并添加genymotion--->tools文件夹的路径.

2. frida/pip不被认为是内部或外部命令

i.打开环境系统属性--->高级--->环境变量
ii.创建新路径并添加Python--->script文件夹的路径

3.将应用程序安装到设备时出现错误

i.下载转换文件

ii.将文件拖放到设备模拟器中或从恢复中刷新此文件。重启设备,你就可以拖放安装目标应用程序

4.产生失败

出现Android应用程序时不支持'argv'选项

检查计算机上的fridascript.js路径。路径可能不正确。

5.启动frida服务器但无法列出服务

断开并重新连接设备中的wifi。


文章来源: http://xz.aliyun.com/t/6102
如有侵权请联系:admin#unsafe.sh