Skip to content

[Feature] Read Keychain of specific App (Any App RemoteCall) #309

Description

@DYY-Studio

Is your feature request related to a problem?

I thought that the mechanism of DarkSword is fully capable of achieving RemoteCall for any App, but the pipeline is not yet mature and there are many detailed issues.

Through vibe coding, I performed extensive testing and explored a basically stable pipeline for executing RemoteCall on any App under Arm64e, using a physical iPhone SE (3rd Gen) running iOS 17.7.2. During this process, I also discovered some issues with the current pipeline.

I am opening this issue because I do not have a deep understanding of the hardware mechanisms, cannot properly explain my findings and make sure they are right; additionally, the highly experimental pipeline and messy code produced from vibe coding are not suitable for submitting a PR.

Keychain Read is what I consider a relatively interesting application of this approach, and it is universally applicable to most Apps. I've tested that this is fully possible.

Image

Here shows the Keychain Read Experiment Results. Target: BOOK WALKER (Japan Store)

This experiment only fetch the description of the returned dictionary

You can see the whole experiment route in this branch, although the branch name is wrong and the code is really messy, also included some unneeded functions such as dynamic offset resolve and multi-thread inject:
https://github.com/DYY-Studio/lara/tree/leaf-vm-scan

Some points are listed in Addtional context.

Hope this helpful.

Describe the solution you'd like:

New Tweak Keychain Read

  • Provide an App List for users to choose from
  • Execute RemoteCall on the target App to read Keychain
    • Remotely check if Security.framework is available (via dlsym, dlopen, or dyld_image scanning)
    • (remote dlsym SecItemCopyMatching and then use it to query)
    • For available Apps, execute SecItemCopyMatching to list all entries under the five classes
    • Allow selecting specific entries to read, or directly fetch the values together with kSecReturnData when executing SecItemCopyMatching

Describe alternatives you've considered:

NONE

Scope:

  • UI / UX change
  • New exploit capability or device support
  • Tweak / package management
  • Persistence or boot behavior
  • Logging, diagnostics, or error handling
  • Build system / CI
  • Documentation
  • Other

Additional context:

In my experimental vibe-coded pipeline, I found that for any arbitrary App, the following points generally need attention:

  • Preparation Timing and Thread Selection
    • Threads in a typical App are mostly inactive for long periods, especially when in the background.
    • In my testing, injectguardexc can be successfully performed on inactive threads. We can first inject into the inactive main thread, and then switch to the target App using the method in App Decrypt, which will inevitably trigger first-landing.
    • It is feasible to perform an initial injection on the main thread and then complete the creation process of an auxiliary dedicated thread within the main thread, or directly use the main thread to execute simple tasks.
    • On iPhone, the execution flow seemingly should be fully completed while the App is in the foreground.
    • In a typical App, main thread activity is predictable and triggerable, so I believe it should be chosen over other threads to complete the initialization.
    • launch App if not running -> switch to lara? -> injectguardexc on Main Thread -> switch to the App -> first_landing -> create helper thread and so on -> finish jobs -> clearguardexc and other cleanning, pthread_exit -> switch to lara
  • PAC Signing Strategy for PC / LR
    • The current pipeline signs PC and LR on Arm64e.
    • However, in my testing, I found that both PC and LR are bare pointers without PAC during takeover.
      • At this time, the thread has __DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH flag.
      • If the contents placed into PC and LR are signed with PAC at this moment, it instead triggers a CODESIGNING 2 error, resulting in a SIGKILL.
  • Trap Exception Triggering
    • The FAKE_LR 0x401 / 0x201 in the current strategy triggers CODESIGNING 2 (SIGKILL) on typical Apps.
    • Through experimentation, I found that the following two approaches are feasible:
      1. Misalign
        • Offset a pointer of a function from the dyld_shared_cache (such as getpid) by 0x2 or 0x6.
        • This operation triggers EXC_BAD_ACCESS (SIGBUS), which can be reliably triggered regardless of whether PAC is valid.
        • This aligns with the current EXC_BAD_ACCESS handling strategy and does not kill the process.
      2. ObjCTrapBRK
        • For apps with an ObjC runtime, use objc_exception_throw to raise a BRK.
        • However, this direction does not align with the current strategy and is only mentioned in passing.

Maybe more but I cannot remember.

Are you willing to help implement this?

  • Yes, I can submit a PR
  • I can help test
  • I'm just suggesting the idea

I really want to submit a PR but I'm not so familiar with Swift and Objective-C...

Pre-submission checklist:

  • I have searched existing issues (open and closed) and confirmed this feature has not already been requested
  • This request is relevant to the latest version / commit of Lara
  • I have provided sufficient detail (problem, proposed solution, scope) for a maintainer to evaluate
  • I agree to communicate respectfully with the developers and understand that harassment may result in restricted support

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions