Android应用程序:绕过SSL pinning

2019-08-28 约 3754 字 预计阅读 8 分钟

声明:本文 【Android应用程序:绕过SSL pinning】 由作者 落花四月 于 2019-08-28 09:00:00 首发 先知社区 曾经 浏览数 135 次

感谢 落花四月 的辛苦付出!

Android应用程序:绕过SSL pinning

原文链接: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。

关键词:[‘安全技术’, ‘移动安全’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now