Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatic setup of on-device dependencies for iOS #74

Merged
merged 4 commits into from
Jun 7, 2023
Merged

Conversation

zner0L
Copy link
Contributor

@zner0L zner0L commented May 15, 2023

This automatically installs missing dependencies on a jailbroken iOS device via apt.

@zner0L zner0L requested a review from baltpeter May 15, 2023 14:16
@zner0L zner0L marked this pull request as draft May 15, 2023 14:16
@zner0L zner0L marked this pull request as ready for review June 1, 2023 16:11
Copy link
Member

@baltpeter baltpeter left a comment

Choose a reason for hiding this comment

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

Haven't tested this yet but a few comments from reading the code.

src/ios.ts Outdated Show resolved Hide resolved
@@ -178,6 +213,8 @@ export const iosApi = <RunTarget extends SupportedRunTarget<'ios'>>(
} catch (err) {
throw new Error('Cannot connect using SSH.', { cause: err });
}

await this._internal.setupEnvironment();
Copy link
Member

Choose a reason for hiding this comment

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

You still have to update the README. As this only happens when the ssh capability is enabled and considering #59 (comment), I guess you could just add a "These are installed automatically if…" note to the list of packages for now.

Copy link
Member

Choose a reason for hiding this comment

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

But we should consider what we want to ultimate design of this to be. If we do implement this iproxy thing, an ssh capability doesn't really make sense anymore as that will just always be available if jailbroken. So maybe we should rename that to root then?

And then we should mention in the docstrings that frida requires (or implies, even?) root (similarly, on Android we should mention that wireguard requires root).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does fridadepend on root, though? One could install frida-server on the device and use it without any need to access the terminal.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Otherwise I think you are right. Do you want me to do this in this PR, or open an issue for it?

Copy link
Member

Choose a reason for hiding this comment

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

Does fridadepend on root, though? One could install frida-server on the device and use it without any need to access the terminal.

I don't understand what you're saying. Unless you compile frida-server into an app, you can only use it on a jailbroken device, so it does require root?

Copy link
Member

Choose a reason for hiding this comment

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

Otherwise I think you are right. Do you want me to do this in this PR, or open an issue for it?

Issue is fine for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't understand what you're saying. Unless you compile frida-server into an app, you can only use it on a jailbroken device, so it does require root?

Yes, but you don’t need to necessarily give appstraction root access, if you installed it yourself.

Copy link
Member

Choose a reason for hiding this comment

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

Hm, I guess you could view it that way.

src/ios.ts Outdated Show resolved Hide resolved
@baltpeter
Copy link
Member

I tried resetting an rejailbreaking one of my iPhones to test this but failed. As such, I'm really not too keen on also resetting the other phone. I need at least one jailbroken device…

I really don't know how I can test this.

src/index.ts Outdated Show resolved Hide resolved
@@ -178,6 +213,8 @@ export const iosApi = <RunTarget extends SupportedRunTarget<'ios'>>(
} catch (err) {
throw new Error('Cannot connect using SSH.', { cause: err });
}

await this._internal.setupEnvironment();
Copy link
Member

Choose a reason for hiding this comment

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

Hm, I guess you could view it that way.

@baltpeter
Copy link
Member

Trying the example script on this branch on a freshly reset and jailbroken iOS 15 iPhone (with a password for root set), I get the following error:

/home/benni/coding/JS/tweasel/appstraction/src/ios.ts:197
                if (!(await retryCondition(fridaIsRunning, 20))) throw new Error('Frida server did not start.');
                                                                       ^


Error: Frida server did not start.
    at Object.ensureFrida (/home/benni/coding/JS/tweasel/appstraction/src/ios.ts:197:72)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at Object.ensureDevice (/home/benni/coding/JS/tweasel/appstraction/src/ios.ts:236:13)
    at <anonymous> (/home/benni/coding/JS/tweasel/appstraction/examples/ios-device.ts:22:5)

src/index.ts Show resolved Hide resolved
@baltpeter
Copy link
Member

The problem is that I don't have an /etc/apt directory that you could write the sources to:

Vanessas-iPhone:~ root# ls -l /etc
lrwxr-xr-x 1 root wheel 11 Aug 11  2022 /etc -> private/etc/
Vanessas-iPhone:~ root# ls /private/etc 
asl/  asl.conf  group  hosts  hosts.equiv  master.passwd  networks  notify.conf  passwd  ppp/  protocols  racoon/  services  ttys

As such, only the packages that don't need extra repositories installed. And since we're not checking anything for errors, the rest just silently failed.

@baltpeter
Copy link
Member

If I understand https://cdn.nickchan.lol/palera1n/c-rewrite/releases/v2.0.0-beta.7/palera1n.1.html correctly, palera1n-c installs in rootless mode by default (I just ran palera1n, without any arguments). I'm guess that's the problem?

