现时越狱越来越难了, iOS 10.2.1 - 11都没有有效的越狱. 没有有效的越狱, 我们就无法安装 frida-server, 也无法访问 localstorage, keychain 等.
本文为此阐述了如何在未越狱 iPhone 中运行 Frida.
- virtualev (optional, but highly recommended)
- nvm (optional, but highly recommended)
1.1 Installing python3 & pip3
Since Mac has python2 preinstalled, we need to install python3 & pip3 separately.
$ brew install python3
After installation, you would have python3 and pip3. However, as python2 and python3 co-exist, you need to run
pip for python2,
pip3 for python3.
NIN: If homebrew is yet to be installed, visit Homebrew — The missing package manager for macOS for details on installation.
1.2 Installing virtualenv
$ pip3 install --user virtualenv
1.3 Installing objection
$ mkdir objection $ cd objection $ virtualenv -p python3 venv $ source venv/bin/activate $ pip3 install -U objection
NIN: It is recommended using nvm to manage node & npm. Visit Github for more details.
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash
After running above command, it would clone the nvm repository to
~/.nvm. If after installation, it still complains
nvm not found, add below lines to your profile (~/.bash_profile, ~/.zshrc, ~/.profile, or ~/.bashrc), depending on what shell are you using.
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
NIN: 6.10.3 is used for this tutorial.
$ nvm install 6.10.3 $ node -v v6.10.3
1.5 Installing applesign
$ npm install -g applesign $ which applesign /Users/its/.nvm/versions/node/v6.10.3/bin/applesign
1.6 Installing insert_dylib
$ git clone https://github.com/Tyilo/insert_dylib $ cd insert_dylib $ xcodebuild $ cp build/Release/insert_dylib /usr/local/bin/insert_dylib $ which insert_dylib /usr/local/bin/insert_dylib
xcodebuildis not found, make sure you have installed command line tools with
1.7 Installing ios-deploy
$ npm install -g ios-deploy $ which ios-deploy /usr/local/bin/ios-deploy
2. Patching iOS Applications
2.1 XCode Developer Certificate
First and foremost, you need to register for an Apple Developer account. A free one works fine, but you need to keep in mind that you will only be allowed to run patched applications for 7 days, before repeating the patching/signing/installation process again
- Visit https://developer.apple.com/register/ and agree to the license agreement.
- Sign in with your AppleID in XCode by browsing to "XCode" -> "Preferences" -> "Accounts" and clicking on the "+" at the bottom left.
- Click on "Manage Certificates" and click on the "+" drop down, selecting "iOS Development". XCode will generate a new code signing certificate for you to use.
- Click "Done".
Once you have a developer account signed in to in XCode, you will now be able to sideload applications and run them on iOS devices. You can also check for code signing certificates that are now available in a terminal:
$ security find-identity -p codesigning -v 1) CC295C1137E6F2A08B26Axxxxxx "iPhone Developer: firstname.lastname@example.org (RF6X7S2JSJ)" 2) 00DB9FD78FA8E21CE3793xxxxxx "iPhone Developer: email@example.com (4X74WJ9LKM)" (CSSMERR_TP_CERT_REVOKED) 3) DA44B44E56769CF64B1D2xxxxxx "iPhone Developer: firstname.lastname@example.org (4X74WJ9LKM)" 3 valid identities found
With XCode ready we can now generate the .mobileprovison file we need. This file contains some certificate information as well as the entitlements groups for the application. To generate the .mobileprovision file, all we need to do is build and deploy a blank iOS application to an iOS device. The build process will leave an embedded.mobileprovision file in
~/Library/Developer/Xcode/DerivedData/ for us to pick up and re-use. When you run the
objection patchipa command, it will automatically search for a valid embedded.mobileprovision file in
~/Library/Developer/Xcode/DerivedData/ to use.
So, to build and deploy a blank iOS application using XCode to get the updated
embedded.mobileprovision file you need:
- Start XCode and select "Create new XCode Project"
- Select "iOS" -> "Single View Application" and hit next.
- Fill in a Product name, choose a unique organization identifier and hit next.
- Choose where to save the project and finally click on "Create".
- In the projects root, under the "General" tab, ensure that there are no errors with the signing certificate. Most of the time, XCode is pretty verbose with what needs to be done to fix any errors you may encounter, so just take a moment to read.
- When done, ensure your iOS device is plugged in. Select it as the target device in the top left corner, and hit the big play button. This process will compile the blank app for the target device, and leave that embedded.mobileprovision file on disk for us to pick up later.
- You should now see the application has been installed on your iPhone. Then trust your iTunes account to run code on your iOS device.
Settings App -> General -> Profiles & Device Management -> Select your iTunes account from the "Developer App" section -> Select "Trust".
$ objection patchipa --source my-app.ipa --codesign-signature CC295C1137E6F2A08B26Axxxxxx
It should work like a charm. A new IPA with Frida.dylib bundled will be created on the current path.
NIN: Make sure you are using ios-deploy with version 1.9.2. Otherwise, you may find an error -
[ !! ] Unable to mount developer disk image. (Ref: https://github.com/phonegap/ios-deploy/issues/221)
------ Debug phase ------ Starting debug of 63e8000a2b7f13b82caff22b8988c7b8424604e3 (N49AP, iPhone 5c (Global/CDMA), iphoneos, armv7s) a.k.a. 'Illnino的 iPhone' connected through USB... [ 0%] Looking up developer disk image 2017-10-30 23:13:05.504 ios-deploy[13314:7893719] [ !! ] Unable to mount developer disk image. (e8000033)
Run below command to install the latest version of ios-deploy.
npm install -g ios-deploy
3.2 Deploying the patched app
- Extract the IPA package with
unzip my-app.ipa. This should leave you with a Payload/ directory.
- Attach your iOS device to your computer via USB and ensure that it is unlocked.
- Run ios-deploy with
ios-deploy --bundle Payload/my-app.app -W -dwhere
my-app.appis the folder where your application lives.
$ unzip my-app.ipa $ objection ios-deploy --bundle Payload/MyApp.app -W -d [....] Waiting for iOS device to be connected [....] Using 63e8000a2b7f13b82caff22b8988c7b8424604e3 (N49AP, iPhone 5c (Global/CDMA), iphoneos, armv7s) a.k.a. 'Illnino的 iPhone'. ------ Install phase ------ [ 0%] Found 63e8000a2b7f13b82caff22b8988c7b8424604e3 (N49AP, iPhone 5c (Global/CDMA), iphoneos, armv7s) a.k.a. 'Illnino的 iPhone' connected through USB, beginning install [ 5%] Copying /Users/its/Project/tools/iOS/objection/Payload/MyApp.app/META-INF/ to device [REDACTED] [ 52%] CreatingStagingDirectory [ 57%] ExtractingPackage [ 60%] InspectingPackage [ 60%] TakingInstallLock [ 65%] PreflightingApplication [ 65%] InstallingEmbeddedProfile [ 70%] VerifyingApplication [ 75%] CreatingContainer [ 80%] InstallingApplication [ 85%] PostflightingApplication [ 90%] SandboxingApplication [ 95%] GeneratingApplicationMap [100%] Installed package Payload/MyApp.app ------ Debug phase ------ Starting debug of 63e8000a2b7f13b82caff22b8988c7b8424604e3 (N49AP, iPhone 5c (Global/CDMA), iphoneos, armv7s) a.k.a. 'Illnino的 iPhone' connected through USB... [ 0%] Looking up developer disk image [ 95%] Developer disk image mounted successfully [100%] Connecting to remote debug server ------------------------- (lldb) command source -s 0 '/tmp/869AF7F1-B18C-4049-8F0F-9A0973C76031/fruitstrap-lldb-prep-cmds-63e8000a2b7f13b82caff22b8988c7b8424604e3' Executing commands in '/tmp/869AF7F1-B18C-4049-8F0F-9A0973C76031/fruitstrap-lldb-prep-cmds-63e8000a2b7f13b82caff22b8988c7b8424604e3'. (lldb) platform select remote-ios --sysroot '/Users/its/Library/Developer/Xcode/iOS DeviceSupport/9.3.1 (13E238)/Symbols' Platform: remote-ios Connected: no SDK Path: "/Users/its/Library/Developer/Xcode/iOS DeviceSupport/9.3.1 (13E238)/Symbols" (lldb) target create "/Users/its/Project/tools/iOS/objection/Payload/MyApp.app" Current executable set to '/Users/its/Project/tools/iOS/objection/Payload/MyApp.app' (arm64). (lldb) script fruitstrap_device_app="/private/var/containers/Bundle/Application/CBC05B30-14E0-4542-969B-4B3505A7149A/MyApp.app" (lldb) script fruitstrap_connect_url="connect://127.0.0.1:64641" (lldb) target modules search-paths add /usr "/Users/its/Library/Developer/Xcode/iOS DeviceSupport/9.3.1 (13E238)/Symbols/usr" /System "/Users/its/Library/Developer/Xcode/iOS DeviceSupport/9.3.1 (13E238)/Symbols/System" "/private/var/containers/Bundle/Application/CBC05B30-14E0-4542-969B-4B3505A7149A" "/Users/its/Project/tools/iOS/objection/Payload" "/var/containers/Bundle/Application/CBC05B30-14E0-4542-969B-4B3505A7149A" "/Users/its/Project/tools/iOS/objection/Payload" /Developer "/Users/its/Library/Developer/Xcode/iOS DeviceSupport/9.3.1 (13E238)/Symbols/Developer" (lldb) command script import "/tmp/869AF7F1-B18C-4049-8F0F-9A0973C76031/fruitstrap_63e8000a2b7f13b82caff22b8988c7b8424604e3.py" (lldb) command script add -f fruitstrap_63e8000a2b7f13b82caff22b8988c7b8424604e3.connect_command connect (lldb) command script add -s asynchronous -f fruitstrap_63e8000a2b7f13b82caff22b8988c7b8424604e3.run_command run (lldb) command script add -s asynchronous -f fruitstrap_63e8000a2b7f13b82caff22b8988c7b8424604e3.autoexit_command autoexit (lldb) command script add -s asynchronous -f fruitstrap_63e8000a2b7f13b82caff22b8988c7b8424604e3.safequit_command safequit (lldb) connect (lldb) run success 2017-10-30 23:20:02.119 MyApp[8159:1933074] Frida: Listening on 127.0.0.1 TCP port 27042
At the very last line, you should see Frida-server is running on the iPhone. Leave this tab open.
3.3 Using Frida
Open another tab.
➜ App frida-ps -Uai PID Name Identifier ---- ------ --------------- 8176 Gadget re.frida.Gadget
➜ App frida -U 8176 ____ / _ | Frida 10.6.10 - A world-class dynamic instrumentation framework | (_| | > _ | Commands: /_/ |_| help -> Displays the help system . . . . object? -> Display information about 'object' . . . . exit/quit -> Exit . . . . . . . . More info at http://www.frida.re/docs/home/ [iPhone::PID::8176]->
3.4 Using objection
Alternatively, you could take full advantage of objection which has a list of pre-defined frida scripts.
com.myapp.mybank on (iPhone: 9.3.1) [usb] # ios keychain dump Note: You may be asked to authenticate using the devices passcode or TouchID Get all of the attributes by adding `--json keychain.json` to this command Reading the iOS keychain... Class Account Service Generic Data ------------------------ ------------- -------------------------- --------- ---------------------------------- kSecClassGenericPassword ATTRIBUTE_KEY myapp-KEYCHAIN-SERVICE-NAME UUID kSecClassGenericPassword myapp-APP-UUID myapp-KEYCHAIN-SERVICE-NAME 017F435248791246F0B29F8A3A5C93917E
这是一个 provisioning profile 集成到 App 中的. 假如机器上没有这个 profile,iOS 会在安装 App 的时候把它也安装上去.
这个 Profile 其实就是一个 plist file, 记录了一系列的 permission. 假如无法安装, 可以查看UDID 是否绑定在该provisioning file 中.
以下 command 会显示 mobileprovision 绑定那个 UDID.
security cms -D -i /path/to/appName.mobileprovision