Skip to content

Add technique for non-jailbroken iOS dynamic analysis (#3724)#3731

Draft
Galaxy-sc wants to merge 5 commits intoOWASP:masterfrom
Galaxy-sc:feature/3724-ios-non-jb-dynamic-analysis
Draft

Add technique for non-jailbroken iOS dynamic analysis (#3724)#3731
Galaxy-sc wants to merge 5 commits intoOWASP:masterfrom
Galaxy-sc:feature/3724-ios-non-jb-dynamic-analysis

Conversation

@Galaxy-sc
Copy link

Description

Adds a technique for dynamic analysis on non-jailbroken iOS devices. This follows the discussion in the issue and documents the decryption and sideloading approach used in practice.

Linted locally with markdownlint-cli2.


AI Tool Disclosure

  • This contribution does not include AI-generated content.
  • This contribution includes AI-generated content.

Contributor Checklist

  • I have read and understood the contributing guidelines.
  • I followed the project style guide.
  • I validated the technical correctness of my changes.
  • This PR adds clear value and is not spam or low-effort content.

Closes #3724

@github-actions
Copy link

Thank you for your contribution! However, you are not assigned to any of the linked issues:

To contribute to this project, please:

  1. Request to be assigned to the issue you want to work on
  2. Wait for a maintainer to assign you
  3. Reopen this PR once you are assigned

This helps us coordinate contributions and avoid duplicate work.

@github-actions github-actions bot closed this Feb 24, 2026
@cpholguera cpholguera reopened this Feb 25, 2026
Copy link
Collaborator

@cpholguera cpholguera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @Galaxy-sc, please take a look at the suggestions.


Follow @MASTG-TECH-0054 to obtain the IPA file for the app you want to test and ensure you obtain a **non-encrypted version before proceeding** (you'll need a jailbroken device).

### Overcoming Decryption Constraints (Version Mismatch)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This content seems like it belongs in MASTG-TECH-0054. This technique, 0146 is an overview/summary wrapper so to say.

In addition to that:

  • you mentioned that you got this "workaround" from an online article. Please always include the sources, in this case as an inline markdown link []().
  • we also require links to other things like the Apple Configurator (this could even be added as a new MASTG-TOOL.
  • Is AppSync Unified the only way of installing the app? Do we have this as a MASTG-TOOL? We have a MASTG-TECH for installing apps, please refer to it using @MASTG-TECH-XXXX and in case it doesn't use AppSync Unified yet, you can add it as a subsection.
  • frida-ios-dump has a MASTG ID, Please use it with @ as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Moved the workaround to MASTG-TECH-0054, added the source link, and referenced AppSync Unified via @MASTG-TOOL-0127


Follow @MASTG-TECH-0056 to install the signed IPA on your device. Note that because you've modified the IPA, the Bundle Identifier may have changed depending on the signing tool you used.

### Modern Sideloading for Persistence
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, this seems to belong in MASTG-TECH-0056. Also, the 2 tools mentioned should be added as MASTG tools if not already there (and referenced with @ from MASTG-TECH-0056).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Moved this section to MASTG-TECH-0056 and created the new tool files for SideStore (@MASTG-TOOL-0150) and TrollStore (@MASTG-TOOL-0151).


Follow @MASTG-TECH-0055 to launch the repackaged app in debug mode. Launching via SpringBoard will cause it to crash; you must use the debug launch method so the Frida Gadget can start and wait for your connection.

## Automated Dynamic Analysis with MobSF
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to belong here. Or are you suggesting that the app cannot be launched following the current instructions in MASTG-TECH-0055?

Since this is information specific to MobSF, in the MASTG-TOOL for it, you could add a short sentence with an inline link to MobSF's documentation where this is explained. In general, for tools we try to link to their docs instead of duplicating info that's already there. We do this to lower maintenance effort in the MASTG side.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Removed this section entirely to keep 0146 purely as a wrapper. I moved the usbmuxd Docker snippet directly to the MobSF tool file and referenced @MASTG-TOOL-0069.

…ol files

- Modularize MASTG-TECH-0146 to act purely as a wrapper
- Move MinimumOSVersion workaround to MASTG-TECH-0054
- Move persistence/sideloading to MASTG-TECH-0056
- Add new tool files for SideStore and TrollStore
- Move MobSF Docker workaround to MobSF tool file
- Add correct cross-references for AppSync and usbmuxd
@Galaxy-sc
Copy link
Author

Hi @cpholguera, thanks for the detailed review! I agree that keeping the architecture modular makes sense here. I've applied all your suggestions: I moved the workarounds and sideloading methods to their appropriate tech files (0054 and 0056), created the new tool files, and stripped 0146 down to a pure wrapper by moving the MobSF Docker/USB snippet to its specific tool file, where it belongs for analyzing repackaged apps.

@cpholguera
Copy link
Collaborator

Great, thank you @Galaxy-sc!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands the MASTG documentation to better support dynamic analysis workflows on non-jailbroken iOS devices, adding supporting tool references and updating related techniques/tool pages so v2 tests can reference a practical black-box setup.

Changes:

  • Add new iOS tool reference pages for SideStore and TrollStore.
  • Extend the MobSF tool page with guidance for using Docker with a physical iOS device via usbmuxd.
  • Update iOS techniques with modern iOS caveats, persistence-oriented sideloading options, and a decryption/version-mismatch workaround.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tools/ios/MASTG-TOOL-0150.md New tool page for SideStore to support longer-running sideloading workflows.
tools/ios/MASTG-TOOL-0151.md New tool page for TrollStore as an alternative persistence option on affected iOS versions.
tools/generic/MASTG-TOOL-0035.md Adds guidance for using MobSF (Docker) with physical non-jailbroken iOS devices via usbmuxd.
techniques/ios/MASTG-TECH-0146.md Adds troubleshooting notes for modern iOS (Lockdown Mode / PAC) in the non-jailbroken dynamic analysis technique.
techniques/ios/MASTG-TECH-0056.md Adds a “Modern Sideloading for Persistence” section referencing the new tools.
techniques/ios/MASTG-TECH-0054.md Adds a version-mismatch workaround to obtain decrypted binaries when iOS requirements exceed the jailbreak device OS.

source: https://sidestore.io/
---

SideStore is an iOS sideloading app that allows you to sign and install apps using your Apple ID, bypassing the 7-day limit by refreshing them on-device via a local WireGuard VPN.
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use consistent prose formatting for numbers (the style guide spells out zero through ten). Consider changing "7-day limit" to "seven-day limit" here to match the rest of the iOS sideloading guidance.

Suggested change
SideStore is an iOS sideloading app that allows you to sign and install apps using your Apple ID, bypassing the 7-day limit by refreshing them on-device via a local WireGuard VPN.
SideStore is an iOS sideloading app that allows you to sign and install apps using your Apple ID, bypassing the seven-day limit by refreshing them on-device via a local WireGuard VPN.

Copilot uses AI. Check for mistakes.
source: https://github.com/opa334/TrollStore
---

TrollStore is a permasigned jailed app that can permanently install any IPA you open in it, exploiting the CoreTrust bug on specific iOS versions to bypass the standard seven-day expiration.
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"permasigned" is informal jargon and may be unclear for readers. Consider using a more explicit term like "permanently signed" (or briefly defining what "perma-signed" means in this context).

Suggested change
TrollStore is a permasigned jailed app that can permanently install any IPA you open in it, exploiting the CoreTrust bug on specific iOS versions to bypass the standard seven-day expiration.
TrollStore is a permanently signed jailed app that can permanently install any IPA you open in it, exploiting the CoreTrust bug on specific iOS versions to bypass the standard seven-day expiration.

Copilot uses AI. Check for mistakes.
@@ -26,3 +26,11 @@ run.bat # For Windows
```

Once you have MobSF up and running you can open it in your browser by navigating to <http://127.0.0.1:8000>. Simply drag the APK you want to analyze into the upload area and MobSF will start its job.
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tool page now mentions uploading a repackaged IPA for iOS, but the earlier instruction still says to drag an APK into the upload area. Consider generalizing that sentence to "APK or IPA" (or otherwise clarifying Android vs iOS) so the workflow reads consistently.

Suggested change
Once you have MobSF up and running you can open it in your browser by navigating to <http://127.0.0.1:8000>. Simply drag the APK you want to analyze into the upload area and MobSF will start its job.
Once you have MobSF up and running you can open it in your browser by navigating to <http://127.0.0.1:8000>. Simply drag the APK or IPA you want to analyze into the upload area and MobSF will start its job.

Copilot uses AI. Check for mistakes.
@Galaxy-sc
Copy link
Author

Applied Copilot's style and grammar suggestions.

@cpholguera
Copy link
Collaborator

Great, thank you! Next time, please incorporate any suggestions using the GitHub UI's buttons for "Add suggestion to batch" and then "Commit suggestions" this help us keep track of Copilot's (or other reviewer's) commits and also auto resolves the conversations which saves us a lot of time especially when there are a lot of them (not the case here but still helpful). Again, not an issue but just FYI for next time 🙏

docker run -it --rm -p 8000:8000 -v /var/run/usbmuxd:/var/run/usbmuxd opensecurity/mobile-security-framework-mobsf:latest
```

Once the container has USB access, upload your repackaged IPA to the MobSF web interface.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this line and the above: how about APK and Android physical devices?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! I’ve updated the section to clarify Android physical device support via --device /dev/bus/usb, generalized the final step to include APKs, and aligned the wording to virtual jailbroken or rooted devices.

Galaxy-sc and others added 2 commits February 27, 2026 03:02
@TheDauntless
Copy link
Collaborator

@Galaxy-sc can you give some examples of packages on which you applied this technique? I've tried it a few times already but was not able to do so. Mostly due to entitlement limitations (eg entitlements that don't exist on older ios versions) or app extensions.

@sushi2k
Copy link
Collaborator

sushi2k commented Mar 2, 2026

I am also stuck now. I have a

  • Jailbroken iOS 15.8.3 (palera1n)
  • Non-jailbroken iOS 17

Both phones have the same Apple ID so they have the same decryption keys for FairPlay available.

I downloaded 2 apps via the App Store on the non-jailbroken phone (that can't be installed on my jailbroken one as it's too old), followed the guide and could install them on the jailbroken phone by changing the Info.plist.

Both apps won't start on the jailbroken phone, I can only click the icon but nothing happens. I can see only this in in the Xcode console logs:

[com.PACKAGE.NAME - signature state: Unknown, reason: Error - -402620415: reason: An unknown error has occurred.
Attempted to launch an untrusted application scene sceneID:com.PACKAGE.NAME-default
Transition request <SBMainWorkspaceTransitionRequest: 0x281820f30; eventLabel: SBUIApplicationIconLaunchEventLabel; display: Main; source: HomeScreen> was declined: Failed preflight

I don't know if this is the expected behaviour. I installed one of them again via Sideloadly and now the app starts and crashes.

My problem is now that I can't find a tool that would allow the dumping of the IPA. Iridium and Flexdecrypt are not available as arm-64 binary and can't get them compiled in the latest Xcode.

How do you try to dump the decrypted IPA from the jailbroken device?

$ ssh -p 2222 root@127.0.0.1
(root@127.0.0.1) Password for root@Svens-JB-device:
Svens-JB-device:~ root# cd /var/mobile/Downloads
Svens-JB-device:/var/mobile/Downloads root# dpkg -i wiki.qaq.iridium.rel.ci.1642832736.deb
dpkg: error processing archive wiki.qaq.iridium.rel.ci.1642832736.deb (--install):
 package architecture (iphoneos-arm) does not match system (iphoneos-arm64)
Errors were encountered while processing:
 wiki.qaq.iridium.rel.ci.1642832736.deb
Svens-JB-device:/var/mobile/Downloads root# dpkg -i flexdecrypt.deb
dpkg: error processing archive flexdecrypt.deb (--install):
 package architecture (iphoneos-arm) does not match system (iphoneos-arm64)
Errors were encountered while processing:
 flexdecrypt.deb
image

@cpholguera cpholguera marked this pull request as draft March 6, 2026 17:16
@sushi2k
Copy link
Collaborator

sushi2k commented Mar 7, 2026

I tried it on an even older jailbroken device, with iOS 12.4 and unc0ver and used a recent version of a well known app. I can install the App on the jailbroken device, but I can't install iridium on it:

Svens-iPhone:/var/mobile/Downloads root# dpkg -i wiki.qaq.iridium.rel.ci.1642832736.deb
Selecting previously unselected package wiki.qaq.iridium.
dpkg: regarding wiki.qaq.iridium.rel.ci.1642832736.deb containing wiki.qaq.iridium, pre-dependency problem:
 wiki.qaq.iridium pre-depends on firmware (>= 13.5)
  firmware is installed, but is version 12.4.

dpkg: error processing archive wiki.qaq.iridium.rel.ci.1642832736.deb (--install):
 pre-dependency problem - not installing wiki.qaq.iridium
Errors were encountered while processing:
 wiki.qaq.iridium.rel.ci.1642832736.deb

I could install flexcrypt and used flexdump, but flexdump was only crashing with Abort trap: 6. It seems flexcrypt has issues with iOS 12 and/or unc0ver:

Svens-iPhone:~ root# ./flexdump.sh dump TESTING-APP.app
  _____ _              _
 |  ___| | _____  ____| |_   _ _ __ ___  _ __
 | |_  | |/ _ \ \/ / _` | | | | '_ ` _ \| '_ \
 |  _| | |  __/>  < (_| | |_| | | | | | | |_) |
 |_|   |_|\___/_/\_\__,_|\__,_|_| |_| |_| .__/
                                        |_|

                                 by @defparam

[+] Searching for TESTING-APP.app...
[+] Found app at: /private/var/containers/Bundle/Application/D81E2900-5F2A-49D7-B0D2-8625AECC9C0D/TESTING-APP.app
[+] App name: TESTING-APP
[+] App version: 0.0.0
[+] Preparing working directory at: /tmp/tmp.wAZY0nga07/Payload
[+] Copying application to: /tmp/tmp.wAZY0nga07/Payload/TESTING-APP.app , please wait...
[+] Decrypting and signing binaries...
[+] Decrypting: ./TESTING-APP.app/PlugIns/NotificationServiceExtension.appex/NotificationServiceExtension
./flexdump.sh: line 89: 19310 Abort trap: 6           flexdecrypt2 "$j" &> /dev/null
mv: cannot stat '/tmp/NotificationServiceExtension': No such file or directory
[+] Self-signing: ./TESTING-APP.app/PlugIns/NotificationServiceExtension.appex/NotificationServiceExtension
[+] Decrypting: ./TESTING-APP.app/PlugIns/TESTING-APPSearchSafariExtension.appex/TESTING-APPSearchSafariExtension
./flexdump.sh: line 89: 19324 Abort trap: 6           flexdecrypt2 "$j" &> /dev/null
...
[+] Decrypting: ./TESTING-APP.app/Frameworks/ScreenRecording_4DF1B615F876FB0C_PackageProduct.framework/ScreenRecording_4DF1B615F876FB0C_PackageProduct
./flexdump.sh: line 89: 19482 Abort trap: 6           flexdecrypt2 "$j" &> /dev/null
mv: cannot stat '/tmp/ScreenRecording_4DF1B615F876FB0C_PackageProduct': No such file or directory
[+] Self-signing: ./TESTING-APP.app/Frameworks/ScreenRecording_4DF1B615F876FB0C_PackageProduct.framework/ScreenRecording_4DF1B615F876FB0C_PackageProduct
[+] Packaging final IPA file...
[+] Generated: /var/root/dump/TESTING-APP_0.0.0_fd.ipa
[+] Done!

When I unzip the created IPA from flexdump it's still encrypted:

Svens-iPhone:~/dump/Payload/TESTING-APP.app root# otool -l TESTING-APP | grep cryptid
      cryptid 1

When trying to use flexdecrypt on the binary I get this error:

# flexdecrypt file TESTING-APP
Error: mremap_encryptedFailed(segment: "__TEXT", error: "#12: Cannot allocate memory")

@Galaxy-sc can you please share your test setup and what worked for you:

  • iOS version
  • jailbreak type and version
  • Phone model
  • decryption tools you used
  • apps that worked for you and which ones didn't and why

This seems to me like a very fragile setup and might only word in very specific use cases, and this we need to point out and document properly. So far I couldn't replicate it on 2 jailbroken devices.

Copy link
Collaborator

@sushi2k sushi2k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please. clarify this comment. @Galaxy-sc

1. Extract the FairPlay-encrypted IPA via [Apple Configurator](https://support.apple.com/apple-configurator).
2. Unzip the archive and modify the `MinimumOSVersion` key within the `Info.plist` file to match the older jailbroken device's iOS version.
3. Repackage and force-install the app. Please refer to @MASTG-TECH-0056 for standard app installation methods. If standard methods fail due to the version mismatch, using a tweak like @MASTG-TOOL-0127 is a common workaround.
4. The app will probably crash right away due to missing modern APIs. However, the decrypted Mach-O binary is usually already loaded in memory. You can dump it during this early initialization stage using standard tools like @MASTG-TOOL-0050 (`frida-ios-dump`). Once you have the decrypted payload, just transfer it to your modern non-jailbroken device for patching.
Copy link
Collaborator

@sushi2k sushi2k Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I installed an app that needs > iOS 17 on a jailbroken iOS 15.8.3 device (with palera1n) by changing the min iOS version in the Info.plist. The app is installed, it crashes when it starts.

But if the app crashes, frida-ios-dump is not able to dump the app binary from memory. At least for me it wasn't working. My understanding is that the app/process need to run, ideally in the foreground. Please let me know if this would work otherwise. I tried to start the app multiple times, it crashes and then a time out comes.

$ ./dump.py TARGET_TEST -u mobile -P alpine
Start the target app TARGET_TEST
unexpectedly timed out while waiting for app to launch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add new v2 Technique for iOS dynamic analysis on non-jailbroken devices

5 participants