But all the other files we depend on do appear to be there:

Vanessas-iPhone:~ root# ls /Library/LaunchDaemons 
com.apple.factory.NFQRCoded.plist
Vanessas-iPhone:~ root# ls /private/var/mobile/Library/TCC/TCC.db
/private/var/mobile/Library/TCC/TCC.db
Vanessas-iPhone:~ root# ls /private/var/protected/trustd/private/TrustStore.sqlite3
/private/var/protected/trustd/private/TrustStore.sqlite3

@baltpeter
Copy link
Member

So, where are the sources saved?

Vanessas-iPhone:~ root# grep -r "apt.procurs.us" / 2>/dev/null
/private/preboot/88DCF80B58E42648095610A0AF68DA1FCCCD3DEC60C0E2440FE0CFD6E4B47BD03B96B3EDDB340CB3517674A9059D3429/jb-0N5TRzIB/procursus/etc/apt/sources.list.d/procursus.sources:URIs: https://apt.procurs.us/
/private/preboot/88DCF80B58E42648095610A0AF68DA1FCCCD3DEC60C0E2440FE0CFD6E4B47BD03B96B3EDDB340CB3517674A9059D3429/jb-0N5TRzIB/procursus/var/mobile/Library/Caches/Sileo/RepoHashCache.json:{"sha512":{"https:\/\/apt.procurs.us\/dists\/1800\/Packages.zst":"716ec7a16de7cd9ebd9d5c3936e16cf8902a4fd0f0e2fc5efdc75bc82db4d330bd9ee474e034f227d13736acd9cd8509ab23fb94d749b9 […long]
/private/var/mobile/Library/Caches/org.coolstar.SileoStore/fsCachedData/3D1F8351-0668-411C-9D23-22FBD58EC88B:{"status":"200 OK","date":"2 [very, very, long…]
/private/var/mobile/Library/palera1n/logs/1686050641.916493-loader.log:Get:2 https://apt.procurs.us 1800 InRelease [8310 B]
/private/var/mobile/Library/palera1n/logs/1686050641.916493-loader.log:Get:5 https://apt.procurs.us 1800/main iphoneos-arm64 Packages [308 kB]
/private/var/mobile/Library/palera1n/logs/1686050641.916493-loader.log:Get:1 https://apt.procurs.us 1800/main iphoneos-arm64 libkrw0-tfp0 iphoneos-arm64 1.1.1 [3862 B]
/private/var/mobile/Library/palera1n/logs/1686050641.916493-loader.log:Get:1 https://apt.procurs.us 1800/main iphoneos-arm64 nebula-keyring all 2022.09.15 [3608 B]

The first one is the only one that makes sense. But it's in a procursus directory. Did I just happen to pick the one source with the same name as the thing that holds these files or does every source have its own… whatever?

I added a dummy source:

Vanessas-iPhone:~ root# grep -r "test.bn.al" / 2>/dev/null
/private/preboot/88DCF80B58E42648095610A0AF68DA1FCCCD3DEC60C0E2440FE0CFD6E4B47BD03B96B3EDDB340CB3517674A9059D3429/jb-0N5TRzIB/procursus/etc/apt/sources.list.d/sileo.sources:URIs: https://test.bn.al/
/private/var/tmp/488DC191-B899-470F-A7C6-62CA3503FE70:URIs: https://test.bn.al/

Vanessas-iPhone:~ root# cat /private/preboot/88DCF80B58E42648095610A0AF68DA1FCCCD3DEC60C0E2440FE0CFD6E4B47BD03B96B3EDDB340CB3517674A9059D3429/jb-0N5TRzIB/procursus/etc/apt/sources.list.d/sileo.sources
Types: deb
URIs: https://havoc.app/
Suites: ./
Components:

Types: deb
URIs: https://repo.chariz.com/
Suites: ./
Components:

Types: deb
URIs: https://test.bn.al/
Suites: ./
Components:

Okay, /private/preboot/88DCF80B58E42648095610A0AF68DA1FCCCD3DEC60C0E2440FE0CFD6E4B47BD03B96B3EDDB340CB3517674A9059D3429/jb-0N5TRzIB/procursus/etc/apt it is.

@baltpeter
Copy link
Member

If I hardcode this path, the source is added and shows up in Sileo, but I still get Frida server did not start.

@baltpeter
Copy link
Member

But Frida was installed:

Vanessas-iPhone:~ root# apt list | grep frida 

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

re.frida.server/unknown 16.0.19 iphoneos-arm

@baltpeter
Copy link
Member

Hm, I can't find the re.frida.server.plist you're trying to modify:

Vanessas-iPhone:~ root# cat /Library/LaunchDaemons/re.frida.server.plist
cat: /Library/LaunchDaemons/re.frida.server.plist: No such file or directory
Vanessas-iPhone:~ root# ls /Library/LaunchDaemons 
com.apple.factory.NFQRCoded.plist
Vanessas-iPhone:~ root# ls /private/preboot/88DCF80B58E42648095610A0AF68DA1FCCCD3DEC60C0E2440FE0CFD6E4B47BD03B96B3EDDB340CB3517674A9059D3429/jb-0N5TRzIB/procursus/Library/LaunchDaemons/
com.apple.atrun.plist  com.openssh.sshd.plist  us.diatr.shshd.plist
Vanessas-iPhone:~ root# find / -name "re.frida.server.plist" 2>/dev/null

@baltpeter
Copy link
Member

I'm assuming you installed in rootful mode? Maybe we should just make that a requirement and document it in the README?

@zner0L
Copy link
Contributor Author

zner0L commented Jun 6, 2023

Yes. I use rootful mode, which I think we should require.

@baltpeter
Copy link
Member

Please document your steps for jailbreaking. I'm really not sure which of the options I would use for that.

@zner0L
Copy link
Contributor Author

zner0L commented Jun 6, 2023

Please document your steps for jailbreaking. I'm really not sure which of the options I would use for that.

tweaselORG/meta#4 (comment)

@baltpeter
Copy link
Member

With rootful mode, this now works on my iOS 15 device. Unfortunately, SSL Kill Switch 2 doesn't seem to be enabled after the automatic setup. The menu item doesn't show up in the Settings app. Iirc, you need to respring for that to start working. I tried launchctl reboot userspace but that didn't help.

@baltpeter
Copy link
Member

Huh. Even after respringing, the setting still doesn't show up. Maybe the version of SKS2 you're installing doesn't have that? Have you verified whether it works? I can't think of a good app to test right now.

@baltpeter
Copy link
Member

Other than that, it did work. I was able to run the the example successfully (well, the app I tested crashed on the first try, causing the script to fail—but it did work on second try…).

@zner0L
Copy link
Contributor Author

zner0L commented Jun 7, 2023

Ok, I tested it and I can confirm that SSL Kill Switch 2 is activated. However I forgot to include PreferenceLoader as a dependency for it to show up in the Preferences. This needs more than a respring, you need to go into the palera1n app and tap "Enable Tweaks". I haven’t figured out what that does, yet.

@baltpeter
Copy link
Member

Ok, I tested it and I can confirm that SSL Kill Switch 2 is activated.

For future reference: How?

@baltpeter
Copy link
Member

Respringing unfortunately leaves the device locked. In the current state, the example now fails with Error: Cannot connect using Frida. while it is still respringing.

@baltpeter
Copy link
Member

Is the problem only the preference or does the pinning bypass also not work currently? I don't care too much about the former.

@zner0L
Copy link
Contributor Author

zner0L commented Jun 7, 2023

For future reference: How?

SSL Kill Switch writes to the syslog: === SSL Kill Switch 2: Preference set to 1.. Also, the App Store relies on certificate pinning and crashes if mitmproxy is used as a proxy, even with the CA set up. But it does work if SSL Kill Switch 2 has been installed, even without respring.

Respringing unfortunately leaves the device locked. In the current state, the example now fails with Error: Cannot connect using Frida. while it is still respringing.

This is probably because the SpringBoard has not fully started up again. I guess we should waitForDevice there, but this is not available in the scope of respring… Also, for future reference, there is a way to unlock the screen: https://stackoverflow.com/questions/21706050/how-to-unlock-ios-screen-programmatically

Is the problem only the preference or does the pinning bypass also not work currently? I don't care too much about the former.

The pinning bypass also seems to work without PreferenceLoader and without respring. So I guess if you want to marge you could undo the last changes I made.

@baltpeter
Copy link
Member

So I guess if you want to marge you could undo the last changes I made.

Okay, will do.

@baltpeter
Copy link
Member

baltpeter commented Jun 7, 2023

I was able to run the the example successfully (well, the app I tested crashed on the first try, causing the script to fail—but it did work on second try…).

Tested again on a fresh install and ran into the same problem, regardless of which app I tested. Even manually starting the installed apps afterwards, they would always crash.

I found that I have to start the apps once without the proxy enabled. Afterwards, they also work with the proxy, even after uninstalling and reinstalling them.

This seems like it might be a cert pinning issue with Apple verifying that I do in fact own the app? I don't remember running into this before.

@baltpeter
Copy link
Member

Interestingly, it now also works with a different app without needing to start it once without a proxy. So maybe, the condition is in fact that I need to start any App Store app once without proxy? Either way, that doesn't seem so severe anymore and doesn't seem to be caused by this PR, so I'll push this into an issue and merge.

@baltpeter baltpeter merged commit 791f9d2 into main Jun 7, 2023
@baltpeter baltpeter deleted the z_ios-setup branch June 7, 2023 21:49
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.

Start frida-server on iOS in ensureDevice() Automatically setup iOS devices
2 participants