Initial commit - 611 cybersecurity skills across all subdomains

This commit is contained in:
mukul975
2026-02-25 10:47:44 +01:00
commit 22a7ab1462
1765 changed files with 280648 additions and 0 deletions
@@ -0,0 +1,186 @@
---
name: analyzing-ios-app-security-with-objection
description: >
Performs runtime mobile security exploration of iOS applications using Objection, a Frida-powered
toolkit that enables security testers to interact with app internals without jailbreaking. Use when
assessing iOS app security posture, bypassing client-side protections, dumping keychain items,
inspecting filesystem storage, and evaluating runtime behavior. Activates for requests involving
iOS security testing, Objection runtime analysis, Frida-based iOS assessment, or mobile runtime
exploration.
domain: cybersecurity
subdomain: mobile-security
author: mahipal
tags: [mobile-security, ios, objection, frida, owasp-mobile, penetration-testing]
version: 1.0.0
license: MIT
---
# Analyzing iOS App Security with Objection
## When to Use
Use this skill when:
- Performing runtime security assessment of iOS applications during authorized penetration tests
- Inspecting iOS keychain, filesystem, and memory for sensitive data exposure
- Bypassing client-side security controls (SSL pinning, jailbreak detection) during security testing
- Evaluating iOS app behavior at runtime without access to source code
**Do not use** this skill on production devices without explicit authorization -- Objection modifies app runtime behavior and may trigger security monitoring.
## Prerequisites
- Python 3.10+ with pip
- Objection installed: `pip install objection`
- Frida installed: `pip install frida-tools`
- Target iOS device (jailbroken with Frida server, or non-jailbroken with repackaged IPA)
- For non-jailbroken: `objection patchipa` to inject Frida gadget into IPA
- macOS recommended for iOS testing (Xcode, ideviceinstaller)
- USB connection to target device or network Frida server
## Workflow
### Step 1: Prepare the Testing Environment
**For jailbroken devices:**
```bash
# Install Frida server on device via Cydia/Sileo
# SSH to device and start Frida server
ssh root@<device_ip> "/usr/sbin/frida-server -D"
# Verify Frida connectivity
frida-ps -U # List processes on USB-connected device
```
**For non-jailbroken devices (authorized testing):**
```bash
# Patch IPA with Frida gadget
objection patchipa --source target.ipa --codesign-signature "Apple Development: test@example.com"
# Install patched IPA
ideviceinstaller -i target-patched.ipa
```
### Step 2: Attach Objection to Target App
```bash
# Attach to running app by bundle ID
objection --gadget "com.target.app" explore
# Or spawn the app fresh
objection --gadget "com.target.app" explore --startup-command "ios hooking list classes"
```
Once attached, Objection provides an interactive REPL for runtime exploration.
### Step 3: Assess Data Storage Security (MASVS-STORAGE)
```bash
# Dump iOS Keychain items accessible to the app
ios keychain dump
# List files in app sandbox
ios plist cat Info.plist
env # Show app environment paths
# Inspect NSUserDefaults for sensitive data
ios nsuserdefaults get
# List SQLite databases
sqlite connect app_data.db
sqlite execute query "SELECT * FROM credentials"
# Check for sensitive data in pasteboard
ios pasteboard monitor
```
### Step 4: Evaluate Network Security (MASVS-NETWORK)
```bash
# Disable SSL/TLS certificate pinning
ios sslpinning disable
# Verify pinning is bypassed by observing traffic in Burp Suite proxy
# Monitor network-related class method calls
ios hooking watch class NSURLSession
ios hooking watch class NSURLConnection
```
### Step 5: Inspect Authentication and Authorization (MASVS-AUTH)
```bash
# List all Objective-C classes
ios hooking list classes
# Search for authentication-related classes
ios hooking search classes Auth
ios hooking search classes Login
ios hooking search classes Token
# Hook authentication methods to observe parameters
ios hooking watch method "+[AuthManager validateToken:]" --dump-args --dump-return
# Monitor biometric authentication calls
ios hooking watch class LAContext
```
### Step 6: Assess Binary Protections (MASVS-RESILIENCE)
```bash
# Check jailbreak detection implementation
ios jailbreak disable
# Simulate jailbreak detection bypass
ios jailbreak simulate
# List loaded frameworks and libraries
memory list modules
# Search memory for sensitive strings
memory search "password" --string
memory search "api_key" --string
memory search "Bearer" --string
# Dump specific memory regions
memory dump all dump_output/
```
### Step 7: Review Platform Interaction (MASVS-PLATFORM)
```bash
# List URL schemes registered by the app
ios info binary
ios bundles list_frameworks
# Hook URL scheme handlers
ios hooking watch method "-[AppDelegate application:openURL:options:]" --dump-args
# Monitor clipboard access
ios pasteboard monitor
# Check for custom keyboard restrictions
ios hooking search classes UITextField
```
## Key Concepts
| Term | Definition |
|------|-----------|
| **Objection** | Runtime mobile exploration toolkit built on Frida that provides pre-built scripts for common security testing tasks |
| **Frida Gadget** | Shared library injected into app process to enable Frida instrumentation without jailbreak |
| **Keychain** | iOS secure credential storage system; Objection can dump items accessible to the target app's keychain access group |
| **SSL Pinning Bypass** | Runtime modification of certificate validation logic to allow proxy interception of HTTPS traffic |
| **Method Hooking** | Intercepting Objective-C/Swift method calls at runtime to observe arguments, return values, and modify behavior |
## Tools & Systems
- **Objection**: High-level Frida-powered mobile security exploration toolkit with pre-built commands
- **Frida**: Dynamic instrumentation framework providing JavaScript injection into native app processes
- **Frida-tools**: CLI utilities for Frida including frida-ps, frida-trace, and frida-discover
- **ideviceinstaller**: Cross-platform tool for installing/managing iOS apps via USB
- **Burp Suite**: HTTP proxy for intercepting traffic after SSL pinning bypass
## Common Pitfalls
- **App crashes on attach**: Some apps implement Frida detection. Use `--startup-command` to hook anti-Frida checks early in the app lifecycle.
- **Keychain access scope**: Objection can only dump keychain items within the app's access group. System keychain items require separate jailbreak-level tools.
- **Swift name mangling**: Swift method names are mangled in the runtime. Use `ios hooking list classes` with grep to find demangled names.
- **Non-persistent changes**: All Objection modifications are runtime-only and reset on app restart. Document findings immediately.
@@ -0,0 +1,80 @@
# iOS Objection Security Assessment Report
## Engagement Information
| Field | Value |
|-------|-------|
| Application | [APP_NAME] |
| Bundle ID | [BUNDLE_ID] |
| iOS Version | [IOS_VERSION] |
| Device | [DEVICE_MODEL] |
| Device State | [Jailbroken/Non-Jailbroken] |
| Assessment Date | [DATE] |
| Analyst | [ANALYST] |
| Objection Version | [VERSION] |
## Executive Summary
[Brief narrative of findings from Objection runtime analysis]
## Keychain Analysis
| Service | Account | Data Type | Protection Class | Risk |
|---------|---------|-----------|-----------------|------|
| [SERVICE] | [ACCOUNT] | [TYPE] | [CLASS] | [RISK] |
**Findings**: [Description of sensitive data found in keychain]
## Data Storage Assessment
### NSUserDefaults
| Key | Contains Sensitive Data | Risk |
|-----|----------------------|------|
| [KEY] | [YES/NO] | [RISK] |
### SQLite Databases
| Database | Encrypted | Sensitive Tables | Risk |
|----------|-----------|-----------------|------|
| [DB_NAME] | [YES/NO] | [TABLES] | [RISK] |
### Filesystem
| Path | Contents | Protection | Risk |
|------|----------|-----------|------|
| [PATH] | [DESCRIPTION] | [ATTRIBUTE] | [RISK] |
## Network Security
| Check | Result | Details |
|-------|--------|---------|
| SSL Pinning Present | [YES/NO] | [IMPLEMENTATION_DETAILS] |
| SSL Pinning Bypass | [SUCCESS/FAIL] | [METHOD_USED] |
| ATS Configuration | [STRICT/RELAXED] | [EXCEPTIONS] |
## Binary Protection Assessment
| Protection | Status | Details |
|-----------|--------|---------|
| Jailbreak Detection | [Present/Absent] | [BYPASS_DIFFICULTY] |
| Frida Detection | [Present/Absent] | [DETAILS] |
| Debug Detection | [Present/Absent] | [DETAILS] |
| Code Obfuscation | [Yes/No] | [DETAILS] |
## Memory Analysis
| Search Pattern | Found | Risk | Details |
|---------------|-------|------|---------|
| Passwords | [YES/NO] | [RISK] | [DETAILS] |
| Auth Tokens | [YES/NO] | [RISK] | [DETAILS] |
| API Keys | [YES/NO] | [RISK] | [DETAILS] |
| JWTs | [YES/NO] | [RISK] | [DETAILS] |
## Recommendations
### Critical
1. [RECOMMENDATION]
### High
1. [RECOMMENDATION]
### Medium
1. [RECOMMENDATION]
@@ -0,0 +1,43 @@
# Standards Reference: iOS App Security with Objection
## OWASP Mobile Top 10 2024 Mapping
| OWASP ID | Risk | Objection Testing Coverage |
|----------|------|---------------------------|
| M1 | Improper Credential Usage | Keychain dumping, memory string search for hardcoded credentials |
| M3 | Insecure Authentication/Authorization | Hook authentication methods, bypass biometric checks |
| M5 | Insecure Communication | SSL pinning bypass, network class hooking |
| M7 | Insufficient Binary Protections | Jailbreak detection bypass, Frida detection assessment |
| M8 | Security Misconfiguration | Info.plist review, URL scheme analysis, ATS configuration |
| M9 | Insecure Data Storage | NSUserDefaults inspection, SQLite database access, file system review |
## OWASP MASVS v2.0 Control Mapping
| MASVS Category | Objection Commands | Assessment Area |
|----------------|-------------------|-----------------|
| MASVS-STORAGE | `ios keychain dump`, `ios nsuserdefaults get`, `sqlite connect` | Sensitive data in keychain, NSUserDefaults, databases |
| MASVS-CRYPTO | `memory search`, hook crypto framework calls | Key storage, algorithm selection |
| MASVS-AUTH | Hook LAContext, authentication classes | Biometric bypass, session management |
| MASVS-NETWORK | `ios sslpinning disable`, hook NSURLSession | Certificate pinning, cleartext traffic |
| MASVS-PLATFORM | Hook URL scheme handlers, pasteboard monitor | Deep link security, clipboard exposure |
| MASVS-CODE | `memory list modules`, binary inspection | Debugging symbols, framework analysis |
| MASVS-RESILIENCE | `ios jailbreak disable`, Frida detection hooks | Anti-tampering, anti-debugging |
## OWASP MASTG Test Cases
| Test ID | Description | Objection Approach |
|---------|-------------|-------------------|
| MASTG-TEST-0053 | Testing Local Storage for Sensitive Data | `ios keychain dump`, filesystem inspection |
| MASTG-TEST-0057 | Testing Backups for Sensitive Data | Check backup exclusion attributes |
| MASTG-TEST-0060 | Testing Custom URL Schemes | Hook `application:openURL:options:` |
| MASTG-TEST-0063 | Testing for Sensitive Data in Logs | Monitor NSLog calls via hooking |
| MASTG-TEST-0066 | Testing Enforced App Transport Security | Inspect Info.plist ATS configuration |
## Apple Platform Security Requirements
| Requirement | Assessment Method |
|-------------|-------------------|
| Keychain Access Control | Verify kSecAttrAccessible values via keychain dump |
| App Transport Security | Check Info.plist for NSAllowsArbitraryLoads exceptions |
| Data Protection API | Verify file protection attributes on sensitive files |
| Secure Enclave Usage | Hook SecKey operations for biometric-protected keys |
@@ -0,0 +1,83 @@
# Workflows: iOS App Security with Objection
## Workflow 1: iOS Runtime Security Assessment
```
[Setup Environment] --> [Prepare Device] --> [Attach Objection] --> [Runtime Analysis]
| | | |
v v v v
[Install Frida] [Jailbroken: Start [Connect via USB] [Data Storage Check]
[Install Objection] frida-server] [Spawn target app] [Network Security]
[Non-JB: Patch IPA] [Auth Mechanism Review]
[Binary Protection Test]
|
v
[Document Findings]
[Generate Report]
```
## Workflow 2: SSL Pinning Bypass for Traffic Interception
```
[Configure Burp Proxy] --> [Set device proxy] --> [Attach Objection]
|
v
[ios sslpinning disable]
|
v
[Navigate app in browser/UI]
|
v
[Capture HTTPS traffic in Burp]
[Analyze API endpoints]
[Test authentication flows]
[Check for sensitive data in transit]
```
## Workflow 3: Keychain and Data Storage Assessment
```
[Attach Objection] --> [ios keychain dump] --> [Analyze keychain items]
| |
v v
[ios nsuserdefaults get] [Check protection classes]
| [Identify sensitive tokens]
v [Verify encryption at rest]
[List app sandbox files]
|
v
[sqlite connect *.db]
[Query sensitive tables]
|
v
[memory search "password"]
[memory search "token"]
[memory search "secret"]
```
## Workflow 4: Jailbreak Detection Assessment
```
[Attach Objection] --> [ios jailbreak disable] --> [Navigate app]
| |
v [App functions normally?]
[Hook detection methods] / \
[Monitor file checks] [Yes] [No]
[Monitor Cydia URL scheme] | |
| [Detection [Additional detection
v bypassed] methods exist]
[Document detection |
methods found] [Hook deeper: search
[Assess bypass for custom checks]
difficulty] [Frida script for
targeted bypass]
```
## Decision Matrix: Testing Approach
| Device State | IPA Access | Approach |
|-------------|-----------|----------|
| Jailbroken | Not needed | Direct Frida server + Objection attach |
| Non-jailbroken | Available | Patch IPA with `objection patchipa` |
| Non-jailbroken | Not available | Request IPA from client or use device management |
| Emulator | N/A | Limited: Frida on Corellium or similar platform |
@@ -0,0 +1,294 @@
#!/usr/bin/env python3
"""
Objection iOS Security Assessment Automation
Automates common Objection commands for iOS app security testing.
Runs keychain dump, storage inspection, SSL pinning check, and jailbreak detection analysis.
Usage:
python process.py --bundle-id com.target.app [--device-id UDID] [--output report.json]
"""
import argparse
import json
import subprocess
import sys
import re
from datetime import datetime
from pathlib import Path
class ObjectionAssessor:
"""Automates Objection-based iOS security assessment tasks."""
def __init__(self, bundle_id: str, device_id: str = None):
self.bundle_id = bundle_id
self.device_id = device_id
self.findings = []
def _run_objection_command(self, command: str, timeout: int = 30) -> str:
"""Execute an Objection command and return output."""
cmd = ["objection", "--gadget", self.bundle_id, "run", command]
if self.device_id:
cmd.insert(1, "--serial")
cmd.insert(2, self.device_id)
try:
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=timeout,
)
return result.stdout + result.stderr
except subprocess.TimeoutExpired:
return f"TIMEOUT: Command '{command}' exceeded {timeout}s"
except FileNotFoundError:
return "ERROR: Objection not found. Install with: pip install objection"
def _run_frida_command(self, script: str, timeout: int = 15) -> str:
"""Execute a Frida script snippet."""
cmd = ["frida", "-U", "-n", self.bundle_id, "-e", script]
if self.device_id:
cmd.extend(["-D", self.device_id])
try:
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=timeout,
)
return result.stdout
except (subprocess.TimeoutExpired, FileNotFoundError):
return ""
def check_frida_connectivity(self) -> dict:
"""Verify Frida can connect to the device."""
cmd = ["frida-ps", "-U"]
if self.device_id:
cmd.extend(["-D", self.device_id])
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
connected = result.returncode == 0
processes = len(result.stdout.strip().split("\n")) - 1 if connected else 0
return {
"connected": connected,
"process_count": processes,
"target_running": self.bundle_id in result.stdout,
}
except (subprocess.TimeoutExpired, FileNotFoundError):
return {"connected": False, "process_count": 0, "target_running": False}
def dump_keychain(self) -> dict:
"""Dump keychain items accessible to the app."""
output = self._run_objection_command("ios keychain dump")
items = []
current_item = {}
for line in output.split("\n"):
line = line.strip()
if "Service" in line and ":" in line:
if current_item:
items.append(current_item)
current_item = {"service": line.split(":", 1)[-1].strip()}
elif "Account" in line and ":" in line:
current_item["account"] = line.split(":", 1)[-1].strip()
elif "Data" in line and ":" in line:
data = line.split(":", 1)[-1].strip()
current_item["data_preview"] = data[:50] + "..." if len(data) > 50 else data
current_item["data_length"] = len(data)
if current_item:
items.append(current_item)
finding = {
"check": "keychain_dump",
"category": "MASVS-STORAGE",
"owasp_mobile": "M9",
"items_found": len(items),
"items": items[:20],
"severity": "HIGH" if items else "INFO",
"description": f"Found {len(items)} keychain items accessible to the application",
}
self.findings.append(finding)
return finding
def check_nsuserdefaults(self) -> dict:
"""Inspect NSUserDefaults for sensitive data."""
output = self._run_objection_command("ios nsuserdefaults get")
sensitive_patterns = [
"password", "token", "secret", "key", "auth",
"session", "credential", "api_key", "apikey",
]
sensitive_entries = []
for line in output.split("\n"):
line_lower = line.lower()
for pattern in sensitive_patterns:
if pattern in line_lower:
sensitive_entries.append(line.strip())
break
finding = {
"check": "nsuserdefaults",
"category": "MASVS-STORAGE",
"owasp_mobile": "M9",
"sensitive_entries": len(sensitive_entries),
"entries": sensitive_entries[:10],
"severity": "HIGH" if sensitive_entries else "PASS",
"description": f"Found {len(sensitive_entries)} potentially sensitive NSUserDefaults entries",
}
self.findings.append(finding)
return finding
def check_ssl_pinning(self) -> dict:
"""Assess SSL pinning implementation."""
output = self._run_objection_command("ios sslpinning disable")
pinning_detected = "pinning" in output.lower() or "hook" in output.lower()
finding = {
"check": "ssl_pinning",
"category": "MASVS-NETWORK",
"owasp_mobile": "M5",
"pinning_detected": pinning_detected,
"bypass_output": output[:500],
"severity": "MEDIUM" if not pinning_detected else "INFO",
"description": "SSL pinning " + ("detected and bypassed" if pinning_detected else "not detected"),
}
self.findings.append(finding)
return finding
def check_jailbreak_detection(self) -> dict:
"""Assess jailbreak detection implementation."""
output = self._run_objection_command("ios jailbreak disable")
detection_found = "hook" in output.lower() or "bypass" in output.lower()
finding = {
"check": "jailbreak_detection",
"category": "MASVS-RESILIENCE",
"owasp_mobile": "M7",
"detection_implemented": detection_found,
"bypass_output": output[:500],
"severity": "MEDIUM" if not detection_found else "INFO",
"description": "Jailbreak detection " + ("found" if detection_found else "not found or not implemented"),
}
self.findings.append(finding)
return finding
def search_sensitive_memory(self) -> dict:
"""Search app memory for sensitive strings."""
patterns = ["password", "Bearer ", "eyJ", "api_key", "secret"]
memory_findings = []
for pattern in patterns:
output = self._run_objection_command(f'memory search "{pattern}" --string')
matches = output.count("Found")
if matches > 0:
memory_findings.append({
"pattern": pattern,
"matches": matches,
})
finding = {
"check": "memory_search",
"category": "MASVS-STORAGE",
"owasp_mobile": "M9",
"patterns_with_matches": len(memory_findings),
"details": memory_findings,
"severity": "HIGH" if memory_findings else "PASS",
"description": f"Found sensitive patterns in memory for {len(memory_findings)} search terms",
}
self.findings.append(finding)
return finding
def get_app_info(self) -> dict:
"""Gather basic app information."""
output = self._run_objection_command("ios info binary")
env_output = self._run_objection_command("env")
return {
"bundle_id": self.bundle_id,
"binary_info": output[:1000],
"environment": env_output[:1000],
}
def generate_report(self) -> dict:
"""Generate consolidated assessment report."""
severity_counts = {"HIGH": 0, "MEDIUM": 0, "LOW": 0, "INFO": 0, "PASS": 0}
for f in self.findings:
sev = f.get("severity", "INFO")
severity_counts[sev] = severity_counts.get(sev, 0) + 1
return {
"assessment": {
"target": self.bundle_id,
"date": datetime.now().isoformat(),
"tool": "Objection (Frida-powered)",
"type": "iOS Runtime Security Assessment",
},
"summary": {
"total_checks": len(self.findings),
"severity_breakdown": severity_counts,
"critical_findings": [
f for f in self.findings if f.get("severity") in ("HIGH", "CRITICAL")
],
},
"findings": self.findings,
}
def main():
parser = argparse.ArgumentParser(
description="Objection iOS Security Assessment Automation"
)
parser.add_argument("--bundle-id", required=True, help="iOS app bundle identifier")
parser.add_argument("--device-id", help="Device UDID for targeting specific device")
parser.add_argument("--output", default="objection_report.json", help="Output report path")
parser.add_argument("--checks", nargs="+",
default=["keychain", "nsuserdefaults", "ssl", "jailbreak", "memory"],
help="Checks to run")
args = parser.parse_args()
assessor = ObjectionAssessor(args.bundle_id, args.device_id)
# Verify connectivity
connectivity = assessor.check_frida_connectivity()
if not connectivity["connected"]:
print("[-] ERROR: Cannot connect to device via Frida")
print(" Ensure Frida server is running on device or IPA is patched")
sys.exit(1)
print(f"[+] Connected to device. Target running: {connectivity['target_running']}")
# Run selected checks
check_map = {
"keychain": assessor.dump_keychain,
"nsuserdefaults": assessor.check_nsuserdefaults,
"ssl": assessor.check_ssl_pinning,
"jailbreak": assessor.check_jailbreak_detection,
"memory": assessor.search_sensitive_memory,
}
for check in args.checks:
if check in check_map:
print(f"[*] Running check: {check}")
result = check_map[check]()
print(f" Severity: {result['severity']} - {result['description']}")
# Generate report
report = assessor.generate_report()
with open(args.output, "w") as f:
json.dump(report, f, indent=2)
print(f"\n[+] Report saved: {args.output}")
# Summary
high_count = report["summary"]["severity_breakdown"].get("HIGH", 0)
if high_count > 0:
print(f"[!] {high_count} HIGH severity findings require attention")
if __name__ == "__main__":
main()