IPA
IPA File¶
An IPA file is just a Zip File with the folder information below
Example IPA File Structure:
Payload
└── APPNAME.app
├── _CodeSignature
│ └── CodeResources
├── [email protected]
├── AppIcon76x76@2x~ipad.png
├── Assets.car
├── Base.lproj
│ └── Localizable.strings
├── Frameworks
│ ├── AFNetworking.framework
│ ├── DoubleConversion.framework
│ ├── Eureka.framework
│ ├── FMDB.framework
│ ├── libswiftAccelerate.dylib
│ ├── SQLCipher.framework
│ │ ├── _CodeSignature
│ │ │ └── CodeResources
│ │ ├── Info.plist
│ │ ├── SC_Info
│ │ │ ├── SQLCipher.sinf
│ │ │ ├── SQLCipher.supf
│ │ │ ├── SQLCipher.supp
│ │ │ └── SQLCipher.supx
│ │ ├── SQLCipher
│ │ └── SQLCipher.i64
│ │ ├── info.png
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── success.png
│ │ ├── [email protected]
│ │ └── [email protected]
│ └── yoga.framework
│ ├── _CodeSignature
│ │ └── CodeResources
│ ├── Info.plist
│ ├── SC_Info
│ │ ├── yoga.sinf
│ │ ├── yoga.supf
│ │ ├── yoga.supp
│ │ └── yoga.supx
│ └── yoga
├── FullscreenImageVC.nib
Look at the .plist and .json files sensitive data can be included in the application.
Check the Info.plist
for application configuration.
Permissions¶
The user Grants the Permissions at runtime like the new android model.
Permissions:
- Contacts
- Microphone
- Calendars
- Camera
- Reminders
- HomeKit
- Photos
- Health
- Motion activity and fitness
- Speech recognition
- Location Services
- Bluetooth sharing
- Media Library
- Social media accounts
Entitlements¶
Entitlements are Permissions to iOS Sanboxed data.
These are stored in a Plist file called archived-expanded-entitlements.xcent.
Example archived-expanded-entitlements.xcent file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>69CN5HMUNT.co.razio.RS-Exchange</string>
<key>keychain-access-groups</key>
<array>
<string>69CN5HMUNT.co.razio.RS-Exchange</string>
</array>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:telegram.me</string>
<string>applinks:t.me</string>
</array>
</dict>
</plist>
Contains URLs this app can open:
plist Files¶
Read though objection:
OWASP.iGoat-Swift on (iPhone: 12.0) [usb] # ios plist cat <myfile.plist>
Read through plutil:
plutil -convert xml1 Info.plist
Info.plist¶
Contains Information about the application. Similar to Application Manifest.xml
from Android.
- NSAppTransportSecurity
- NSAllowsArbitraryLoads
- NSAllowsArbitraryLoadsForMedia
- NSAllowsArbitraryLoadsInWebContent
- NSAllowsLocalNetworking
- NSExceptionDomains
- NSIncludesSubdomains
- NSExceptionAllowsInsecureHTTPLoads
- NSExceptionMinimumTLSVersion
- NSExceptionRequiresForwardSecrecy
- NSRequiresFCertificateTransparency
Full list of Keys.
Encrypted Executable¶
When downloading from the App store the Executable code is encrypted. Apple uses a custom DRM technology called FairPlay. To decrypt it it needs to be run then dumped from memory.
- The Decryption key is associated with the Apple Id that downloaded the application.
- The Private key is stored on the iOS device when signing into the apple store.
- The decryption keys are in the SC_Info
folder.
Todo
Look into https://github.com/ChiChou/bagbak
Is the Executable Encrypted:
>>> otool -l Safari | grep -A4 LC_ENCRYPTION_INFO_64
cmd LC_ENCRYPTION_INFO_64
cmdsize 24
cryptoff 16384
cryptsize 1146880
cryptid 1
Check if PIE flag is enabled:
otool -Vh <TARGETMACHO>
Check if stack smashing protections are enabled:
otool -Iv <TARGETMACHO> | grep -i stack
Check if Automatic Reference Counting (ARC) is enabled:
otool -Iv <TARGETMACHO> | grep -iE "objc_autorelease|objc_release"
Convert Fat binary into a thin binary:*
>>> otool -hv DamnVulnerableIOSApp
DamnVulnerableIOSApp (architecture armv7):
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC ARM V7 0x00 EXECUTE 38 4292 NOUNDEFS DYLDLINK TWOLEVEL WEAK_DEFINES BINDS_TO_WEAK PIE
DamnVulnerableIOSApp (architecture arm64):
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 ARM64 ALL 0x00 EXECUTE 38 4856 NOUNDEFS DYLDLINK TWOLEVEL WEAK_DEFINES BINDS_TO_WEAK PIE
>>> lipo -thin armv7 DamnVulnerableIOSApp -output DVIA32
Without Jailbreak¶
https://github.com/DerekSelander/yacd
Through Frida Script (Old Don't Use)¶
Using the Frida Script:
>>> frida -U "Test App" /opt/Memory/Mobile/frida_iOS_dump_ipa.js
____
/ _ | Frida 12.3.6 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at http://www.frida.re/docs/home/
[iOS Device::Test App]-> dumpModule(".app")
Fix decrypted at:ca0
Fix decrypted at:4000
Decrypted file at:/var/mobile/Containers/Data/Application/1BD09CA5-BFB1-4223-99A4-4FCD6EC8A784/Library/mscrmapp.decrypted 0x550000
undefined
[iOS Device::Test App]->
Copy decrypted File:
scp -P 2222 -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null [email protected]:/var/mobile/Containers/Data/Application/1BD09CA5-BFB1-4223-99A4-4FCD6EC8A784/Library/mscrmapp.decrypted .
Through Frida Python (Old Donot use)¶
Checkout Python3 Version:
git clone https://github.com/AloneMonkey/frida-ios-dump
cd frida-ios-dump
git checkout 3.x
Change SSH Connection information:
vim dump.py
Dump app:
>>> python2 dump.py -o Test\ App\ 13.19043.32_decrypted.ipa com.test.iphone.app
/usr/lib/python3.7/site-packages/paramiko/kex_ecdh_nist.py:39: CryptographyDeprecationWarning: encode_point has been deprecated on EllipticCurvePublicNumbers and will be removed in a future version. Please use EllipticCurvePublicKey.public_bytes to obtain both compressed and uncompressed point encoding.
m.add_string(self.Q_C.public_numbers().encode_point())
/usr/lib/python3.7/site-packages/paramiko/kex_ecdh_nist.py:96: CryptographyDeprecationWarning: Support for unsafe construction of public numbers from encoded data will be removed in a future version. Please use EllipticCurvePublicKey.from_encoded_point
self.curve, Q_S_bytes
/usr/lib/python3.7/site-packages/paramiko/kex_ecdh_nist.py:111: CryptographyDeprecationWarning: encode_point has been deprecated on EllipticCurvePublicNumbers and will be removed in a future version. Please use EllipticCurvePublicKey.public_bytes to obtain both compressed and uncompressed point encoding.
hm.add_string(self.Q_C.public_numbers().encode_point())
Start the target app com.test.iphone.app
Dumping Test App to /tmp
[frida-ios-dump]: IntuneMAMWalledGarden.framework has been loaded.
start dump /var/containers/Bundle/Application/D9187540-72A8-465E-88E5-E86C9ADD6B0D/mscrmapp.app/mscrmapp
mscrmapp.fid: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████| 6.82M/6.82M [00:00<00:00, 15.9MB/s]
start dump /private/var/containers/Bundle/Application/D9187540-72A8-465E-88E5-E86C9ADD6B0D/mscrmapp.app/Frameworks/IntuneMAMWalledGarden.framework/IntuneMAMWalledGarden
IntuneMAMWalledGarden.fid: 100%|██████████████████████████████████████████████████████████████████████████████████████████| 5.27M/5.27M [00:00<00:00, 20.9MB/s]
Resources.strings: 53.3MB [00:09, 5.73MB/s]
0.00B [00:00, ?B/s]
Generating "13.19043.32_decrypted.ipa"
Before iOS 11¶
Use Clutch to list the installed applications on your device:
>>> ./Clutch-2.0.4 -i
Installed apps:
[...]
2: Duo Mobile <com.duosecurity.DuoMobile>
Use Clutch to decrypt the application you just downloaded by passing its index:
Clutch -d 1
Wait for Clutch to finish, then in the output you'll see Clutch saved the decrypted application in /private/var/mobile/Documents/Dumped.
On your computer, on a different terminal window, copy the dumped application to your machine:
scp -P 2222 -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null root@localhost:/private/var/mobile/Documents/Dumped/<app-name>.ipa .
Through bfinject (Old Do not use)¶
Note
Tweaks must be disabled in Electra
Copy the bfinject directory to idevice:
scp -P 2222 -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -r /opt/iOS/tools/bfinject [email protected]:/electra/
Run bfinject on the app:
cd /electra/bfinject
bash ./bfinject -P RubyBrowser.app -l dylibs/bfdecrypt.dylib
Use Netcat to copy the file to an IPA file:
>>> nc 172.20.10.6 31336 > decrypted.ipa
>>> ls -l decrypted.ipa
-rw-r--r-- 1 carl wheel 14649063 Jan 25 16:57 decrypted.ipa
>>> file decrypted.ipa
decrypted.ipa: iOS App Zip archive data, at least v2.0 to extract
Manually through lldb¶
https://labs.f-secure.com/blog/repacking-and-resigning-ios-applications/
Third Party Libraries¶
View Library from the Frameworks folder.
Get the Version from XXXXX.
LocalAuthentication.framework¶
- Fingerprint check can be bypassed.
Security.framework¶
- Fingerprint check can be bypassed.
AFNetworking.framework¶
- Version 2.5.1 has Certificate Checking bug
Code Signing¶
Every application must be signed for iOS. But at least it is possible to sign an application for free for 7 days at a time.
View code signing information:
$ codesign -dvvv YOURAPP.app
Executable=/Users/Documents/YOURAPP/Payload/YOURAPP.app/YOURNAME
Identifier=com.example.example
Format=app bundle with Mach-O universal (armv7 arm64)
CodeDirectory v=20200 size=154808 flags=0x0(none) hashes=4830+5 location=embedded
Hash type=sha256 size=32
CandidateCDHash sha1=455758418a5f6a878bb8fdb709ccfca52c0b5b9e
CandidateCDHash sha256=fd44efd7d03fb03563b90037f92b6ffff3270c46
Hash choices=sha1,sha256
CDHash=fd44efd7d03fb03563b90037f92b6ffff3270c46
Signature size=4678
Authority=iPhone Distribution: Example Ltd
Authority=Apple Worldwide Developer Relations Certification Authority
Authority=Apple Root CA
Signed Time=4 Aug 2017, 12:42:52
Info.plist entries=66
TeamIdentifier=8LAMR92KJ8
Sealed Resources version=2 rules=12 files=1410
Internal requirements count=1 size=176
Signing with iOS App Signer¶
https://dantheman827.github.io/ios-app-signer/
Signing with Impactor (Doesn't Currently Work)¶
Use Cydia Impactor on OSX, Windows or Linux.
- Start Impactor
- Drag the target application IPA file (from GUI application, such as Explorer or Finder) into the Impactor window
- Enter the throw-away Apple ID credentials when prompted
- Navigate (on the iOS device) to Settings > General > Profiles or Profiles & Device Management and tap the profile listed with the email address associated with your Apple ID
- Choose "Trust [APPLE ID]" and tap through warnings
- Choose "Verify App" and tap through warnings
Changes Signature files which may affect the application
Signing Semi Manually with Xcode¶
Export Mobile Provision Profiles:
1. Start a project in XCode
2. Setup Auto Signing under the Signing and Capabilities.
3. Make a unique Bundle Identifier.
4. Go to Settings -> Accounts -> Apple IDs -> Click the Gear -> Export Apple ID and Code Signing
5. unzip the file
6. Will be located in ./developer/profile/*.mobileprovision
Get provision profile information:
security cms -D -i ./developer/profile/*.mobileprovision
Sign the app with applesign:
./node-applesign-master/bin/applesign.js -w -c -b com.example.bundleid -m "~/Downloads/developer/profile/c*.mobileprovision" 1.3.9-12.0-12.4.ipa -o Chimera.ipa
Install the app:
ios-deploy --id <device_id> -b Chimera.ipa
Manually¶
Do it manually - a good white-paper to understand it:
# create a backup of the IPA file - so if something goes wrong you can restart
cp <IPA_FILE> <IPA_FILE>.bak
# unzip the file
unzip <IPA_FILE>
# download last version of frida-gadget
curl -O https://build.frida.re/frida/ios/lib/FridaGadget.dylib
mv FridaGadget.dylib Payload/<CLIENT_APP>/
Use insert_dylib
# patch the binary to load frida-gadget upon startup
insert_dylib --strip-codesig --inplace @executable_path/FridaGadget.dylib Payload/<CLIENT_APP>/<CLIENT_BIN>
zip -r <CLIENT_APP>.ipa Payload
Use node-applesign to resign the application
# it overrides your IPA file -> make sure to have a backup of the file first
./bin/applesign.js -i <CODE_SIGN_ID> -c -m <MOB_PROVISION_FILE> <IPA_FILE>
Get Developer account CODE_SIGN_ID:
# retrieve your signing IDs
>>> security find-identity -v -p codesigning
1) 0A765C06838ED4FD[REMOVED] "Apple Development: <emailaddress> (SHORTHASH)"
1 valid identities found
Get MOB_PROVISION_FILE:
Get ENTITLMENTS_FILE:
# fetch ents from the unencrypted IPA file unzipped
codesign -d --entitlements :- "Payload/<CLIENT_APP>" > ents.xml
# you need to manually update the Team ID value in this ents.xml, according to your mobile
# provision file. You can use the ID of the hello-world app you created with xcode
# The ID is usually the value in all capital letters/numbers.
# use vim
# :%s/<CLIENT_APP_ID>/<YOUR_APP_ID>/g
Redeploy the IPA file:
unzip <IPA_FILE_RESIGNED>
ios-deploy -b Payload/<YOUR_APP>
# or
ipa-deploy <IPA_FILE_RESIGNED>
Manualy sign the IPA file:
codesign -f -s 'iPhone Developer: <emailaddress> (SHORTHASH)' --entitlements entitlements.xml <Binarry>
Pushing to the iPhone¶
https://github.com/ios-control/ios-deploy
ios-deploy -b PAYLOAD/<CLIENT_APP> -d
Installing Unsigned Applications (Deprecated)¶
Debugging¶
Debug Server Setup¶
Getting the Developer Tools:
>>> hdiutil attach /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/<LATESTiOSVERSION>/DeveloperDiskImage.dmg
>>> cp /Volumes/DeveloperDiskImage/usr/bin/debugserver .
Sign and push the binary:
>>> cat entitlements.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/ PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.private.security.no-container</key>
<true/>
<key>com.apple.private.skip-library-validation</key>
<true/>
<key>com.apple.backboardd.launchapplications</key>
<true/>
<key>com.apple.diagnosticd.diagnostic</key>
<true/>
<key>com.apple.frontboard.debugapplications</key>
<true/>
<key>com.apple.frontboard.launchapplications</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.system-task-ports</key>
<true/>
<key>platform-application</key>
<true/>
<key>get-task-allow</key>
<true/>
<key>task_for_pid-allow</key>
<true/>
<key>com.apple.backboardd.debugapplications</key>
<true/>
<key>com.apple.springboard.debugapplications</key>
<true/>
<key>run-unsigned-code</key>
<true/>
<key>com.apple.private.librarian.can-get-application-info</key>
<true/>
<key>com.apple.private.mobileinstall.allowedSPI</key>
<array>
<string>Lookup</string>
<string>CopyInstalledAppsForLaunchServices</string>
</array>
</dict>
</plist>
>>> codesign -s --entitlements entitlements.plist -f debugserver
>>> scp -P 2222 -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null debugserver root@localhost:/var/root/debugserver
````
#### Debugging a iOS Application (lldb)
**Launch App from iOS:**
```bash
# to launch the app in debug mode
/var/root/debugserver 0.0.0.0:6666 -x auto /var/containers/Bundle/Application/4F2E06A0-B1C7-4F08-A00A-55644FEC55FE/DuoMobileApp.app/DuoMobileApp
# otherwise just wait for lldb
/var/root/debugserver 0.0.0.0:6666
Connect to the iOS Device from a Mac:
(lldb) platform select remote-ios
(lldb) process connect connect://<DEVICE_IP>:6666
(lldb) process attach --name <CLIENT_APP> --wait-for
Anti Anti Debugging stuff¶
Install Anti Debugging Tools:
#Install chisel
brew update
brew install chisel
#Edit lldb initialization file
touch ~/.lldbinit
echo "command script import /usr/local/opt/chisel/libexec/fblldb.py" >> ~/.lldbinit
echo "settings set target.load-cwd-lldbinit true" >> ~/.lldbinit
Anti Debug Tweak AntiAntiDebug