
Analyzing Ios App Security With Objection
- 352 installs
- 27.3k repo stars
- Updated August 2, 2026
- mukul975/anthropic-cybersecurity-skills
Run a structured Objection-based runtime security assessment on an iOS app and fill out a standardized report for keychain, storage, TLS, and binary protections.
About
Analyzing iOS App Security With Objection is an agent skill that turns Objection runtime findings into a repeatable security assessment report for solo builders and small teams shipping native iOS products. It is for developers who need App Store–adjacent assurance without hiring a full mobile pentest firm every sprint. Use it when you have a build on a jailbroken or instrumented device and want consistent tables for keychain secrets, local storage, network controls, and binary hardening instead of ad-hoc notes. The template forces explicit risk labels and check results so agents and humans can compare releases over time. It matters because mobile data leaks and weak TLS often surface only under dynamic analysis, and a fixed schema makes those issues citable for fix tickets and stakeholder sign-off.
- Report skeleton covering engagement metadata, executive summary, and analyst traceability
- Keychain table mapped by service, account, protection class, and risk tier
- NSUserDefaults, SQLite, and filesystem rows for sensitive-data classification
- Network section for SSL pinning presence, bypass outcome, and ATS strictness
- Binary protection status block aligned to jailbroken vs non-jailbroken device state
Analyzing Ios App Security With Objection by the numbers
- 352 all-time installs (skills.sh)
- +25 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #581 of 2,203 Security skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill analyzing-ios-app-security-with-objectionAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 352 |
|---|---|
| repo stars | ★ 27.3k |
| Security audit | 2 / 3 scanners passed |
| Last updated | August 2, 2026 |
| Repository | mukul975/anthropic-cybersecurity-skills ↗ |
What it does
Run a structured Objection-based runtime security assessment on an iOS app and fill out a standardized report for keychain, storage, TLS, and binary protections.
Files
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 patchipato 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:
# 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 deviceFor non-jailbroken devices (authorized testing):
# Patch IPA with Frida gadget
objection patchipa --source target.ipa --codesign-signature "Apple Development: test@example.com"
# Install patched IPA
ideviceinstaller -i target-patched.ipaStep 2: Attach Objection to Target App
# 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)
# 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 monitorStep 4: Evaluate Network Security (MASVS-NETWORK)
# 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 NSURLConnectionStep 5: Inspect Authentication and Authorization (MASVS-AUTH)
# 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 LAContextStep 6: Assess Binary Protections (MASVS-RESILIENCE)
# 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)
# 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 UITextFieldKey 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-commandto 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 classeswith grep to find demangled names. - Non-persistent changes: All Objection modifications are runtime-only and reset on app restart. Document findings immediately.
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]
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to the Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by the Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding any notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. Please do not remove or change
the license header comment from a contributed file except when
necessary.
Copyright 2026 mukul975
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
API Reference: iOS App Security with Objection
Objection CLI
Launch
objection -g com.example.app explore # Attach to running app
objection -g com.example.app explore -s "command" # Run startup command
objection patchipa --source app.ipa # Patch IPA with Frida gadgetKeychain & Data Storage
ios keychain dump # Dump keychain items
ios keychain dump --json # JSON output
ios cookies get # List HTTP cookies
ios nsuserdefaults get # Read NSUserDefaults
ios plist cat Info.plist # Read plist fileSSL Pinning
ios sslpinning disable # Bypass SSL pinning
ios sslpinning disable --quiet # Quiet modeJailbreak Detection
ios jailbreak disable # Bypass jailbreak detection
ios jailbreak simulate # Simulate jailbroken deviceHooking
ios hooking list classes # List all classes
ios hooking list classes --include Auth # Filter classes
ios hooking list class_methods ClassName # List methods
ios hooking watch method "-[Class method]" # Watch method calls
ios hooking set return_value "-[Class isJB]" false # Override returnFilesystem
ls / # List app sandbox root
ls /Documents # List Documents directory
file download /path/to/file local.out # Download file
file upload local.file /remote/path # Upload fileMemory
memory dump all dump.bin # Dump all memory
memory search "password" # Search memory for string
memory list modules # List loaded modules
memory list exports libModule.dylib # List module exportsFrida CLI
Syntax
frida -U -n AppName # Attach by name
frida -U -f com.app.id # Spawn and attach
frida -U -n AppName -l script.js # Load script
frida-ps -U # List running processes
frida-ls-devices # List connected devicesCommon Frida Scripts
// Hook method and log arguments
ObjC.choose(ObjC.classes.ClassName, {
onMatch: function(instance) {
Interceptor.attach(instance['- methodName:'].implementation, {
onEnter: function(args) {
console.log('arg1:', ObjC.Object(args[2]));
}
});
}, onComplete: function() {}
});OWASP Mobile Top 10 (2024)
| ID | Category | Objection Check |
|---|---|---|
| M1 | Improper Credential Usage | ios keychain dump |
| M2 | Inadequate Supply Chain Security | Binary analysis |
| M3 | Insecure Authentication | Hook auth classes |
| M4 | Insufficient Input/Output Validation | Hook input methods |
| M5 | Insecure Communication | ios sslpinning disable |
| M6 | Inadequate Privacy Controls | ios nsuserdefaults get |
| M7 | Insufficient Binary Protections | Check PIE, ARC, stack canary |
| M8 | Security Misconfiguration | ios plist cat Info.plist |
| M9 | Insecure Data Storage | Filesystem + keychain review |
| M10 | Insufficient Cryptography | Hook crypto classes |
iOS App Sandbox Paths
| Path | Contents |
|---|---|
/Documents | User-generated data |
/Library/Caches | Cached data |
/Library/Preferences | Plist settings |
/tmp | Temporary files |
/Library/Cookies | Cookie storage |
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 |
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 |
#!/usr/bin/env python3
"""iOS app security analysis agent using Objection/Frida concepts.
Performs runtime security assessment of iOS apps including SSL pinning bypass,
keychain dumping, filesystem inspection, and jailbreak detection bypass.
"""
import subprocess
import json
import sys
def run_objection(command, app_id=None, timeout=30):
"""Execute an Objection command against a target app."""
cmd = ["objection"]
if app_id:
cmd.extend(["-g", app_id])
cmd.extend(["explore", "-c", command])
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
return result.stdout, result.returncode
except FileNotFoundError:
return "objection not installed (pip install objection)", 1
except subprocess.TimeoutExpired:
return "Command timed out", 1
def run_frida(script_code, app_id, timeout=30):
"""Execute a Frida script against target app."""
cmd = ["frida", "-U", "-n", app_id, "-e", script_code]
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
return result.stdout, result.returncode
except FileNotFoundError:
return "frida not installed (pip install frida-tools)", 1
except subprocess.TimeoutExpired:
return "Command timed out", 1
def dump_keychain(app_id):
"""Dump keychain items accessible by the application."""
return run_objection("ios keychain dump", app_id)
def dump_cookies(app_id):
"""Dump HTTP cookies stored by the application."""
return run_objection("ios cookies get", app_id)
def list_classes(app_id, filter_str=None):
"""List Objective-C classes loaded in the app."""
cmd = "ios hooking list classes"
if filter_str:
cmd += f" --include {filter_str}"
return run_objection(cmd, app_id)
def check_ssl_pinning(app_id):
"""Check and bypass SSL certificate pinning."""
return run_objection("ios sslpinning disable", app_id)
def check_jailbreak_detection(app_id):
"""Check for and bypass jailbreak detection."""
return run_objection("ios jailbreak disable", app_id)
def inspect_filesystem(app_id, path="/"):
"""Inspect the application's filesystem sandbox."""
return run_objection(f"ls {path}", app_id)
def dump_plist(app_id):
"""Dump application plist configuration files."""
return run_objection("ios plist cat Info.plist", app_id)
def check_pasteboard(app_id):
"""Check pasteboard/clipboard for sensitive data."""
return run_objection("ios pasteboard monitor", app_id)
def search_binary_strings(app_id, pattern):
"""Search for strings in the app binary."""
return run_objection(f"memory search '{pattern}'", app_id)
OWASP_MOBILE_CHECKS = {
"M1_Improper_Platform_Usage": {
"checks": ["ios keychain dump", "ios plist cat Info.plist"],
"description": "Check for misuse of platform security features",
},
"M2_Insecure_Data_Storage": {
"checks": ["ios keychain dump", "ios cookies get", "ios nsuserdefaults get"],
"description": "Check for sensitive data in insecure storage",
},
"M3_Insecure_Communication": {
"checks": ["ios sslpinning disable"],
"description": "Test SSL/TLS implementation and certificate pinning",
},
"M4_Insecure_Authentication": {
"checks": ["ios hooking list classes --include Auth",
"ios hooking list classes --include Login"],
"description": "Analyze authentication mechanisms",
},
"M5_Insufficient_Cryptography": {
"checks": ["ios hooking list classes --include Crypto",
"ios hooking list classes --include AES"],
"description": "Review cryptographic implementations",
},
"M8_Code_Tampering": {
"checks": ["ios jailbreak disable"],
"description": "Test runtime integrity and jailbreak detection",
},
"M9_Reverse_Engineering": {
"checks": ["ios hooking list classes"],
"description": "Assess reverse engineering protections",
},
}
def run_owasp_assessment(app_id):
"""Run OWASP Mobile Top 10 security checks."""
results = {}
for category, config in OWASP_MOBILE_CHECKS.items():
category_results = {"description": config["description"], "findings": []}
for check in config["checks"]:
output, rc = run_objection(check, app_id)
category_results["findings"].append({
"command": check,
"status": "success" if rc == 0 else "failed",
"output_preview": output[:200] if output else "",
})
results[category] = category_results
return results
FRIDA_SCRIPTS = {
"ssl_pinning_bypass": """
ObjC.choose(ObjC.classes.NSURLSessionConfiguration, {
onMatch: function(instance) {
instance['- setTLSMinimumSupportedProtocol:'](0);
}, onComplete: function() {}
});
""",
"jailbreak_bypass": """
var paths = ['/Applications/Cydia.app', '/usr/sbin/sshd', '/etc/apt'];
Interceptor.attach(ObjC.classes.NSFileManager['- fileExistsAtPath:'].implementation, {
onEnter: function(args) { this.path = ObjC.Object(args[2]).toString(); },
onLeave: function(retval) {
if (paths.some(p => this.path.includes(p))) retval.replace(0);
}
});
""",
"keychain_dump": """
var kSecClass = ObjC.classes.__NSDictionary.dictionaryWithObject_forKey_(
ObjC.classes.__NSCFConstantString.alloc().initWithUTF8String_('genp'),
ObjC.classes.__NSCFConstantString.alloc().initWithUTF8String_('class')
);
console.log('Keychain query prepared');
""",
}
def generate_report(app_id, assessment_results):
"""Generate iOS security assessment report."""
findings_count = sum(
len(cat["findings"]) for cat in assessment_results.values()
)
return {
"app_identifier": app_id,
"assessment_framework": "OWASP Mobile Top 10",
"categories_tested": len(assessment_results),
"total_checks": findings_count,
"results": assessment_results,
}
if __name__ == "__main__":
print("=" * 60)
print("iOS App Security Analysis Agent (Objection/Frida)")
print("Runtime analysis, SSL bypass, keychain dump, OWASP checks")
print("=" * 60)
app_id = sys.argv[1] if len(sys.argv) > 1 else None
if not app_id:
print("\n[DEMO] Usage: python agent.py <app_bundle_id>")
print(" e.g. python agent.py com.example.app")
print("\nAvailable checks:")
for category, config in OWASP_MOBILE_CHECKS.items():
print(f" {category}: {config['description']}")
print("\nFrida scripts available:")
for name in FRIDA_SCRIPTS:
print(f" {name}")
sys.exit(0)
print(f"\n[*] Target: {app_id}")
print("[*] Running OWASP Mobile Top 10 assessment...")
results = run_owasp_assessment(app_id)
report = generate_report(app_id, results)
for category, data in results.items():
status_counts = {"success": 0, "failed": 0}
for f in data["findings"]:
status_counts[f["status"]] += 1
print(f"\n [{category}] {data['description']}")
print(f" Checks: {status_counts['success']} passed, {status_counts['failed']} failed")
print(f"\n{json.dumps(report, indent=2, default=str)}")
#!/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()
Related skills
FAQ
Is Analyzing Ios App Security With Objection safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.