python+Android-APP隐私合规检测-模拟器操作

标准文件:
App违法违规收集使⽤个⼈信息⾏为认定⽅法》
《移动互联网应用程序(App)收集使用个人信息自评估指南》
《关于开展纵深推进APP侵害用户权益专项整治行动的通知》工信部〔2020〕164
《移动互联网应用程序(App)系统权限申请使用指南》
《移动互联网应用程序(App)个人信息保护常见问题及处置指南》
《移动互联网应用程序(App)个人信息安全防范指引》
《常见类型移动互联网应用程序必要个人信息范围规定》
《GB/T 37964-2019 信息安全技术 个⼈信息去标识化指南》
《GB/T 35273-2020 信息安全技术 个⼈信息安全规范》
《中华人民共和国网络安全法》
《中华人民共和国数据安全法》
《中华人民共和国个人信息保护法》
《中华人民共和国消费者权益保护法》
《信息安全技术 移动互联网应用程序(App)收集个人信息基本要求》

参考(功能) : 小米开放平台、vivo开放平台
底层(行为):需要通过注入JSON,HOOK接口才能实现,目前参考该方法亲测有效。

一、python安装第三方库(前提你安装了python环境)

步骤1:打开cmd 输入以下命令:

方法一:
pip install frida
pip install frida==16.0.1  # 指定版本号
方法二:
# 豆瓣:http://pypi.douban.com/simple/
# 清华:https://pypi.tuna.tsinghua.edu.cn/simple
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple frida

注意:

1.安装过程先更新pip; pip install --upgrade pip

2.进行安装命令,安装过程中很慢的情况下,可以使用方法二或使用方法一但需要翻墙下载;

3.安装完成后,请记住你的版本号。

二、查看雷电模拟器CPU架构类型

步骤2:雷电模拟器提前打开root权限,再模拟器中进行设置。如图:

 步骤2:安装雷电模拟器,安装的过程就不再介绍了,通过adb连接模拟器,依次输入:

adb devices # 查看设置连接
adb shell # 进入调试命令
su  # 获取root权限

getprop ro.product.cpu.abi # 查看架构


打印的cpu架构类型64位x86架构。 

步骤3: 访问该地址  https://github.com/frida/frida/releases 下载对应的frida版本,python安装的是PC端frida16.0.1最好保持版本一致。如图:

解压后,拷贝至模拟器

adb push E:\雷电模拟器\leidian\frida-server-16.0.1-android-x86_64 /data/local/tmp/frida-server-16.0.1-android-x86_64

启动服务

./frida-server-16.0.1-android-x86_64

注意:若运行不成功 chmod 777 frida-server-16.0.1-android-x86_64

运行成功截图:

 三、python代码部分

这是一个使用Frida库进行Android应用程序的动态分析的Python脚本。Frida是一款强大的动态分析工具,可以用于分析和操纵应用程序的运行时行为。

以下是这个脚本的主要功能:

1. `__init__`方法:定义了一个名为`AppInstrumentation`的类,该类接受一个包名和一个脚本文件列表作为参数,并初始化一个设备和会话对象。

2. `attach`方法:连接到指定的Android设备,并启动指定的应用程序。然后,它会在设备上创建一个Frida会话,并附加到新启动的应用程序进程。

3. `detach`方法:从应用程序进程中分离Frida会话。

4. `load_script`方法:加载并注入指定的Frida脚本到应用程序进程。它首先读取脚本文件的内容,然后创建一个Frida脚本,将脚本内容注入到应用程序进程,并设置一个消息处理器来处理从脚本发送的消息。

5. `on_message`方法:处理从Frida脚本发送的消息。如果消息类型是'send',则将消息的有效载荷写入到指定的文件。

6. `run`方法:启动动态分析过程。它首先附加到应用程序进程,然后加载和注入Frida脚本,最后等待用户输入以分离从应用程序进程。

在主函数部分,它创建了一个`AppInstrumentation`对象,并运行它,开始对指定的Android应用程序进行动态分析。

需要注意的是,这个脚本需要在已经安装了Frida的环境中运行,并且需要有对应的Frida脚本文件(在这个例子中是"script.js"和"request.js")。而且,运行这个脚本的设备需要连接到一个Android设备,并且该设备上需要安装指定的应用程序。

