Skip to content

Instantly share code, notes, and snippets.

@ay-kay
Last active October 21, 2015 15:19
Show Gist options
  • Save ay-kay/6fb67b586f36c799568b to your computer and use it in GitHub Desktop.
Save ay-kay/6fb67b586f36c799568b to your computer and use it in GitHub Desktop.
YiSpecter targeting non-jailbroken devices

In @PaloAltoNtwks recent report on YiSpecter it is said that "NoIcon (..) is the main malicious component of YiSpecter". In order to being able to invoke the private MobileInstallation API, NoIcon claims the required private entitlement key com.apple.private.mobileinstall.allowedSPI. This can be seen from the provided samples.

Entitlements of the app bundle:

$ codesign -d --entitlements :- "Payload/NoIcon.app/"
Executable=./Trojan_iPhoneOS_YiSpecter_samples/Payload/NoIcon.app/NoIcon
<?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>VN36KFTLTA.com.weiying.hiddenIconLaunch</string>
	<key>com.apple.developer.team-identifier</key>
	<string>VN36KFTLTA</string>
	
	<key>com.apple.private.mobileinstall.allowedSPI</key>
	<array>
		<string>Install</string>
		<string>Browse</string>
		<string>Uninstall</string>
		<string>Archive</string>
		<string>RemoveArchive</string>
	</array>
	<key>com.apple.springboard.launchapplications</key>
	<true/>
	<key>get-task-allow</key>
	<false/>
	<key>keychain-access-groups</key>
	<array>
		<string>com.weiying.noicon</string>
	</array>
	
</dict>
</plist>

However, from the very first moment I was wondering how NoIcon should have received an enterprise provisioning profile from Apple that actually allows to utilize these entitlements. As a rule, Apple does not issue such profiles claiming private entitlements. In fact, as seen below, the entitlements of the app's embedded enterprise provisioning profile do, as expected, not match the entitlements of the app's binary. In recent iOS versions this causes installd's verification procedures to fail and, consequently, mobile_installation_proxy to refuse installation of such an app on non-jailbroken devices.

Entitlements of the app's embedded provisioning profile (mismatch!):

$ unzip -p NoIcon.ipa Payload/NoIcon.app/embedded.mobileprovision | security cms -D 
<?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>AppIDName</key>
	<string>hiddenIconLaunch</string>
	<key>ApplicationIdentifierPrefix</key>
	<array>
	<string>VN36KFTLTA</string>
	</array>
	<key>CreationDate</key>
	<date>2015-03-24T03:50:52Z</date>
	<key>DeveloperCertificates</key>

	[..]

	<key>Entitlements</key>    <--- missing the private MobileInstallation entitlement
	<dict>
		<key>keychain-access-groups</key>
		<array>
			<string>VN36KFTLTA.*</string>
		</array>
		<key>get-task-allow</key>
		<false/>
		<key>application-identifier</key>
		<string>VN36KFTLTA.com.weiying.hiddenIconLaunch</string>
		<key>com.apple.developer.team-identifier</key>
		<string>VN36KFTLTA</string>
	</dict>

	<key>ExpirationDate</key>
	<date>2016-03-23T03:50:52Z</date>
	<key>Name</key>
	<string>NoIcon</string>
	<key>ProvisionsAllDevices</key>
	<true/>
	<key>TeamIdentifier</key>
	<array>
		<string>VN36KFTLTA</string>
	</array>
	<key>TeamName</key>
	<string>Beijing Yingmob Interaction Technology co, .ltd</string>
	<key>TimeToLive</key>
	<integer>365</integer>
	<key>UUID</key>
	<string>7e5ca063-865c-4834-b062-c32218a0600a</string>
	<key>Version</key>
	<integer>1</integer>
</dict>
</plist>

Still feels like something I'm missing?

Anyone aware of a bug in previous iOS versions that allowed to bypass profile verification?

Otherwise, YiSpecter's "main malicious component" would have been able to run on jailbroken devies only...

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