Feuille Frida Cheat
Aperçu général
Frida est une boîte à outils d'instrumentation dynamique pour les développeurs, les moteurs inversés et les chercheurs en sécurité. Il vous permet d'injecter JavaScript ou votre propre bibliothèque dans des applications natives sous Windows, macOS, GNU/Linux, iOS, Android et QNX. Frida fournit des capacités puissantes pour la manipulation d'exécution, le crochet API et l'analyse dynamique des applications.
C'est pas vrai. Attention: N'utilisez Frida que sur les applications que vous possédez ou avez la permission explicite de tester. Une utilisation non autorisée peut violer les conditions de service ou les lois locales.
Installation
Installation du paquet Python
# Install Frida via pip (recommended)
pip install frida-tools
# Install specific version
pip install frida-tools==12.11.18
# Upgrade to latest version
pip install --upgrade frida-tools
Installation spécifique à la plateforme
Linux
# Ubuntu/Debian
sudo apt update
sudo apt install python3-pip
pip3 install frida-tools
# Arch Linux
sudo pacman -S python-pip
pip install frida-tools
# CentOS/RHEL
sudo yum install python3-pip
pip3 install frida-tools
```_
#### MACOS
```bash
# Using Homebrew
brew install python3
pip3 install frida-tools
# Using MacPorts
sudo port install python39 +universal
pip3 install frida-tools
```_
#### Fenêtres
```bash
# Using Python installer
python -m pip install frida-tools
# Using Chocolatey
choco install python3
pip install frida-tools
Configuration du périphérique mobile
Android
# Download Frida server for Android
wget https://github.com/frida/frida/releases/download/16.0.8/frida-server-16.0.8-android-arm64.xz
unxz frida-server-16.0.8-android-arm64.xz
# Push to device and set permissions
adb push frida-server-16.0.8-android-arm64 /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server
# Run Frida server on device
adb shell su -c "/data/local/tmp/frida-server &"
iOS
# Install via Cydia (jailbroken devices)
# Add Frida repository: https://build.frida.re
# Or install via SSH
ssh root@<device-ip>
apt update
apt install re.frida.server
Utilisation de base
Découverte des processus
# List running processes
frida-ps
# List processes on USB device
frida-ps -U
# List processes on remote device
frida-ps -H <host>:<port>
# List applications (Android/iOS)
frida-ps -Uai
# List installed applications
frida-ps -Ua
Crochet de base
# Attach to running process by name
frida -n "target_app" -l script.js
# Attach to process by PID
frida -p 1234 -l script.js
# Spawn and attach to application
frida -f com.example.app -l script.js --no-pause
# Interactive REPL mode
frida -n "target_app"
Exécution du script
# Execute JavaScript file
frida -n "target_app" -l hook_script.js
# Execute inline JavaScript
frida -n "target_app" -e "console.log('Hello from Frida');"
# Execute with USB device
frida -U -f com.example.app -l script.js
# Execute with remote device
frida -H 192.168.1.100:27042 -f com.example.app -l script.js
Référence de commande
Command | Description |
---|---|
frida-ps |
List running processes |
frida-ps -U |
List processes on USB device |
frida-ps -Uai |
List applications on USB device |
frida -n <name> |
Attach to process by name |
frida -p <pid> |
Attach to process by PID |
frida -f <app> |
Spawn and attach to application |
frida -l <script> |
Load JavaScript file |
frida -e <code> |
Execute inline JavaScript |
frida-trace |
Trace function calls |
frida-discover |
Discover internal functions |
frida-kill |
Kill Frida scripts |
Bases de l'API JavaScript
Opérations de mémoire
// Read memory
var addr = ptr("0x12345678");
var value = Memory.readU32(addr);
console.log("Value:", value);
// Write memory
Memory.writeU32(addr, 0xdeadbeef);
// Allocate memory
var buffer = Memory.alloc(1024);
Memory.writeUtf8String(buffer, "Hello World");
// Search memory
var pattern = "48 8b 05 ?? ?? ?? ??";
var matches = Memory.scanSync(ptr("0x400000"), 0x1000, pattern);
Crochet de fonction
// Hook function by address
Interceptor.attach(ptr("0x12345678"), \\\\{
onEnter: function(args) \\\\{
console.log("Function called with args:", args[0], args[1]);
this.arg0 = args[0];
\\\\},
onLeave: function(retval) \\\\{
console.log("Function returned:", retval);
retval.replace(ptr("0x1"));
\\\\}
\\\\});
// Hook function by name (with Module)
var targetModule = Process.getModuleByName("libc.so");
var mallocAddr = targetModule.getExportByName("malloc");
Interceptor.attach(mallocAddr, \\\\{
onEnter: function(args) \\\\{
console.log("malloc called with size:", args[0].toInt32());
\\\\}
\\\\});
Module et résolution des symboles
// List loaded modules
Process.enumerateModules().forEach(function(module) \\\\{
console.log(module.name, module.base, module.size);
\\\\});
// Get module by name
var module = Process.getModuleByName("libssl.so");
console.log("Base address:", module.base);
// Enumerate exports
module.enumerateExports().forEach(function(exp) \\\\{
console.log(exp.name, exp.address);
\\\\});
// Find symbol
var symbol = Module.findExportByName("libc.so", "strcmp");
console.log("strcmp address:", symbol);
Utilisation avancée
Crochet d'application Android
// Hook Android Java methods
Java.perform(function() \\\\{
var MainActivity = Java.use("com.example.MainActivity");
MainActivity.checkLicense.implementation = function() \\\\{
console.log("License check bypassed");
return true;
\\\\};
// Hook constructor
MainActivity.$init.implementation = function() \\\\{
console.log("MainActivity constructor called");
return this.$init();
\\\\};
// Hook with multiple overloads
var String = Java.use("java.lang.String");
String.equals.overload("java.lang.Object").implementation = function(obj) \\\\{
var result = this.equals(obj);
console.log("String.equals called:", this.toString(), "==", obj.toString(), "->", result);
return result;
\\\\};
\\\\});
Crochet d'application iOS
// Hook Objective-C methods
if (ObjC.available) \\\\{
var NSString = ObjC.classes.NSString;
var method = NSString["- isEqualToString:"];
Interceptor.attach(method.implementation, \\\\{
onEnter: function(args) \\\\{
var self = ObjC.Object(args[0]);
var other = ObjC.Object(args[2]);
console.log("NSString isEqualToString:", self.toString(), "==", other.toString());
\\\\}
\\\\});
// Hook class methods
var UIApplication = ObjC.classes.UIApplication;
var sharedApplication = UIApplication["+ sharedApplication"];
Interceptor.attach(sharedApplication.implementation, \\\\{
onLeave: function(retval) \\\\{
console.log("UIApplication sharedApplication called");
\\\\}
\\\\});
\\\\}
SSL Détournement d'épingle
// Android SSL pinning bypass
Java.perform(function() \\\\{
// Hook TrustManagerImpl
var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
TrustManagerImpl.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) \\\\{
console.log("SSL verification bypassed for: " + host);
return untrustedChain;
\\\\};
// Hook HttpsURLConnection
var HttpsURLConnection = Java.use("javax.net.ssl.HttpsURLConnection");
HttpsURLConnection.setDefaultHostnameVerifier.implementation = function(hostnameVerifier) \\\\{
console.log("Default hostname verifier bypassed");
\\\\};
\\\\});
Détection des racines
// Android root detection bypass
Java.perform(function() \\\\{
// Hook common root detection methods
var RootBeer = Java.use("com.scottyab.rootbeer.RootBeer");
RootBeer.isRooted.implementation = function() \\\\{
console.log("Root detection bypassed");
return false;
\\\\};
// Hook file existence checks
var File = Java.use("java.io.File");
File.exists.implementation = function() \\\\{
var path = this.getAbsolutePath();
if (path.indexOf("su") !== -1||path.indexOf("busybox") !== -1) \\\\{
console.log("Blocked file check for:", path);
return false;
\\\\}
return this.exists();
\\\\};
\\\\});
Analyse du protocole personnalisé
// Hook network functions
var send = Module.findExportByName("libc.so", "send");
var recv = Module.findExportByName("libc.so", "recv");
Interceptor.attach(send, \\\\{
onEnter: function(args) \\\\{
var sockfd = args[0].toInt32();
var buf = args[1];
var len = args[2].toInt32();
console.log("Send on socket", sockfd, "length", len);
console.log(hexdump(buf, \\\\{ length: len, ansi: true \\\\}));
\\\\}
\\\\});
Interceptor.attach(recv, \\\\{
onLeave: function(retval) \\\\{
if (retval.toInt32() > 0) \\\\{
console.log("Received", retval.toInt32(), "bytes");
console.log(hexdump(this.context.r1, \\\\{ length: retval.toInt32(), ansi: true \\\\}));
\\\\}
\\\\}
\\\\});
Outils Frida
frida-trace
# Trace all functions in a module
frida-trace -n "target_app" -i "libssl.so!*"
# Trace specific functions
frida-trace -n "target_app" -i "malloc" -i "free"
# Trace with custom handler
frida-trace -n "target_app" -i "strcmp" --runtime=v8
# Trace Java methods (Android)
frida-trace -U -f com.example.app -j '*!*encrypt*'
# Trace Objective-C methods (iOS)
frida-trace -U -f com.example.app -m '*[* *encrypt*]'
frida-découverte
# Discover internal functions
frida-discover -n "target_app" -a libssl.so
# Discover with specific patterns
frida-discover -n "target_app" -a libssl.so -s "SSL_*"
# Output to file
frida-discover -n "target_app" -a libssl.so -o discovered_functions.txt
Dispositifs
# List available devices
frida-ls-devices
# List with details
frida-ls-devices -l
Scripts d'automatisation
Analyse du processus par lots
#!/usr/bin/env python3
import frida
import sys
def on_message(message, data):
if message['type'] == 'send':
print(f"[*] \\\\{message['payload']\\\\}")
else:
print(message)
# Connect to device
device = frida.get_usb_device()
# List and analyze multiple apps
apps = ['com.example.app1', 'com.example.app2', 'com.example.app3']
for app_id in apps:
try:
print(f"[+] Analyzing \\\\{app_id\\\\}")
session = device.attach(app_id)
script_code = """
Java.perform(function() \\\\{
console.log("Analyzing: " + Java.use("android.app.Application").currentApplication().getPackageName());
\\\\});
"""
script = session.create_script(script_code)
script.on('message', on_message)
script.load()
input("Press Enter to continue to next app...")
session.detach()
except Exception as e:
print(f"[-] Error with \\\\{app_id\\\\}: \\\\{e\\\\}")
Test d'épinglement SSL automatisé
#!/usr/bin/env python3
import frida
import time
ssl_bypass_script = """
Java.perform(function() \\\\{
console.log("[+] Starting SSL bypass");
// Multiple SSL bypass techniques
var techniques = [
function() \\\\{
var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
TrustManagerImpl.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) \\\\{
console.log("[+] SSL verification bypassed for: " + host);
return untrustedChain;
\\\\};
\\\\},
function() \\\\{
var X509TrustManager = Java.use("javax.net.ssl.X509TrustManager");
var TrustManager = Java.registerClass(\\\\{
name: "com.frida.TrustManager",
implements: [X509TrustManager],
methods: \\\\{
checkClientTrusted: function(chain, authType) \\\\{\\\\},
checkServerTrusted: function(chain, authType) \\\\{\\\\},
getAcceptedIssuers: function() \\\\{ return []; \\\\}
\\\\}
\\\\});
\\\\}
];
techniques.forEach(function(technique, index) \\\\{
try \\\\{
technique();
console.log("[+] SSL bypass technique " + (index + 1) + " applied");
\\\\} catch (e) \\\\{
console.log("[-] SSL bypass technique " + (index + 1) + " failed: " + e);
\\\\}
\\\\});
\\\\});
"""
def test_ssl_bypass(package_name):
try:
device = frida.get_usb_device()
session = device.attach(package_name)
script = session.create_script(ssl_bypass_script)
script.load()
print(f"[+] SSL bypass applied to \\\\{package_name\\\\}")
time.sleep(5)
session.detach()
return True
except Exception as e:
print(f"[-] Failed to apply SSL bypass to \\\\{package_name\\\\}: \\\\{e\\\\}")
return False
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python3 ssl_bypass.py <package_name>")
sys.exit(1)
test_ssl_bypass(sys.argv[1])
Exemples d'intégration
Intégration de Burp Suite
#!/usr/bin/env python3
import frida
import requests
import json
# Frida script to extract API endpoints
api_extraction_script = """
Java.perform(function() \\\\{
var URL = Java.use("java.net.URL");
URL.$init.overload("java.lang.String").implementation = function(url) \\\\{
console.log("[API] URL accessed: " + url);
send(\\\\{"type": "url", "data": url\\\\});
return this.$init(url);
\\\\};
var HttpURLConnection = Java.use("java.net.HttpURLConnection");
HttpURLConnection.setRequestMethod.implementation = function(method) \\\\{
console.log("[API] HTTP Method: " + method);
send(\\\\{"type": "method", "data": method\\\\});
return this.setRequestMethod(method);
\\\\};
\\\\});
"""
def on_message(message, data):
if message['type'] == 'send':
payload = message['payload']
if payload['type'] == 'url':
# Send to Burp Suite for further analysis
burp_data = \\\\{
'url': payload['data'],
'timestamp': time.time()
\\\\}
# Add to Burp Suite scope or send to Collaborator
print(f"[+] New API endpoint discovered: \\\\{payload['data']\\\\}")
# Setup Frida session
device = frida.get_usb_device()
session = device.attach("com.example.app")
script = session.create_script(api_extraction_script)
script.on('message', on_message)
script.load()
input("Press Enter to stop...")
OWASP ZAP Intégration
#!/usr/bin/env python3
import frida
from zapv2 import ZAPv2
# Initialize ZAP
zap = ZAPv2(proxies=\\\\{'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'\\\\})
# Frida script to route traffic through ZAP
proxy_script = """
Java.perform(function() \\\\{
var System = Java.use("java.lang.System");
System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "8080");
System.setProperty("https.proxyHost", "127.0.0.1");
System.setProperty("https.proxyPort", "8080");
console.log("[+] Proxy settings configured for ZAP");
\\\\});
"""
def setup_zap_integration(package_name):
device = frida.get_usb_device()
session = device.attach(package_name)
script = session.create_script(proxy_script)
script.load()
print(f"[+] ZAP integration setup for \\\\{package_name\\\\}")
print(f"[+] ZAP Spider: \\\\{zap.spider.scan('http://target-api.com')\\\\}")
return session
# Usage
session = setup_zap_integration("com.example.app")
input("Press Enter to stop...")
session.detach()
Dépannage
Problèmes communs de connexion
# Check if Frida server is running on device
adb shell ps|grep frida
# Restart Frida server
adb shell su -c "pkill frida-server"
adb shell su -c "/data/local/tmp/frida-server &"
# Check port forwarding
adb forward --list
adb forward tcp:27042 tcp:27042
# Test connection
frida-ps -U
Questions relatives à la permission
# Android: Ensure proper permissions
adb shell su -c "chmod 755 /data/local/tmp/frida-server"
adb shell su -c "chown root:root /data/local/tmp/frida-server"
# iOS: Check Frida installation
ssh root@<device-ip> "dpkg -l|grep frida"
# Reinstall if necessary
ssh root@<device-ip> "apt remove re.frida.server && apt install re.frida.server"
Déboguement des scripts
// Add comprehensive error handling
try \\\\{
Java.perform(function() \\\\{
// Your code here
\\\\});
\\\\} catch (e) \\\\{
console.log("Error in Java.perform:", e);
console.log("Stack trace:", e.stack);
\\\\}
// Use console.log for debugging
console.log("Debug: Variable value is", someVariable);
// Check if classes exist before using
if (Java.available) \\\\{
try \\\\{
var MyClass = Java.use("com.example.MyClass");
console.log("MyClass found");
\\\\} catch (e) \\\\{
console.log("MyClass not found:", e);
\\\\}
\\\\}
Optimisation des performances
// Cache frequently used classes
var cachedClasses = \\\\{\\\\};
function getClass(className) \\\\{
if (!cachedClasses[className]) \\\\{
cachedClasses[className] = Java.use(className);
\\\\}
return cachedClasses[className];
\\\\}
// Use efficient memory operations
var buffer = Memory.alloc(1024); // Allocate once
// Reuse buffer instead of allocating repeatedly
// Minimize console output in production
var DEBUG = false;
function debugLog(message) \\\\{
if (DEBUG) \\\\{
console.log(message);
\\\\}
\\\\}
Ressources
- [Documentation officielle de Frida] (LINK_7)
- [Résistoire de Frida GitHub] (LINK_7)
- Référence de l'API JavaScript de Frida
- [Frida CodeShare] (LINK_7)
- [Manuel de Frida] (LINK_7)
- [Hooking Android avec Frida] (LINK_7)
- [Hooking iOS avec Frida] (LINK_7)
*Cette feuille de triche fournit une référence complète pour l'utilisation de Frida pour l'instrumentation dynamique et les tests de sécurité. Assurez-vous toujours d'avoir une autorisation appropriée avant d'utiliser cet outil dans n'importe quel environnement. *