import frida
import chardetclass AppInstrumentation(object):def __init__(self, package_name, script_files):self.package_name = package_nameself.script_files = script_filesself.device = Noneself.session = Nonedef attach(self):# 创建一个设备对象self.device = frida.get_usb_device()# 连接到目标应用程序pid = self.device.spawn([self.package_name])print(pid)self.session = self.device.attach(pid)self.device.resume(pid)def detach(self):# 分离会话if self.session:self.session.detach()def load_script(self):# 为应用程序注入 Frida 脚本for script_file in self.script_files:with open(script_file, 'rb') as f:file_content = f.read()encoding = chardet.detect(file_content)['encoding']with open(script_file, 'r', encoding=encoding) as f:script_content = f.read()script = self.session.create_script(script_content)script.on('message', self.on_message)script.load()def on_message(self, message, data):if message['type'] == 'send':payload = message['payload']# print("这是python的打印",payload)if 'java.lang.Exception' in payload:with open("script_trace.txt", "a") as f:f.write(payload + "\n")elif 'http' in payload:with open("request_trace.txt", "a") as f:f.write(payload + "\n")def run(self):self.attach()self.load_script()input('[+] Press  at any time to detach from instrumented program.\n\n')self.detach()# 应用包名
# 天之禁 com.shenwan.tzjzjps51APP_PACKAGE_NAME = "com.shenwan.tzjzjps51"
# Frida 脚本文件路径列表
SCRIPT_FILES = ["script.js", "request.js"]# 创建 AppInstrumentation 对象并运行
instrumentation = AppInstrumentation(APP_PACKAGE_NAME, SCRIPT_FILES)
instrumentation.run()

注意:

1.python是通过注入js的方式,且需要提前创建txt文档用于接收堆栈信息内容和请求数据内容request_trace.txt和script_trace.txt

2.需提前安装apk,获取包名的方式有很多方法可以百度,包的要求(未加固过的过或有反root检测、反frida、反调试的app)不可执行。

四、json代码部分

script.js文件

这是一个使用Frida库进行Android应用程序的动态分析的JavaScript脚本。它主要用于拦截和记录一些敏感的API调用,包括获取设备信息、网络信息、传感器信息、电话信息、系统属性、运行进程、剪贴板内容和WiFi信息等。

以下是这个脚本的主要功能:

1. `formatDateTime`函数和`logAndSend`函数:这两个函数用于格式化日期时间和记录日志。它们会在每次拦截API调用时被调用,以记录API调用的详细信息。

2. 对各种敏感API的拦截:这个脚本拦截了一系列敏感的API调用,包括但不限于获取应用程序信息、获取无线网络信息、获取网络接口信息、获取传感器信息、获取电话信息、获取系统属性、获取运行进程、获取剪贴板内容和获取WiFi信息等。在每次拦截API调用时,它会记录API调用的详细信息,并发送到Frida的Python端。

这个脚本需要在已经安装了Frida的环境中运行,它会在目标应用程序的进程空间内执行,拦截和记录API调用。这个脚本可以用于动态分析Android应用程序的行为,以帮助理解应用程序的运行机制,或者发现应用程序的潜在问题。

