iOS Hacking with otool: A Step-by-Step Guide for Security Pros
“Ever wondered how hackers extract secrets from iOS apps? Meet otool — the powerful tool for dissecting iOS binaries like a pro. If you’re into iOS security, this guide is a must-read!”
otool — Object File Display Tool for macOS/iOS
otool
is a command-line utility on macOS and iOS used for analyzing object files, libraries, and executables. It’s useful for reverse engineering iOS applications, especially when inspecting binaries for security analysis and exploitation

📌 otool Checklist for iOS Pentesting
Open the terminal and take the ssh of your Iphone.
Command:- ssh root@<IP>
cd /var/containers/Bundle/Application/<APP_ID>/<app>

1️. Check Linked Libraries
otool -L <binary>
✅ Findings:
Look for insecure or third-party libraries.
Identify dependencies on security-related libraries (e.g.,
libcrypto
,libssl
).
2️. Check Position Independent Executable (PIE)
otool -hv <binary>
✅ Findings:
Look for
PIE
in the flags section.If missing, the binary is vulnerable to memory corruption exploits.
3️. Check Stack Canary Protection (SSP)
otool -Iv <binary> | grep stack
✅ Findings:
Look for
_stack_chk_guard
or_stack_chk_fail
.If missing, the binary lacks protection against stack overflow attacks.
4️. Check for ARC (Automatic Reference Counting)
otool -Iv <binary> | grep _objc_release
✅ Findings:
Memory management vulnerabilities (e.g., use-after-free) might exist if ARC is missing.
5️. Check for Encryption (FairPlay DRM)
otool -l <binary> | grep crypt
✅ Findings:
cryptid 1
→ Encrypted (App Store binary).
cryptid 0
→ Not encrypted (can be directly analyzed).
6️. Check for NX (No-Execute) Bit / DEP (Data Execution Prevention)
otool -lv <binary> | grep -A 5 LC_SEGMENT
✅ Findings:
If
__TEXT
isr-x
and__DATA
isrw-
, NX is enabled (good).If disabled, memory corruption exploits become easier.
7️. Check for Code-Signing
codesign -dvvv <binary>
✅ Findings:
Verifies whether the app is properly signed.
If unsigned or improperly signed, it may be modifiable.
8️. Check for Debug Symbols and Symbols Exposure
nm <binary> | grep “ U “
✅ Findings:
Debug symbols expose function names useful for reverse engineering.
Look for sensitive function names like
decrypt
,password
, etc.
9️. Check for RPATH and @rpath Usage (Dylib Hijacking Risk)
otool -l <binary> | grep -A 5 RPATH
✅ Findings:
If
@rpath
is present, it could be abused for dylib injection attacks.
10. Check Objective-C Class and Method Names
otool -oV <binary>
✅ Findings:
Extracts Objective-C class and method names.
Helps in identifying sensitive API calls.
11. Checking for Weak Hashing Algorithms
otool -Iv <app> | grep -w _CC_MD5
otool -Iv <app> | grep -w _CC_SHA1
otool -tv /path/to/binary | grep -iE “MD5|SHA1”
✅ Findings:
Common Weak Hashing Functions to Look For:
CC_MD5
CC_SHA1
CC_SHA1_Init
,CC_SHA1_Update
,CC_SHA1_Final
If
CC_MD5
orCC_SHA1
appears, the app is using weak hashing and should be replaced with SHA-256 or SHA-512.
12. Checking for Deprecated/Banned APIs
otool -Iv <app> | grep -w _stat
otool -Iv <app> | grep -w _sscanf
otool -Iv <app> | grep -w _strncpy
otool -Iv <app> | grep -w _strle
otool -tv /path/to/binary | grep -iE “system|exec|fork|dlopen|dlsym|getpw|strcpy|strcat|sprintf”
✅ Findings:
Apple bans certain APIs due to security risks, such as:
system()
exec()
,execve()
fork()
dlopen()
,dlsym()
getpwuid()
,getpwnam()
strcpy()
,strcat()
,sprintf()
If
system()
is present, the app is using command execution, which is risky.
13. Checking for Insecure Random Number Functions
otool -tv /path/to/binary | grep -iE “rand|srand|random”
✅ Findings:
Insecure Functions:
rand()
srand()
random()
Secure Alternative:
SecRandomCopyBytes()
14. Checking for Insecure Memory Functions
otool -tv /path/to/binary | grep -iE “memcpy|memmove|strcpy|strcat|sprintf|gets”
✅ Findings:
Insecure Functions:
strcpy()
strcat()
gets()
sprintf()
Secure Alternatives:
strncpy()
strlcpy()
snprintf()
memset_s()
📌 Bonus Checks
💡 Check Hardcoded Strings:
strings <binary> | grep -i “password\|token\|api”
Findings:
Look for hardcoded API keys, secrets, and sensitive info.
💡 Check App Entitlements:
codesign -d — entitlements — <binary>
Findings:
Look for excessive permissions (
get-task-allow
,com.apple.security.application-groups
).
I have written a script which will automate all the above key security checks for iOS pentesting using otool
How to use this script
1️⃣ Save the script as otool_checker.sh
nano otool_checker.sh
Paste the script inside and save (
CTRL+X
,Y
,Enter
).
2️⃣ Give execution permission
chmod +x otool_checker.sh
3️⃣ Run the script on an iOS binary
./otool_checker.sh <binary_file>
#!/bin/bash
# Check if a binary file is provided
if [ $# -ne 1 ]; then
echo "Usage: $0 <binary>"
exit 1
fi
BINARY=$1
echo "======================================"
echo "🔍 Enhanced iOS Binary Security Check"
echo "======================================"
# 1️⃣ Check Linked Libraries
echo -e "\n📌 Checking Linked Libraries..."
otool -L "$BINARY"
# 2️⃣ Check Position Independent Executable (PIE)
echo -e "\n📌 Checking PIE Support..."
PIE_CHECK=$(otool -hv "$BINARY" | grep PIE)
if [ -z "$PIE_CHECK" ]; then
echo "❌ PIE is NOT enabled! Binary is vulnerable to memory corruption attacks."
else
echo "✅ PIE is enabled."
fi
# 3️⃣ Check Stack Canary Protection (SSP)
echo -e "\n📌 Checking Stack Canary Protection..."
STACK_CANARY=$(otool -Iv "$BINARY" | grep stack_chk)
if [ -z "$STACK_CANARY" ]; then
echo "❌ Stack Canary is NOT enabled! Binary is vulnerable to buffer overflow attacks."
else
echo "✅ Stack Canary is enabled."
fi
# 4️⃣ Check for ARC (Automatic Reference Counting)
echo -e "\n📌 Checking ARC (Automatic Reference Counting)..."
ARC_CHECK=$(otool -Iv "$BINARY" | grep _objc_release)
if [ -z "$ARC_CHECK" ]; then
echo "❌ ARC is NOT enabled! There may be memory management vulnerabilities."
else
echo "✅ ARC is enabled."
fi
# 5️⃣ Check for Encryption (FairPlay DRM)
echo -e "\n📌 Checking Encryption Status..."
CRYPTID=$(otool -l "$BINARY" | grep cryptid | awk '{print $2}')
if [ "$CRYPTID" == "1" ]; then
echo "🔒 The binary is encrypted (FairPlay DRM enabled)."
else
echo "✅ The binary is NOT encrypted. Ready for analysis."
fi
# 6️⃣ Check for NX (No-Execute) Bit / DEP
echo -e "\n📌 Checking NX (No-Execute) Bit..."
NX_CHECK=$(otool -lv "$BINARY" | grep -A 5 LC_SEGMENT | grep __TEXT)
if [[ "$NX_CHECK" == *"r-x"* ]]; then
echo "✅ NX (DEP) is enabled."
else
echo "❌ NX (DEP) is NOT enabled! Memory corruption exploits are possible."
fi
# 7️⃣ Check for RPATH and @rpath Usage (Dylib Hijacking Risk)
echo -e "\n📌 Checking RPATH (Dylib Hijacking Risk)..."
RPATH_CHECK=$(otool -l "$BINARY" | grep -A 5 RPATH)
if [ -z "$RPATH_CHECK" ]; then
echo "✅ No @rpath found. Safe from dylib hijacking."
else
echo "⚠️ @rpath found! There might be a risk of dylib hijacking."
echo "$RPATH_CHECK"
fi
# 8️⃣ Check for Debug Symbols
echo -e "\n📌 Checking for Debug Symbols..."
DEBUG_SYMBOLS=$(nm "$BINARY" | grep " U ")
if [ -z "$DEBUG_SYMBOLS" ]; then
echo "✅ No debug symbols found."
else
echo "⚠️ Debug symbols found! Could help in reverse engineering."
echo "$DEBUG_SYMBOLS"
fi
# 9️⃣ Check Objective-C Class and Method Names
echo -e "\n📌 Extracting Objective-C Class and Method Names..."
otool -oV "$BINARY" | grep "name ="
# 🔟 Check for Weak Hashing Algorithms
echo -e "\n📌 Checking for Weak Hashing Algorithms (MD5, SHA-1)..."
HASH_CHECK=$(otool -Iv "$BINARY" | grep -E 'CC_MD5|CC_SHA1')
if [ -z "$HASH_CHECK" ]; then
echo "✅ No weak hashing algorithms detected."
else
echo "❌ Weak hashing algorithms found! Consider using SHA-256 or better."
echo "$HASH_CHECK"
fi
# 🔟+1 Check for Deprecated/Banned APIs
echo -e "\n📌 Checking for Deprecated/Banned APIs..."
BANNED_APIS=$(otool -Iv "$BINARY" | grep -E 'gets|strcpy|strcat|getpwuid|getpwnam|system|popen|sprintf|vsprintf')
if [ -z "$BANNED_APIS" ]; then
echo "✅ No banned/deprecated APIs found."
else
echo "❌ Banned APIs found! These can lead to security vulnerabilities."
echo "$BANNED_APIS"
fi
# 🔟+2 Check for Random Functions
echo -e "\n📌 Checking for Random Number Generation Functions..."
RANDOM_FUNCTIONS=$(otool -Iv "$BINARY" | grep -E 'rand|srand|random')
if [ -z "$RANDOM_FUNCTIONS" ]; then
echo "✅ No weak random functions detected."
else
echo "⚠️ Weak random functions detected! Ensure strong randomness using arc4random()."
echo "$RANDOM_FUNCTIONS"
fi
# 🔟+3 Check for Unsafe Memory Functions
echo -e "\n📌 Checking for Unsafe Memory Functions..."
MEMORY_FUNCTIONS=$(otool -Iv "$BINARY" | grep -E 'malloc|free|memcpy|memmove|bzero')
if [ -z "$MEMORY_FUNCTIONS" ]; then
echo "✅ No unsafe memory functions detected."
else
echo "⚠️ Unsafe memory functions detected! Ensure secure memory management."
echo "$MEMORY_FUNCTIONS"
fi
echo -e "\n✅ Security Check Complete!"
Have you used otool before? Share your experience in the comments!
Do you want me to cover another iOS pentesting topic next? do comments!
Thank you for reading !!
Do follow and subscribe for new upcoming blogs via mail on Medium
connect with me over LinkedIn