// 日期格式化
const formatDateTime = (date) => {const year = date.getFullYear().toString();const month = (date.getMonth() + 1).toString().padStart(2, '0');const day = date.getDate().toString().padStart(2, '0');const hour = date.getHours().toString().padStart(2, '0');const minute = date.getMinutes().toString().padStart(2, '0');const second = date.getSeconds().toString().padStart(2, '0');const milliseconds = date.getMilliseconds().toString().padStart(3, '0');return `${year}-${month}-${day} ${hour}:${minute}:${second}.${milliseconds}`;
};// 日志记录和发送
const logAndSend = (methodName, message) => {const currentPackage = Java.use('android.app.ActivityThread').currentPackageName();const stackTrace = Java.use('android.util.Log').getStackTraceString(Java.use('java.lang.Exception').$new());const formattedTime = formatDateTime(new Date());const logMessage = `${formattedTime} - ${currentPackage} - ${methodName} - ${message}\n${stackTrace}`;console.log(logMessage);send(logMessage);
};// android.app.ApplicationPackageManager类及方法
const PackageManager = Java.use('android.app.ApplicationPackageManager');
PackageManager.getApplicationInfoAsUser.overload('java.lang.String', 'int', 'int').implementation = function(packageName, flags, userId) {const result = this.getApplicationInfoAsUser(packageName, flags, userId);logAndSend('getApplicationInfoAsUser-获取给定(包名)应用程序信息(名称、图标、资源、权限)', `flags: ${flags}, userId: ${userId}, result: ${result}`);return result;
};PackageManager.getPackageInfoAsUser.implementation = function(packageName, flags, userId) {const result = this.getPackageInfoAsUser(packageName, flags, userId);logAndSend('getPackageInfoAsUser-获取应用(包名、flags)程序信息(版本号、版本代码、包名称等)', `flags: ${flags}, userId: ${userId}, result: ${result}`);return result;
};// android.net.wifi.WifiInfo类及方法
const WifiInfo = Java.use('android.net.wifi.WifiInfo');
WifiInfo.getSSID.implementation = function() {const result = this.getSSID();logAndSend('getSSID-获取无线网络名称信息', `result: ${result}`);return result;
};//   "02:00:00:00:00:00" 是一种特殊的 MAC 地址,称为“未知的”或“空的”MAC地址。它通常用于表示 MAC 地址未知或未配置。
WifiInfo.getMacAddress.implementation = function() {const result = this.getMacAddress();logAndSend('getMacAddress-获取WLAN网卡设备硬件地址', `result: ${result}`);return result;
};
WifiInfo.getBSSID.implementation = function() {const result = this.getBSSID();logAndSend('getBSSID-获取WLAN路由器设备地址', `result: ${result}`);return result;
};// android.net.NetworkInfo类及方法
const NetworkInfo = Java.use('android.net.NetworkInfo');
NetworkInfo.getTypeName.implementation = function() {const result = this.getTypeName();logAndSend('getTypeName-网络类型的名称', `result: ${result}`);return result;
};
NetworkInfo.getType.implementation = function() {
const result = this.getType();logAndSend('getType-获取当前连接wifi类型', `result: ${result}`);return result;
};// java.net.NetworkInterface类及方法
const NetworkInterface = Java.use('java.net.NetworkInterface');
NetworkInterface.getNetworkInterfaces.implementation = function() {const result = this.getNetworkInterfaces();const array = [];while (result.hasMoreElements()) {const obj = result.nextElement();const networkInterface = Java.cast(obj, NetworkInterface);array.push({name: networkInterface.getName(),  //网络接口的名称displayName: networkInterface.getDisplayName(), // 网络接口的显示名称hardwareAddress: networkInterface.getHardwareAddress(), // 网络接口的硬件地址,也就是 MAC 地址mtu: networkInterface.getMTU(), // 网络接口的最大传输单元 (MTU) 大小isLoopback: networkInterface.isLoopback(), // 网络接口是否是环回接口 (loopback interface),用于本机回环通信isPointToPoint: networkInterface.isPointToPoint(), // 网络接口是否是点对点接口 (point-to-point interface)isUp: networkInterface.isUp(),  // 网络接口是否启用 (up),表示网络接口是否正在使用isVirtual: networkInterface.isVirtual(), // 网络接口是否是虚拟接口 (virtual interface),例如 VPN、tun 等等});}logAndSend('getNetworkInterfaces-获取网络接口列表', `result: ${JSON.stringify(array, null, 2)}`);return array;
};
NetworkInterface.getHardwareAddress.implementation = function() {
const result = this.getHardwareAddress();logAndSend('getHardwareAddress-获取网络接口硬件地址信息', `result: ${result}`);return result;
};// android.hardware.SensorManager类及方法
const SensorManager = Java.use('android.hardware.SensorManager');
SensorManager.getSensorList.implementation = function(type) {const result = this.getSensorList(type);// 获取所有可用的传感器-1,TYPE_ACCELEROMETER: 1,TYPE_MAGNETIC_FIELD: 2,TYPE_ORIENTATION: 3 (弃用),TYPE_GYROSCOPE: 4,TYPE_LIGHT: 5,TYPE_PRESSURE: 6,TYPE_TEMPERATURE: 7,TYPE_PROXIMITY: 8,TYPE_GRAVITY: 9,TYPE_LINEAR_ACCELERATION: 10,TYPE_ROTATION_VECTOR: 11,TYPE_RELATIVE_HUMIDITY: 12,TYPE_AMBIENT_TEMPERATURE: 13,TYPE_MAGNETIC_FIELD_UNCALIBRATED: 14,TYPE_GAME_ROTATION_VECTOR: 15,TYPE_GYROSCOPE_UNCALIBRATED: 16,TYPE_SIGNIFICANT_MOTION: 17,TYPE_STEP_DETECTOR: 18,TYPE_STEP_COUNTER: 19,TYPE_GEOMAGNETIC_ROTATION_VECTOR: 20,TYPE_HEART_RATE: 21,TYPE_POSE_6DOF: 28,TYPE_STATIONARY_DETECT: 29,TYPE_MOTION_DETECT: 30,logAndSend('getSensorList-获取传感器信息', `result: (type:${type})`);return result;
};// android.telephony.TelephonyManager类及方法
const TelephonyManager = Java.use('android.telephony.TelephonyManager');
TelephonyManager.getDeviceId.overload().implementation = function() {const result = this.getDeviceId();logAndSend('getDeviceId-获取设备IMEI', `result: ${result}`);return result;
};
TelephonyManager.getImei.overload().implementation = function() {const result = this.getImei();logAndSend('getImei-获取设备IMEI', `result: ${result}`);return result;
};TelephonyManager.getTelephonyProperty.overload('int', 'java.lang.String', 'java.lang.String').implementation = function(subId, propName, defaultValue) {const result = this.getTelephonyProperty(subId, propName, defaultValue);logAndSend('getTelephonyProperty-获取运营商信息', `result: ${result}`);return result;
};TelephonyManager.getSubscriberId.overload().implementation = function() {const result = this.getSubscriberId();logAndSend('getSubscriberId-获取国际移动用户识别码', `result: ${result}`);return result;
};TelephonyManager.getSimOperatorNumeric.overload().implementation = function() {const result = this.getSimOperatorNumeric();logAndSend('getSimOperatorNumeric-获取移动网络运营商(MNC)和移动网络所属国家或地区(MCC)', `result: ${result}`);return result;
};TelephonyManager.getSimCountryIso.overload().implementation = function() {const result = this.getSimCountryIso();logAndSend('getSimCountryIso-获取SIM卡所在国家的ISO', `result: ${result}`);return result;
};TelephonyManager.getSimSerialNumber.overload().implementation = function() {const result = this.getSimSerialNumber();logAndSend('getSimSerialNumber-获取SIM卡序列号/ICCID', `result: ${result}`);return result;
};TelephonyManager.getCellLocation.implementation = function() {const result = this.getCellLocation();logAndSend('getCellLocation-获取当前设备基站信息(基站ID、区域码、位置区域码)', `result: ${result}`);return result;
};TelephonyManager.getAllCellInfo.implementation = function() {const result = this.getAllCellInfo();logAndSend('getAllCellInfo-获取当前设备连接的所有基站信息', `result: ${result}`);return result;
};// android.os.SystemProperties类及方法
const SystemProperties = Java.use('android.os.SystemProperties');
SystemProperties.get.overload('java.lang.String').implementation = function(key) {const result = this.get(key);// ro.build.version.release:Android系统的版本号。 ro.product.model:设备型号。 ro.product.brand:设备品牌。 ro.build.version.sdk:Android SDK的版本号。 ro.build.version.security_patch:安全补丁程序级别。logAndSend('SystemProperties-获取手机系统属性', `key: ${key}, value: ${result}`);return result;
};// android.app.ActivityManager类及方法
const ActivityManager = Java.use('android.app.ActivityManager');
ActivityManager.getRunningAppProcesses.implementation = function() {const result = this.getRunningAppProcesses();const processList = [];for (let i = 0; i < result.size(); i++) {const processInfo = result.get(i);processList.push({processName: processInfo.processName,pid: processInfo.pid,uid: processInfo.uid});}logAndSend('getRunningAppProcesses-获取运行进程列表信息', JSON.stringify(processList));return result;
};// android.provider.Settings$Secure类及方法
const Secure = Java.use('android.provider.Settings$Secure');
const ANDROID_ID = 'android_id';
Secure.getString.overload('android.content.ContentResolver', 'java.lang.String').implementation = function(resolver, name) {
if (name === ANDROID_ID) {const result = this.getString(resolver, name);logAndSend('getString-获取Android ID', `result: ${result}`);return result;}return this.getString(resolver, name);
};
Secure.getStringForUser.implementation = function(cr, name, userHandle) {if (name === ANDROID_ID) {const result = this.getStringForUser(cr, name, userHandle);logAndSend('getStringForUser-获取Android ID', `result: ${result}`);return result;}return this.getStringForUser(cr, name, userHandle);
};// java.net.Inet4Address类及方法
const Inet4Address = Java.use('java.net.Inet4Address');
Inet4Address.getHostAddress.implementation = function() {const result = this.getHostAddress();logAndSend('getHostAddress-获取IPv4地址/IP地址', `result: ${result}`);return result;
};// android.content.ClipboardManager类及方法
const ClipboardManager = Java.use('android.content.ClipboardManager');
ClipboardManager.getPrimaryClip.overload().implementation = function() {const result = this.getPrimaryClip();logAndSend('getPrimaryClip-获取剪贴板内容', `result: ${result}`);return result;
};// android.net.wifi.WifiManager类及方法
const WifiManager = Java.use('android.net.wifi.WifiManager');
WifiManager.getWifiState.overload().implementation = function() {const result = this.getWifiState();logAndSend('getWifiState-获取WiFi开关状态', `result: ${result}`);return result;
};
WifiManager.getConnectionInfo.overload().implementation = function() {const result = this.getConnectionInfo();// SSID:当前连接的无线网络的名称(网络标识符)。BSSID:当前连接的无线网络的基本服务集标识符,即接入点的物理地址。MAC:设备的无线网络接口的物理地址。Supplicant state:无线网络连接的状态,此处为 "COMPLETED" 表示已成功连接。RSSI:接收信号强度指示(Received Signal Strength Indicator),表示当前连接的信号强度。Link speed:当前连接的无线网络的链接速度。Frequency:当前连接的无线网络的频率。Net ID:无线网络的网络ID。Metered hint:指示当前网络是否为按流量计费的网络。Score:当前网络的分数,用于选择最佳网络。logAndSend('getConnectionInfo-获取当前连接wifi信息(部分)', `result: ${result}`);return result;
};WifiManager.getScanResults.overload().implementation = function() {const result = this.getScanResults();logAndSend('getScanResults-获取附近wifi信息', `result: ${result}`);return result;
};

request.js文件 

这段代码是使用Frida框架在Android应用中进行动态分析的JavaScript脚本。它的主要目标是拦截并记录网络请求的URL。

以下是这段代码的主要功能:

1. 使用Frida的Java.use函数获取到java.net.SocketOutputStream类的引用。
2. 重写SocketOutputStream类的socketWrite0方法。这个方法在写入网络请求数据时被调用,因此可以通过拦截这个方法来获取网络请求数据。
3. 在重写的socketWrite0方法中,首先将传入的字节数组转换为字符串,然后从这个字符串中提取出请求的URL。最后,将这个URL打印出来,并通过Frida的send函数发送到Python端。
4. 提供了两个辅助函数:extractUrlFromRequest函数用于从HTTP请求字符串中提取出URL,byteArrayToString函数用于将字节数组转换为字符串。

这段代码需要在已经安装了Frida的环境中运行,并且目标应用程序的进程需要已经启动。它会在目标应用程序的进程空间内执行,拦截并记录网络请求的URL。这对于理解应用程序的网络行为,或者发现应用程序的潜在问题非常有帮助。

Java.perform(function () {var SocketOutputStream = Java.use('java.net.SocketOutputStream');SocketOutputStream.socketWrite0.overload('java.io.FileDescriptor', '[B', 'int', 'int').implementation = function (fd, buffer, offset, count) {var byteArray = Java.array('byte', buffer);var requestString = byteArrayToString(byteArray, offset, count);var url = extractUrlFromRequest(requestString);console.log('URL:', url);send(url);var result = this.socketWrite0(fd, buffer, offset, count);return result;};function extractUrlFromRequest(requestString) {var start = requestString.indexOf(' ') + 1;var end = requestString.indexOf(' ', start);var path = requestString.substring(start, end);var hostStart = requestString.indexOf('Host: ') + 6;var hostEnd = requestString.indexOf('\r\n', hostStart);var host = requestString.substring(hostStart, hostEnd);var protocol = 'http'; // 默认协议为http,如果使用https请修改为'https'var url = protocol + '://' + host + path;return url;}function byteArrayToString(byteArray, offset, count) {var result = '';for (var i = offset; i < offset + count; i++) {var byteValue = byteArray[i] & 0xff;result += String.fromCharCode(byteValue);}return result;}
});

unpinging.js文件(此文件是抓取HTPPS的请求ssl证书校验)该js也是通过python注入的。并手动开启代理进行抓取htpps的请求,也是绕开证书校验的方法之一

/*  Android ssl certificate pinning bypass script for various methodsby Maurizio SidduRun with:frida -U -f [APP_ID] -l frida_multiple_unpinning.js --no-pause
*/setTimeout(function() {Java.perform(function() {Java.use("android.util.Log").e("[hookenv]", '');Java.use("android.util.Log").e("[hookenv]", '======');Java.use("android.util.Log").e("[hookenv]", '[#] Android Bypass for various Certificate Pinning methods [#]');Java.use("android.util.Log").e("[hookenv]", '======');var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');var SSLContext = Java.use('javax.net.ssl.SSLContext');// TrustManager (Android < 7) //var TrustManager = Java.registerClass({// Implement a custom TrustManagername: 'dev.asd.test.TrustManager',implements: [X509TrustManager],methods: {checkClientTrusted: function(chain, authType) {},checkServerTrusted: function(chain, authType) {},getAcceptedIssuers: function() {return []; }}});// Prepare the TrustManager array to pass to SSLContext.init()var TrustManagers = [TrustManager.$new()];// Get a handle on the init() on the SSLContext classvar SSLContext_init = SSLContext.init.overload('[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom');try {// Override the init method, specifying the custom TrustManagerSSLContext_init.implementation = function(keyManager, trustManager, secureRandom) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing Trustmanager (Android < 7) pinner');SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] TrustManager (Android < 7) pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// OkHTTPv3 (quadruple bypass) ///try {// Bypass OkHTTPv3 {1}var okhttp3_Activity_1 = Java.use('okhttp3.CertificatePinner');    okhttp3_Activity_1.check.overload('java.lang.String', 'java.util.List').implementation = function(a, b) {                              Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing OkHTTPv3 {1}: ' + a);return;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] OkHTTPv3 {1} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}try {// Bypass OkHTTPv3 {2}// This method of CertificatePinner.check is deprecated but could be found in some old Android appsvar okhttp3_Activity_2 = Java.use('okhttp3.CertificatePinner');    okhttp3_Activity_2.check.overload('java.lang.String', 'java.security.cert.Certificate').implementation = function(a, b) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing OkHTTPv3 {2}: ' + a);return;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] OkHTTPv3 {2} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}try {// Bypass OkHTTPv3 {3}var okhttp3_Activity_3 = Java.use('okhttp3.CertificatePinner');    okhttp3_Activity_3.check.overload('java.lang.String', '[Ljava.security.cert.Certificate;').implementation = function(a, b) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing OkHTTPv3 {3}: ' + a);return;};} catch(err) {Java.use("android.util.Log").e("[hookenv]", '[-] OkHTTPv3 {3} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}try {// Bypass OkHTTPv3 {4}var okhttp3_Activity_4 = Java.use('okhttp3.CertificatePinner');    //okhttp3_Activity_4['check$okhttp'].implementation = function(a, b) {okhttp3_Activity_4.check$okhttp.overload('java.lang.String', 'kotlin.jvm.functions.Function0').implementation = function(a, b) {		Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing OkHTTPv3 {4}: ' + a);return;};} catch(err) {Java.use("android.util.Log").e("[hookenv]", '[-] OkHTTPv3 {4} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// Trustkit (triple bypass) ////try {// Bypass Trustkit {1}var trustkit_Activity_1 = Java.use('com.datatheorem.android.trustkit.pinning.OkHostnameVerifier');trustkit_Activity_1.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function(a, b) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing Trustkit {1}: ' + a);return true;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] Trustkit {1} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}try {// Bypass Trustkit {2}var trustkit_Activity_2 = Java.use('com.datatheorem.android.trustkit.pinning.OkHostnameVerifier');trustkit_Activity_2.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function(a, b) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing Trustkit {2}: ' + a);return true;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] Trustkit {2} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}try {// Bypass Trustkit {3}var trustkit_PinningTrustManager = Java.use('com.datatheorem.android.trustkit.pinning.PinningTrustManager');trustkit_PinningTrustManager.checkServerTrusted.overload('[Ljava.security.cert.X509Certificate;', 'java.lang.String').implementation = function(chain, authType) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing Trustkit {3}');//return;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] Trustkit {3} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// TrustManagerImpl (Android > 7) //try {// Bypass TrustManagerImpl (Android > 7) {1}var array_list = Java.use("java.util.ArrayList");var TrustManagerImpl_Activity_1 = Java.use('com.android.org.conscrypt.TrustManagerImpl');TrustManagerImpl_Activity_1.checkTrustedRecursive.implementation = function(certs, ocspData, tlsSctData, host, clientAuth, untrustedChain, trustAnchorChain, used) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing TrustManagerImpl (Android > 7) checkTrustedRecursive check: '+ host);return array_list.$new();};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] TrustManagerImpl (Android > 7) checkTrustedRecursive check not found');//Java.use("android.util.Log").e("[hookenv]", err);}  try {// Bypass TrustManagerImpl (Android > 7) {2} (probably no more necessary)var TrustManagerImpl_Activity_2 = Java.use('com.android.org.conscrypt.TrustManagerImpl');TrustManagerImpl_Activity_2.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing TrustManagerImpl (Android > 7) verifyChain check: ' + host);return untrustedChain;};   } catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] TrustManagerImpl (Android > 7) verifyChain check not found');//Java.use("android.util.Log").e("[hookenv]", err);}// Appcelerator Titanium PinningTrustManager /////try {var appcelerator_PinningTrustManager = Java.use('appcelerator.https.PinningTrustManager');appcelerator_PinningTrustManager.checkServerTrusted.implementation = function(chain, authType) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing Appcelerator PinningTrustManager');return;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] Appcelerator PinningTrustManager pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// Fabric PinningTrustManager //try {var fabric_PinningTrustManager = Java.use('io.fabric.sdk.android.services.network.PinningTrustManager');fabric_PinningTrustManager.checkServerTrusted.implementation = function(chain, authType) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing Fabric PinningTrustManager');return;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] Fabric PinningTrustManager pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// OpenSSLSocketImpl Conscrypt (double bypass) ///try {var OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl');OpenSSLSocketImpl.verifyCertificateChain.implementation = function(certRefs, JavaObject, authMethod) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing OpenSSLSocketImpl Conscrypt {1}');};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] OpenSSLSocketImpl Conscrypt {1} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);        }try {var OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl');OpenSSLSocketImpl.verifyCertificateChain.implementation = function(certChain, authMethod) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing OpenSSLSocketImpl Conscrypt {2}');};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] OpenSSLSocketImpl Conscrypt {2} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);        }// OpenSSLEngineSocketImpl Conscrypt /////try {var OpenSSLEngineSocketImpl_Activity = Java.use('com.android.org.conscrypt.OpenSSLEngineSocketImpl');OpenSSLEngineSocketImpl_Activity.verifyCertificateChain.overload('[Ljava.lang.Long;', 'java.lang.String').implementation = function(a, b) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing OpenSSLEngineSocketImpl Conscrypt: ' + b);};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] OpenSSLEngineSocketImpl Conscrypt pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// OpenSSLSocketImpl Apache Harmony ////try {var OpenSSLSocketImpl_Harmony = Java.use('org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl');OpenSSLSocketImpl_Harmony.verifyCertificateChain.implementation = function(asn1DerEncodedCertificateChain, authMethod) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing OpenSSLSocketImpl Apache Harmony');};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] OpenSSLSocketImpl Apache Harmony pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);      }// PhoneGap sslCertificateChecker //try {var phonegap_Activity = Java.use('nl.xservices.plugins.sslCertificateChecker');phonegap_Activity.execute.overload('java.lang.String', 'org.json.JSONArray', 'org.apache.cordova.CallbackContext').implementation = function(a, b, c) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing PhoneGap sslCertificateChecker: ' + a);return true;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] PhoneGap sslCertificateChecker pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// IBM MobileFirst pinTrustedCertificatePublicKey (double bypass) //try {// Bypass IBM MobileFirst {1}var WLClient_Activity_1 = Java.use('com.worklight.wlclient.api.WLClient');WLClient_Activity_1.getInstance().pinTrustedCertificatePublicKey.overload('java.lang.String').implementation = function(cert) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing IBM MobileFirst pinTrustedCertificatePublicKey {1}: ' + cert);return;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] IBM MobileFirst pinTrustedCertificatePublicKey {1} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}try {// Bypass IBM MobileFirst {2}var WLClient_Activity_2 = Java.use('com.worklight.wlclient.api.WLClient');WLClient_Activity_2.getInstance().pinTrustedCertificatePublicKey.overload('[Ljava.lang.String;').implementation = function(cert) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing IBM MobileFirst pinTrustedCertificatePublicKey {2}: ' + cert);return;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] IBM MobileFirst pinTrustedCertificatePublicKey {2} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// IBM WorkLight (ancestor of MobileFirst) HostNameVerifierWithCertificatePinning (quadruple bypass) /////try {// Bypass IBM WorkLight {1}var worklight_Activity_1 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');worklight_Activity_1.verify.overload('java.lang.String', 'javax.net.ssl.SSLSocket').implementation = function(a, b) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {1}: ' + a);                return;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] IBM WorkLight HostNameVerifierWithCertificatePinning {1} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}try {// Bypass IBM WorkLight {2}var worklight_Activity_2 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');worklight_Activity_2.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function(a, b) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {2}: ' + a);return;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] IBM WorkLight HostNameVerifierWithCertificatePinning {2} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}try {// Bypass IBM WorkLight {3}var worklight_Activity_3 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');worklight_Activity_3.verify.overload('java.lang.String', '[Ljava.lang.String;', '[Ljava.lang.String;').implementation = function(a, b) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {3}: ' + a);return;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] IBM WorkLight HostNameVerifierWithCertificatePinning {3} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}try {// Bypass IBM WorkLight {4}var worklight_Activity_4 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');worklight_Activity_4.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function(a, b) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {4}: ' + a);return true;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] IBM WorkLight HostNameVerifierWithCertificatePinning {4} pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// Conscrypt CertPinManager ////try {var conscrypt_CertPinManager_Activity = Java.use('com.android.org.conscrypt.CertPinManager');conscrypt_CertPinManager_Activity.checkChainPinning.overload('java.lang.String', 'java.util.List').implementation = function(a, b) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing Conscrypt CertPinManager: ' + a);//return;return true;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] Conscrypt CertPinManager pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// Conscrypt CertPinManager (Legacy) /////try {var legacy_conscrypt_CertPinManager_Activity = Java.use('com.android.org.conscrypt.CertPinManager');legacy_conscrypt_CertPinManager_Activity.isChainValid.overload('java.lang.String', 'java.util.List').implementation = function(a, b) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing Conscrypt CertPinManager (Legacy): ' + a);return true;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] Conscrypt CertPinManager (Legacy) pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// CWAC-Netsecurity (unofficial back-port pinner for Android<4.2) CertPinManager /////try {var cwac_CertPinManager_Activity = Java.use('com.commonsware.cwac.netsecurity.conscrypt.CertPinManager');cwac_CertPinManager_Activity.isChainValid.overload('java.lang.String', 'java.util.List').implementation = function(a, b) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing CWAC-Netsecurity CertPinManager: ' + a);return true;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] CWAC-Netsecurity CertPinManager pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// Worklight Androidgap WLCertificatePinningPlugin ///try {var androidgap_WLCertificatePinningPlugin_Activity = Java.use('com.worklight.androidgap.plugin.WLCertificatePinningPlugin');androidgap_WLCertificatePinningPlugin_Activity.execute.overload('java.lang.String', 'org.json.JSONArray', 'org.apache.cordova.CallbackContext').implementation = function(a, b, c) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing Worklight Androidgap WLCertificatePinningPlugin: ' + a);return true;};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] Worklight Androidgap WLCertificatePinningPlugin pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// Netty FingerprintTrustManagerFactory ////try {var netty_FingerprintTrustManagerFactory = Java.use('io.netty.handler.ssl.util.FingerprintTrustManagerFactory');//NOTE: sometimes this below implementation could be useful //var netty_FingerprintTrustManagerFactory = Java.use('org.jboss.netty.handler.ssl.util.FingerprintTrustManagerFactory');netty_FingerprintTrustManagerFactory.checkTrusted.implementation = function(type, chain) {Java.use("android.util.Log").e("[hookenv]", '[+] Bypassing Netty FingerprintTrustManagerFactory');};} catch (err) {Java.use("android.util.Log").e("[hookenv]", '[-] Netty FingerprintTrustManagerFactory pinner not found');//Java.use("android.util.Log").e("[hookenv]", err);}// Squareup CertificatePinner [OkHTTPstack.getClassName() === "javax.net.ssl.SSLPeerUnverifiedException");// Retrieve the method raising the SSLPeerUnverifiedExceptionvar callingFunctionStack = stackTrace[exceptionStackIndex + 1];var className = callingFunctionStack.getClassName();var methodName = callingFunctionStack.getMethodName();var callingClass = Java.use(className);var callingMethod = callingClass[methodName];Java.use("android.util.Log").e("[hookenv]", '\x1b[36m[!] Attempting to bypass uncommon SSL Pinning method on: '+className+'.'+methodName+'\x1b[0m');					// Skip it when already patched by Fridaif (callingMethod.implementation) {return; }// Trying to patch the uncommon SSL Pinning method via implementationvar returnTypeName = callingMethod.returnType.type;callingMethod.implementation = function() {rudimentaryFix(returnTypeName);};} catch (e) {// Dynamic patching via implementation does not works, then trying via function overloading//Java.use("android.util.Log").e("[hookenv]", '[!] The uncommon SSL Pinning method has more than one overload); if (String(e).includes(".overload")) {var splittedList = String(e).split(".overload");for (let i=2; i


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部