├── .gitignore ├── LICENSE.txt ├── README.md ├── bin └── iiv ├── lib ├── boot.sh ├── build.sh ├── common.sh ├── devices │ ├── iPhone3,1.sh │ ├── iPhone3,2.sh │ ├── iPhone3,3.sh │ └── iPod4,1.sh ├── download.sh ├── spec.sh └── verify.sh ├── script └── bootstrap ├── share ├── TOB_Blue.png └── mtree_exclude └── vendor ├── iphone-dataprotection ├── CREDITS.txt ├── README.txt ├── build_ramdisk.sh ├── img3fs │ ├── Makefile │ ├── README │ └── img3fs.c ├── mtree ├── mtree_exclude ├── python_scripts │ ├── README.txt │ ├── backup_tool.py │ ├── backups │ │ ├── __init__.py │ │ ├── backup3.py │ │ └── backup4.py │ ├── crypto │ │ ├── PBKDF2.py │ │ ├── __init__.py │ │ ├── aes.py │ │ ├── aeswrap.py │ │ ├── curve25519.py │ │ └── gcm.py │ ├── demo_backup_keychain.py │ ├── demo_bruteforce.py │ ├── demo_escrow.py │ ├── emf_decrypter.py │ ├── emf_undelete.py │ ├── firmware │ │ ├── __init__.py │ │ ├── img2.py │ │ ├── img3.py │ │ └── scfg.py │ ├── hfs │ │ ├── __init__.py │ │ ├── btree.py │ │ ├── emf.py │ │ ├── hfs.py │ │ ├── journal.py │ │ └── structs.py │ ├── ios_examiner.py │ ├── kernel_patcher.py │ ├── keychain │ │ ├── __init__.py │ │ ├── keychain.py │ │ ├── keychain3.py │ │ ├── keychain4.py │ │ ├── managedconfiguration.py │ │ └── store.py │ ├── keychain_tool.py │ ├── keystore │ │ ├── __init__.py │ │ ├── effaceable.py │ │ └── keybag.py │ ├── nand │ │ ├── __init__.py │ │ ├── carver.py │ │ ├── image.py │ │ ├── legacyftl.py │ │ ├── nand.py │ │ ├── partition_tables.py │ │ ├── remote.py │ │ ├── structs.py │ │ ├── vfl.py │ │ ├── vsvfl.py │ │ └── yaftl.py │ ├── usbmux │ │ ├── __init__.py │ │ └── usbmux.py │ ├── util │ │ ├── __init__.py │ │ ├── asciitables.py │ │ ├── bdev.py │ │ ├── bplist.py │ │ ├── bruteforce.py │ │ ├── cert.py │ │ ├── lzss.py │ │ ├── ramdiskclient.py │ │ └── tlv.py │ ├── windows_redsn0w_keys.py │ └── wordlist.dict ├── ramdisk_tools │ ├── .DS_Store │ ├── AppleEffaceableStorage.c │ ├── AppleEffaceableStorage.h │ ├── AppleKeyStore.c │ ├── AppleKeyStore.h │ ├── AppleKeyStore_kdf.c │ ├── IOAESAccelerator.c │ ├── IOAESAccelerator.h │ ├── IOKit │ ├── IOKit.c │ ├── IOKit.h │ ├── IOUSBDeviceControllerLib.h │ ├── Makefile │ ├── bsdcrypto │ │ ├── key_wrap.c │ │ ├── key_wrap.h │ │ ├── pbkdf2.c │ │ ├── pbkdf2.h │ │ ├── rijndael.c │ │ ├── rijndael.h │ │ ├── sha1.c │ │ └── sha1.h │ ├── device_info.c │ ├── device_info.h │ ├── device_infos.c │ ├── dump_data_partition.sh │ ├── image.c │ ├── image.h │ ├── ioflash │ │ ├── ioflash.c │ │ ├── ioflash.h │ │ ├── ioflash_kernel.c │ │ └── ioflashstoragekit.c │ ├── kernel_patcher.c │ ├── keystore_device.xml │ ├── plist_server.c │ ├── plist_server.h │ ├── registry.c │ ├── registry.h │ ├── remote_functions.c │ ├── remote_functions.h │ ├── restored_external.c │ ├── scripts │ │ └── mount_partitions.sh │ ├── shsh_dump.c │ ├── systemkb_bruteforce.c │ ├── tfp0.plist │ ├── util.c │ └── util.h ├── tcprelay.sh └── usbmuxd-python-client │ ├── tcprelay.py │ └── usbmux.py └── vfdecrypt ├── Makefile ├── README └── vfdecrypt.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | coverage 6 | InstalledFiles 7 | lib/bundler/man 8 | pkg 9 | rdoc 10 | spec/reports 11 | test/tmp 12 | test/version_tmp 13 | tmp 14 | 15 | # YARD artifacts 16 | .yardoc 17 | _yardoc 18 | doc/ 19 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Trail of Bits, Inc. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iOS Integrity Validator 2 | 3 | iOS Integrity Validator is an integrity validator for iOS devices capable of reliably detecting 4 | modifications such as malware and jailbreaks, without the use of signatures. It 5 | runs at boot-time to thoroughly inspect the device, identifying any changes and 6 | collecting relevant artifacts of these changes for offline analysis. This will 7 | let you know if the device has simply been jailbroken or if it has been 8 | modified in a much sneakier way. 9 | 10 | ## Usage 11 | 12 | To setup iOS Integrity Validator: 13 | 14 | git clone https://github.com/trailofbits/ios-integrity-validator.git ios-integrity-validator 15 | cd ios-integrity-validator 16 | script/bootstrap 17 | 18 | Then, plug your phone into your computer, put it in [DFU 19 | mode](http://theiphonewiki.com/wiki/DFU_Mode), and run 20 | 21 | bin/iiv DEVICE VERSION 22 | 23 | If you're not comfortable putting the phone in DFU mode by yourself, run 24 | iOS Integrity Validator with the phone connected normally, and you will be walked through the 25 | process. 26 | 27 | ## Supported Devices 28 | 29 | This open-source release of iOS Integrity Validator comes with slightly limited device support, 30 | since it relies on freely available tools like [redsn0w](http://www.redsn0w.us) 31 | and [iphone-dataprotection](http://code.google.com/p/iphone-dataprotection/). 32 | 33 | * iPhone3,1 (5.0 - 6.1.3) 34 | * iPhone3,2 (6.0 - 6.1.3) 35 | * iPhone3,3 (5.0 - 6.1.3) 36 | * iPod4,1 (5.0 - 6.1.3) 37 | 38 | ## Technical Overview 39 | 40 | iOS Integrity Validator uses redsn0w to boot a custom kernel and ramdisk generated by 41 | iphone-dataprotection. It then uses `mtree` to check the type, user ID, group 42 | ID, mode, and SHA-1 digest of every file on the root filesystem against a 43 | specification generated from the firmware image itself. If any files have 44 | changed, or if any files have been added, the files are copied off the device 45 | for further inspection and analysis by the user. 46 | 47 | ## Note 48 | This project was initially called iVerify when it was released in 2013. 49 | 50 | ## Contact 51 | 52 | If you have not jailbroken your phone on purpose and iOS Integrity Validator finds evidence of 53 | modifications, send us an [e-mail](mailto:opensource@trailofbits.com) with your 54 | evidence file and we will take a look. 55 | -------------------------------------------------------------------------------- /bin/iiv: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | source 'lib/common.sh' 4 | source 'lib/build.sh' 5 | source 'lib/boot.sh' 6 | source 'lib/verify.sh' 7 | source 'lib/download.sh' 8 | source 'lib/spec.sh' 9 | 10 | if (( $# != 2 )) 11 | then 12 | err 'Invalid arguments' 13 | cat </dev/null 2>&1 & 25 | local redsn0w_pid=$! 26 | 27 | log 'Forwarding SSH ports' 28 | python usbmuxd-python-client/tcprelay.py \ 29 | -t 22:2222 1999:1999 \ 30 | >/dev/null 2>&1 & 31 | export USBMUX=$! 32 | 33 | log 'Waiting for device' 34 | while { ! (device uname -a >/dev/null 2>&1) } 35 | do 36 | sleep 2 37 | done 38 | 39 | log 'Booted!' 40 | kill $redsn0w_pid 41 | popd 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /lib/build.sh: -------------------------------------------------------------------------------- 1 | source 'lib/common.sh' 2 | 3 | # Build a kernel and ramdisk for a given iOS version. 4 | # 5 | # Arguments: 6 | # 7 | # 1 - version of iOS for which to build 8 | # 9 | # Environment: 10 | # 11 | # IPSW - path to iOS firmware, relative to project root 12 | # 13 | # Exports: 14 | # 15 | # IPSW - path to iOS firmware, relative to iphone-dataprotection 16 | # RAMDISKNAME - path to extracted ramdisk 17 | # KEY - key to decrypt ramdisk 18 | # IV - IV to decrypt ramdisk 19 | # CUSTOMRAMDISK - path to write custom ramdisk 20 | # OUTKERNEL - path to patched kernel 21 | # 22 | function build_ramdisk { 23 | local version=$1 24 | if (( ! ${+IPSW_URLS[$version]} )) 25 | then 26 | err "No available firmware for '$version'" 27 | exit 28 | fi 29 | 30 | pushd 'vendor/iphone-dataprotection' 31 | log 'make img3fs' 32 | check make -C img3fs/ 33 | 34 | log 'Patching kernel' 35 | typeset -a args 36 | args=($(python python_scripts/kernel_patcher.py "../../${IPSW}")) 37 | 38 | export IPSW=${args[1]} 39 | export RAMDISKNAME=${args[2]} 40 | export KEY=${args[3]} 41 | export IV=${args[4]} 42 | export CUSTOMRAMDISK=${args[5]} 43 | export OUTKERNEL=${args[6]} 44 | 45 | log 'Building ramdisk_tools' 46 | check make -C ramdisk_tools 47 | 48 | log 'Building ramdisk' 49 | check ./build_ramdisk.sh ${IPSW} ${RAMDISKNAME} ${KEY} ${IV} ${CUSTOMRAMDISK} 50 | 51 | popd 52 | } 53 | 54 | -------------------------------------------------------------------------------- /lib/common.sh: -------------------------------------------------------------------------------- 1 | # Print line to terminal. 2 | # Includes a colored prefix to differentiate iiv output from other output. 3 | # 4 | # Arguments: 5 | # 6 | # 1... - Arguments to print 7 | # 8 | function log { 9 | print "\x1b[34m==> \x1b[37m$*\x1b[0m" 10 | } 11 | 12 | # Print an error to terminal. 13 | # Includes a colored prefix to differentiate iiv output from other output. 14 | # 15 | # Arguments: 16 | # 17 | # 1... - Arguments to print 18 | # 19 | function err { 20 | print "\x1b[31;4mError\x1b[0m: $*" 21 | } 22 | 23 | # Print a warning to terminal. 24 | # Includes a colored prefix to differentiate iiv output from other output. 25 | # 26 | # Arguments: 27 | # 28 | # 1... - Arguments to print 29 | # 30 | function warn { 31 | print "\x1b[31;4mWarning\x1b[0m: $*" 32 | } 33 | 34 | # Run a command, recording the output in a log file, and exit if the command 35 | # fails. If the command succeeds, the log is deleted. If it fails, the log is 36 | # printed, an error is printed, and the program terminates. 37 | # 38 | # Arguments: 39 | # 40 | # 1... - Command to run 41 | # 42 | # Examples: 43 | # 44 | # check make install 45 | # 46 | function check { 47 | local logdir="$HOME/Library/Logs/com.trailofbits.iiv" 48 | mkdir -p $logdir 49 | 50 | local timestamp 51 | timestamp=$(date '+%F-%H%M%S') 52 | local log_path="${logdir}/$(basename $1)-${timestamp}.log" 53 | 54 | $* >$log_path 2>&1 55 | 56 | if (( $? )) 57 | then 58 | err $* 59 | cat $log_path 60 | log 'Error log saved to' $log_path 61 | exit 62 | else 63 | rm $log_path 64 | fi 65 | } 66 | 67 | # Run a command on the connected iOS device. 68 | # 69 | # Arguments: 70 | # 71 | # 1... - Command to run 72 | # 73 | # Examples: 74 | # 75 | # device /sbin/halt 76 | # 77 | function device { 78 | ssh -p 2222 -oStrictHostKeyChecking=no root@localhost $* 79 | } 80 | 81 | # mtree keywords are used in multiple places, so we define them here. 82 | MTREE_KEYWORDS='uid,gid,mode,sha1digest' 83 | 84 | -------------------------------------------------------------------------------- /lib/devices/iPhone3,1.sh: -------------------------------------------------------------------------------- 1 | typeset -A IPSW_URLS 2 | IPSW_URLS=( 3 | '5.0' 'http://appldnld.apple.com/iPhone4/041-8358.20111012.FFc34/iPhone3,1_5.0_9A334_Restore.ipsw' 4 | '5.0.1' 'http://appldnld.apple.com/iPhone4/041-3309.20111109.64rtg/iPhone3,1_5.0.1_9A405_Restore.ipsw' 5 | '5.1' 'http://appldnld.apple.com/iOS5/041-1537.20120307.EJrm4/iPhone3,1_5.1_9B176_Restore.ipsw' 6 | '5.1.1' 'http://appldnld.apple.com/iOS5.1.1/041-6051.2012.0525.Cvby7/iPhone3,1_5.1.1_9B208_Restore.ipsw' 7 | '6.0' 'http://appldnld.apple.com/iOS6/Restore/041-7175.20120919.wvv7Y/iPhone3,1_6.0_10A403_Restore.ipsw' 8 | '6.0.1' 'http://appldnld.apple.com/iOS6/041-7950.20121101.Lmr45/iPhone3,1_6.0.1_10A523_Restore.ipsw' 9 | '6.1' 'http://appldnld.apple.com/iOS6.1/091-0682.20130128.mefc4/iPhone3,1_6.1_10B144_Restore.ipsw' 10 | '6.1.2' 'http://appldnld.apple.com/iOS6.1/091-0722.20130215.BzrgV/iPhone3,1_6.1.2_10B146_Restore.ipsw' 11 | '6.1.3' 'http://appldnld.apple.com/iOS6.1/091-2610.20130319.Bedr4/iPhone3,1_6.1.3_10B329_Restore.ipsw' 12 | ) 13 | 14 | typeset -A IPSW_SHA1 15 | IPSW_SHA1=( 16 | '5.0' 'aacd559fee6652685c89de74b89a62de27ce938f' 17 | '5.0.1' 'a123b049c7a03cc952c6328de998d4f74d49c18b' 18 | '5.1' '1454b106551053804f3ac39fff4c17454cb6ae90' 19 | '5.1.1' '1209f57051f675d0328c08a894b073589f9eeb20' 20 | '6.0' '4553077c61fd9c487c906ee419d2159f807a00fb' 21 | '6.0.1' '3d123107c71588fef6f03bd1fc8ca42bda400621' 22 | '6.1' '2dcaae314ae8e0a353ad43010159cf15f7f6bd4e' 23 | '6.1.2' 'b62c043338898893c210bb81e608b4b099de7c5f' 24 | '6.1.3' 'f8c53328656f2708e1d2bcb793f12ae46dd4eb23' 25 | ) 26 | 27 | typeset -A IPSW_ROOT 28 | IPSW_ROOT=( 29 | '5.0' '018-7879-364.dmg' 30 | '5.0.1' '038-3700-001.dmg' 31 | '5.1' '038-1768-165.dmg' 32 | '5.1.1' '038-5508-003.dmg' 33 | '6.0' '038-6494-001.dmg' 34 | '6.0.1' '038-7954-010.dmg' 35 | '6.1' '048-0820-001.dmg' 36 | '6.1.2' '048-0903-002.dmg' 37 | '6.1.3' '048-2748-005.dmg' 38 | ) 39 | 40 | typeset -A IPSW_KEYS 41 | IPSW_KEYS=( 42 | '5.0' '5e5c52fd7e439936d89659b5aa4f79206cd64f09c9961e9d4712a0131075966e2271b354' 43 | '5.0.1' 'a8c7fe8c4698684db2b315cdf9b0c569e6769ed721b83799bad4dadfaf6186c6fd6e0fb1' 44 | '5.1' 'b51d75f7ba8c51397ccd5dbcf8929b14419bfc5e4b21b0370f73d2c9f9e1067b03336989' 45 | '5.1.1' 'd5811298fa4bb88e0bb15c7d16abe69ee74666bd263db16b59eb64b98872de0f9438a56b' 46 | '6.0' 'ca9ed452f256fa47ccdb387fdc0daa53d19428b2569fb089af58df576f6e54a4fb6de0ae' 47 | '6.0.1' '43fd5c7357cfc1bfa0c16ab72343bcb9e8974922b3c00af7a27cf522d2dca3ec471a6f83' 48 | '6.1' '751775f5f345c9632fcc52876c63cffffd5b05b28b402986e3e0898c2fb8c58051bfd575' 49 | '6.1.2' '01c1fb58265e6a22ebe784edf55cc549d4f7f73d5a5769eb7365d1145b3f9e0798b8851a' 50 | '6.1.3' 'c676166434b79cbde341e094000dfc47b3161034371b25a9054880a757d73aead553a317' 51 | ) 52 | 53 | 54 | -------------------------------------------------------------------------------- /lib/devices/iPhone3,2.sh: -------------------------------------------------------------------------------- 1 | typeset -A IPSW_URLS 2 | IPSW_URLS=( 3 | '6.0' 'http://appldnld.apple.com/iOS6/Restore/041-7177.20120919.xqoqs/iPhone3,2_6.0_10A403_Restore.ipsw' 4 | '6.0.1' 'http://appldnld.apple.com/iOS6/041-7951.20121101.GetM4/iPhone3,2_6.0.1_10A523_Restore.ipsw' 5 | '6.1' 'http://appldnld.apple.com/iOS6.1/091-0692.20130128.R3lr4/iPhone3,2_6.1_10B144_Restore.ipsw' 6 | '6.1.2' 'http://appldnld.apple.com/iOS6.1/091-0739.20130215.F654R/iPhone3,2_6.1.2_10B146_Restore.ipsw' 7 | '6.1.3' 'http://appldnld.apple.com/iOS6.1/091-2444.20130319.exFqm/iPhone3,2_6.1.3_10B329_Restore.ipsw' 8 | ) 9 | 10 | typeset -A IPSW_SHA1 11 | IPSW_SHA1=( 12 | '6.0' '4aefb7146df559d29c77f65c29c663a29cf43514' 13 | '6.0.1' 'f311dd43f23f4ab33a4ede6075034f740a9dfd3f' 14 | '6.1' 'f3086f7aca0750e843819c84fe2acc3c1f325b7c' 15 | '6.1.2' '054a21fb789d05055f11b99f3d0acf19c344d9be' 16 | '6.1.3' '5eb08bf9a952943fd23515fdcb9f7590e284b6a2' 17 | ) 18 | 19 | typeset -A IPSW_ROOT 20 | IPSW_ROOT=( 21 | '6.0' '038-6497-001.dmg' 22 | '6.0.1' '038-7956-010.dmg' 23 | '6.1' '048-0801-001.dmg' 24 | '6.1.2' '048-0872-002.dmg' 25 | '6.1.3' '048-2727-005.dmg' 26 | ) 27 | 28 | typeset -A IPSW_KEYS 29 | IPSW_KEYS=( 30 | '6.0' '6055317e3c3f6021c8e0b9e1daa26ec387d2e798c9ee8cf0ec3150665b049ef6d4c10e67' 31 | '6.0.1' 'f5705c4d5d7ce7972ab915e62cac8096e254c3bf3635d7d205eab868d447959135d06c7a' 32 | '6.1' 'd408ec0ee309f3e574e85e71765b71f49a5830bebf5e5b45b28d8804461200e1bb20902f' 33 | '6.1.2' 'ff85a46a289544a28bce5391961b7017a5a80dcc6cee8a0f0bd240be10cd19872877108e' 34 | '6.1.3' '7e2dbf591820349a41df18e39e18b351422e2ca424f3cba61709d7384545f5d8dd7674de' 35 | ) 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /lib/devices/iPhone3,3.sh: -------------------------------------------------------------------------------- 1 | typeset -A IPSW_URLS 2 | IPSW_URLS=( 3 | '5.0' 'http://appldnld.apple.com/iPhone4/041-9743.20111012.vjhfp/iPhone3,3_5.0_9A334_Restore.ipsw' 4 | '5.0.1' 'http://appldnld.apple.com/iPhone4/041-3304.20111109.Vgtyh/iPhone3,3_5.0.1_9A405_Restore.ipsw' 5 | '5.1' 'http://appldnld.apple.com/iOS5/041-1529.20120307.looTW/iPhone3,3_5.1_9B176_Restore.ipsw' 6 | '5.1.1' 'http://appldnld.apple.com/iOS5.1.1/041-4291.20120427.Zs8F0/iPhone3,3_5.1.1_9B206_Restore.ipsw' 7 | '6.0' 'http://appldnld.apple.com/iOS6/Restore/041-7179.20120919.bDw4g/iPhone3,3_6.0_10A403_Restore.ipsw' 8 | '6.0.1' 'http://appldnld.apple.com/iOS6/041-7952.20121101.aClm5/iPhone3,3_6.0.1_10A523_Restore.ipsw' 9 | '6.1' 'http://appldnld.apple.com/iOS6.1/041-6505.20130128.Cpt63/iPhone3,3_6.1_10B141_Restore.ipsw' 10 | '6.1.2' 'http://appldnld.apple.com/iOS6.1/091-0726.20130215.Npal4/iPhone3,3_6.1.2_10B146_Restore.ipsw' 11 | '6.1.3' 'http://appldnld.apple.com/iOS6.1/091-2351.20130319.Fe431/iPhone3,3_6.1.3_10B329_Restore.ipsw' 12 | ) 13 | 14 | typeset -A IPSW_SHA1 15 | IPSW_SHA1=( 16 | '5.0' '3258689a46c7ebd03b621531ee0511a88ae4a9e3' 17 | '5.0.1' '81afa9d2079a7153e5d27e30f1f08e7c53074591' 18 | '5.1' '9c3b42bac8e61323646ca8daf2abe862bd4be4ce' 19 | '5.1.1' '70b736f826335ccefbc9941c3bb5d3b211236461' 20 | '6.0' '82c8774281d97cde005da969ac50827ff4fab173' 21 | '6.0.1' '3084e9bbc9c6fedefc52f098590d57dbcc6da97e' 22 | '6.1' '18c3b2fda21a12729976ecbb44344686ef27442b' 23 | '6.1.2' '8e975c8028daf68ed2fe8e6af3d5e065486b013c' 24 | '6.1.3' '42f09fdc2e35426cc402ee683efb3b5e62dfe46a' 25 | ) 26 | 27 | typeset -A IPSW_ROOT 28 | IPSW_ROOT=( 29 | '5.0' '018-9768-361.dmg' 30 | '5.0.1' '038-3704-001.dmg' 31 | '5.1' '038-1774-166.dmg' 32 | '5.1.1' '038-4297-008.dmg' 33 | '6.0' '038-6500-001.dmg' 34 | '6.0.1' '038-7958-010.dmg' 35 | '6.1' '038-5830-122.dmg' 36 | '6.1.2' '048-0883-002.dmg' 37 | '6.1.3' '048-2443-005.dmg' 38 | ) 39 | 40 | typeset -A IPSW_KEYS 41 | IPSW_KEYS=( 42 | '5.0' 'cbb21346634c5754f3e956f09ca7c93542b87286d7b11de71f18c5d72da529746ab27094' 43 | '5.0.1' '36895be7d36aa1415695ec3cd7d33ccf9b088bfc179d48f4d8fc5fd220a2c6f07c9b76d2' 44 | '5.1' 'e1025ad63ff73af6fa941dc85ce449ad67a471bc0cf51c9c5c3507736f2430f6c91dba84' 45 | '5.1.1' '2e3166688336a53fbc0ca014ff2fa458007d44048646764604bde3b73c88dac625c49d18' 46 | '6.0' 'e2f187cced00643b2129df66f2d22a6bc0c58235ca3cf85d95d7593382c3178737cf7113' 47 | '6.0.1' '1076b3547842e1822a10eaa22723c0ef9145f823899be7f876d5bde1f853f4fb496ab606' 48 | '6.1' '47609f7d1fda9002160be1ea48a75c0497eab5c31051d221fc520974a4804b5fbe1103ff' 49 | '6.1.2' 'f620b7ac829004a7cdf68ffd10008e751878f18331655dbd6b7e08587d0655507cd9319e' 50 | '6.1.3' '3ad3f6163e6d6307f7149ae980df922725718f32f28554d8969cbdb92349e3c79de9b623' 51 | ) 52 | -------------------------------------------------------------------------------- /lib/devices/iPod4,1.sh: -------------------------------------------------------------------------------- 1 | typeset -A IPSW_URLS 2 | IPSW_URLS=( 3 | '5.0' 'http://appldnld.apple.com/iPhone4/061-9622.20111012.Evry3/iPod4,1_5.0_9A334_Restore.ipsw' 4 | '5.0.1' 'http://appldnld.apple.com/iPhone4/041-3313.20111109.Azxe3/iPod4,1_5.0.1_9A405_Restore.ipsw' 5 | '5.1' 'http://appldnld.apple.com/iOS5/041-1542.20120307.Jyknq/iPod4,1_5.1_9B176_Restore.ipsw' 6 | '5.1.1' 'http://appldnld.apple.com/iOS5.1.1/041-4298.20120427.Tzr8w/iPod4,1_5.1.1_9B206_Restore.ipsw' 7 | '6.0' 'http://appldnld.apple.com/iOS6/Restore/041-0807.20120919.soT6X/iPod4,1_6.0_10A403_Restore.ipsw' 8 | '6.0.1' 'http://appldnld.apple.com/iOS6/041-7439.20121101.rgt54/iPod4,1_6.0.1_10A523_Restore.ipsw' 9 | '6.1' 'http://appldnld.apple.com/iOS6.1/091-0688.20130128.omwy3/iPod4,1_6.1_10B144_Restore.ipsw' 10 | '6.1.2' 'http://appldnld.apple.com/iOS6.1/091-0732.20130215.Mkmt5/iPod4,1_6.1.2_10B146_Restore.ipsw' 11 | '6.1.3' 'http://appldnld.apple.com/iOS6.1/091-2655.20130319.Wyt54/iPod4,1_6.1.3_10B329_Restore.ipsw' 12 | ) 13 | 14 | typeset -A IPSW_SHA1 15 | IPSW_SHA1=( 16 | '5.0' '668b3784966d829ec6007d10e38fa117d6799cf1' 17 | '5.0.1' 'ec4feac81de53459701e4baabb6b4534be3260ca' 18 | '5.1' '65d7ee2d2fa505ce6fe91271f84f3fc9cbcc81a1' 19 | '5.1.1' '5facf346ad939e9f11854b05237fddc1ed59e2e3' 20 | '6.0' '7cc754118a4a8113a67635b14abee0b247936ce8' 21 | '6.0.1' 'dd1824e1cd77eea1d210094ab58b1bf15f980af1' 22 | '6.1' '8bc0f54ef70cab0573b635fc56764397116d4d1b' 23 | '6.1.2' '2fc5141896a0723b9723b36a98037fa17698ad5c' 24 | '6.1.3' 'c9c8efb5663b8ab5faece095cefd03aa7d499f5e' 25 | ) 26 | 27 | typeset -A IPSW_ROOT 28 | IPSW_ROOT=( 29 | '5.0' '038-2707-006.dmg' 30 | '5.0.1' '038-3698-001.dmg' 31 | '5.1' '038-1765-165.dmg' 32 | '5.1.1' '038-4290-006.dmg' 33 | '6.0' '038-1142-304.dmg' 34 | '6.0.1' '038-7009-012.dmg' 35 | '6.1' '048-0819-001.dmg' 36 | '6.1.2' '048-0904-002.dmg' 37 | '6.1.3' '048-2642-005.dmg' 38 | ) 39 | 40 | typeset -A IPSW_KEYS 41 | IPSW_KEYS=( 42 | '5.0' '575bcb4f9290a28bc00451f7e444973fd8b0afc529d2d84db4ae227bdd779563f070eaea' 43 | '5.0.1' '7ed37d8c051da8f8d31b0ccf0980fa5ffa54770c7e68ecb5ebf28abe683cadf21a4a99ed' 44 | '5.1' '1ab3765d93aaf106b918829db85c18e724473e51106ad89f3d10e863cc3864974c2852f5' 45 | '5.1.1' 'f21b4cc1ae39ed3b36d33374f77e224b9e77f375f8722c551acdc7033ef16383c0b99b39' 46 | '6.0' '4ca4fb440f88acfd8333efa0b171b02bc76942d448a71922da6a4502e63d8f28bc9d958f' 47 | '6.0.1' '82465a9f8328fdb0a4ef2b3fb19bb8934cb96e773d10d7e2b4ab29a5df482870c6737f7a' 48 | '6.1' '9d4aa60414c4656ef3ecded3315e8717f0c6f308f19bc34e7a8d3fcb8787f7ea58ac2f1a' 49 | '6.1.2' '67aeecbad72fb61ae972895abaf4e903df26cfd6950e089e63fdac21715e078d3f8dac3e' 50 | '6.1.3' '625003a349494ed7fc1972d30f7cf840f8bbff11b2d493593017d0606d88605b7fad5e61' 51 | ) 52 | 53 | -------------------------------------------------------------------------------- /lib/download.sh: -------------------------------------------------------------------------------- 1 | source 'lib/common.sh' 2 | CACHE="${HOME}/Library/Caches/com.trailofbits.iiv" 3 | 4 | # Download an IPSW from Apple, or load it from ~/Library/Caches. 5 | # 6 | # Arguments: 7 | # 8 | # 1 - the version of iOS to download 9 | # 10 | # Exports: 11 | # 12 | # IPSW - path to downloaded firmware relative to the current directory 13 | # 14 | # Examples: 15 | # 16 | # source 'lib/versions/ipod4g.sh' 17 | # download '5.1.1' 18 | # 19 | # Note that you must load a version file first, as shown in the example! 20 | # 21 | function download_ipsw { 22 | local url=${IPSW_URLS[$1]} 23 | local package="${CACHE}/$(basename ${url})" 24 | local dest='ipsw' 25 | mkdir -p $dest 26 | 27 | if [[ -f $package && 28 | ${IPSW_SHA1[$1]} == $(sha $package) ]] 29 | then 30 | log 'Using cached' $package 31 | else 32 | log 'Downloading' $package 33 | curl --progress-bar --location --output ${package} ${url} 34 | fi 35 | 36 | export IPSW="${dest}/$(basename ${package})" 37 | cp ${package} "${IPSW}" 38 | } 39 | 40 | # Download redsn0w and install it to vendor/, install Keys.plist into 41 | # vendor/iphone-dataprotection. 42 | # This function also caches to ~/Library/Caches. 43 | # 44 | # Exports: 45 | # 46 | # REDSN0W - path to redsn0w installation 47 | # 48 | function download_redsn0w { 49 | local url='https://sites.google.com/a/iphone-dev.com/files/home/redsn0w_mac_0.9.15b3.zip' 50 | local package="${CACHE}/$(basename ${url})" 51 | local basename 52 | basename=$(basename -s '.zip' ${package}) 53 | 54 | if [[ -f ${package} && 55 | 'd32a6dd5a2a5ff7c7f05bebaba24992abe291e08' == $(sha ${package}) ]] 56 | then 57 | log 'Using cached' $package 58 | else 59 | log 'Downloading' ${package} 60 | curl --progress-bar --location --output ${package} ${url} 61 | fi 62 | 63 | export REDSN0W=$basename 64 | check unzip -o ${package} -d 'vendor' 65 | check cp "vendor/${basename}/redsn0w.app/Contents/MacOS/Keys.plist" 'vendor/iphone-dataprotection' 66 | } 67 | 68 | # Return the sha1 hash of a file. 69 | # 70 | # Arguments: 71 | # 72 | # $1 - the file to hash 73 | # 74 | function sha { 75 | shasum $1 | awk '{print $1}' 76 | } 77 | 78 | -------------------------------------------------------------------------------- /lib/spec.sh: -------------------------------------------------------------------------------- 1 | source 'lib/common.sh' 2 | 3 | # Generate an mtree specification for a given iOS firmware version. 4 | # Specification is saved to specs/.spec. 5 | # 6 | # Arguments: 7 | # 8 | # 1 - the firmware version to build a specification for 9 | # 10 | # Environment: 11 | # 12 | # IPSW - path to downloaded iOS firmware, relative to project root 13 | # 14 | function spec { 15 | local version=$1 16 | 17 | mkdir -p 'specs' 18 | local dest="specs/${version}.spec" 19 | if [[ -f $dest ]] 20 | then 21 | log $dest 'exists, remove to regenerate' 22 | return 23 | fi 24 | 25 | log 'Building vfdecrypt' 26 | check make -C 'vendor/vfdecrypt' mac 27 | 28 | log 'Extracting root filesystem' 29 | check unzip -jo ${IPSW} ${IPSW_ROOT[$version]} -d 'ipsw/' 30 | 31 | log 'Decrypting root filesystem' 32 | check vendor/vfdecrypt/vfdecrypt \ 33 | -i "ipsw/${IPSW_ROOT[$version]}" \ 34 | -k ${IPSW_KEYS[$version]} \ 35 | -o "decrypted.dmg" 36 | 37 | log 'Mounting' 38 | local mount_point 39 | mount_point=$(hdiutil attach "decrypted.dmg" | awk '/Volumes/ { print $3 }') 40 | log "Mounted to $mount_point" 41 | 42 | log 'Generating mtree spec (need root)' 43 | sudo mtree -c \ 44 | -k $MTREE_KEYWORDS \ 45 | -p $mount_point \ 46 | -X share/mtree_exclude \ 47 | >"specs/${version}.spec" 48 | 49 | log 'Ejecting' 50 | check hdiutil eject $mount_point 51 | 52 | log 'Cleaning up' 53 | rm "decrypted.dmg" 54 | rm "ipsw/${IPSW_ROOT[$version]}" 55 | } 56 | -------------------------------------------------------------------------------- /lib/verify.sh: -------------------------------------------------------------------------------- 1 | source 'lib/common.sh' 2 | 3 | # Verify the filesystem of a connected and booted iOS device. 4 | # 5 | # Arguments: 6 | # 7 | # 1 - the version of iOS to verify 8 | # 9 | # Envrionment: 10 | # 11 | # USBMUX - PID of usbmux tcprelay, to be killed at program termination 12 | # 13 | function verify { 14 | local version=$1 15 | 16 | log 'Mounting filesystem' 17 | local mountpoint='/mnt1' 18 | device mount_hfs -o ro /dev/disk0s1s1 $mountpoint 19 | 20 | log 'Verifying filesystem' 21 | local spec="specs/${version}.spec" 22 | local output 23 | output=$(device /usr/local/bin/mtree \ 24 | -k $MTREE_KEYWORDS \ 25 | -X /etc/mtree_exclude \ 26 | -p /mnt1 \ 27 | <${spec}) 28 | 29 | if (( $? == 2 )) 30 | then 31 | warn 'Device filesystem has been modified' 32 | elif (( $? == 1 )) 33 | then 34 | err 'Error running mtree' 35 | halt 36 | fi 37 | 38 | local evidence="evidence/$(date '+%F-%H%M%S')" 39 | log 'Copying added/modified files to' $evidence 40 | for changed in $(echo $output | awk '/\S+ (changed|extra)$/ { print $1 }') 41 | do 42 | local dest="$evidence/$(dirname $changed)" 43 | mkdir -p $dest 44 | scp -pr -P 2222 root@localhost:"$mountpoint/$changed" $dest 45 | done 46 | 47 | halt 48 | } 49 | 50 | function halt { 51 | log 'Shutting down device' 52 | device /sbin/halt 53 | kill $USBMUX 54 | exit 55 | } 56 | 57 | -------------------------------------------------------------------------------- /script/bootstrap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | set -e 3 | 4 | source 'lib/common.sh' 5 | 6 | OSXFUSE_URL='http://downloads.sourceforge.net/project/osxfuse/osxfuse-2.6.0/osxfuse-2.6.0.dmg' 7 | OSXFUSE_DEST='/tmp/osxfuse.dmg' 8 | OSXFUSE_VOLUME='/Volumes/FUSE for OS X/' 9 | OSXFUSE_PKG=$OSXFUSE_VOLUME'Install OSXFUSE 2.6.pkg' 10 | DEVELOPER_ROOT=`xcode-select --print-path` 11 | CODESIGN_PATH=$DEVELOPER_ROOT'/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate' 12 | 13 | typeset -a BREW_PACKAGES 14 | BREW_PACKAGES=(python swig) 15 | typeset -a PIP_PACKAGES 16 | PIP_PACKAGES=(M2crypto construct progressbar setuptools pycrypto) 17 | 18 | if [[ -d '/Developer' ]] 19 | then 20 | log 'Skipping linking /Developer' 21 | else 22 | log 'Linking /Developer' 23 | sudo ln -sf $DEVELOPER_ROOT // 24 | fi 25 | 26 | log 'Linking codesign_allocate' 27 | sudo ln -sf $CODESIGN_PATH /usr/bin 28 | 29 | if [[ -d '/Library/Frameworks/OSXFUSE.framework' ]] 30 | then 31 | log 'OSXFUSE installed' 32 | else 33 | log 'Downloading' $OSXFUSE_URL 34 | curl -# -o $OSXFUSE_DEST -L $OSXFUSE_URL 35 | log 'Installing OSXFuse' 36 | hdiutil mount $OSXFUSE_DEST 37 | sudo installer -pkg "$OSXFUSE_PKG" -target / 38 | hdiutil eject "$OSXFUSE_VOLUME" 39 | fi 40 | 41 | log 'Installing' ${BREW_PACKAGES[@]} 42 | brew install ${BREW_PACKAGES[@]} 43 | log 'Installing' ${PIP_PACKAGES[@]} 44 | ARCHFLAGS='-arch i386 -arch x86_64' pip install -q ${PIP_PACKAGES[@]} 45 | 46 | -------------------------------------------------------------------------------- /share/TOB_Blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/ios-integrity-validator/2090e6321cd313493c6f3746866411d865cde6ab/share/TOB_Blue.png -------------------------------------------------------------------------------- /share/mtree_exclude: -------------------------------------------------------------------------------- 1 | ./private/var/* 2 | 3 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/CREDITS.txt: -------------------------------------------------------------------------------- 1 | comex 2 | chronic dev team 3 | idroid/openiboot team 4 | iphone dev team 5 | Jonathan Zdziarski 6 | msftguy 7 | planetbeing 8 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/README.txt: -------------------------------------------------------------------------------- 1 | See http://code.google.com/p/iphone-dataprotection/wiki/README 2 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/build_ramdisk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # set +e 4 | # set -o errexit 5 | 6 | if [ $# -lt 4 ] 7 | then 8 | echo "Syntax: $0 IPSW RAMDISK KEY IV CUSTOMRAMDISK" 9 | echo "python_scripts/kernel_patcher.py can generate a shell script with the correct parameters" 10 | exit 11 | fi 12 | 13 | if [ ! -f ramdisk_tools/restored_external ] 14 | then 15 | echo "ramdisk_tools/restored_external not found, check compilation output for errors" 16 | exit -1 17 | fi 18 | 19 | IPSW=$1 20 | RAMDISK=$2 21 | KEY=$3 22 | IV=$4 23 | CUSTOMRAMDISK=$5 24 | if [ "$CUSTOMRAMDISK" == "" ]; then 25 | CUSTOMRAMDISK="myramdisk.dmg" 26 | fi 27 | IMG3FS="./img3fs/img3fs" 28 | IMG3MNT="/tmp/img3" 29 | 30 | if [ ! -f $IMG3FS ]; then 31 | echo "img3fs is missing, install osxfuse and run make -C img3fs/" 32 | exit -1 33 | fi 34 | 35 | if [ ! -f ssh.tar.gz ]; then 36 | echo "Downloading ssh.tar.gz from googlecode" 37 | curl -O http://iphone-dataprotection.googlecode.com/files/ssh.tar.gz 38 | fi 39 | 40 | unzip -o $IPSW $RAMDISK 41 | 42 | if [ -d "/Volumes/ramdisk" ]; then 43 | hdiutil eject /Volumes/ramdisk 44 | umount $IMG3MNT 45 | fi 46 | 47 | mkdir -p $IMG3MNT 48 | 49 | $IMG3FS -key $KEY -iv $IV $IMG3MNT $RAMDISK 50 | 51 | hdiutil attach -owners off $IMG3MNT/DATA.dmg 52 | 53 | #remove baseband files to free space 54 | rm -rf /Volumes/ramdisk/usr/local/standalone/firmware/* 55 | rm -rf /Volumes/ramdisk/usr/share/progressui/ 56 | #dont replace existing files, replacing launchctl on armv6 ramdisks makes it fail somehow 57 | tar -C /Volumes/ramdisk/ -xzkP < ssh.tar.gz 58 | rm /Volumes/ramdisk/bin/vdir 59 | rm /Volumes/ramdisk/bin/egrep 60 | rm /Volumes/ramdisk/bin/grep 61 | 62 | #rm /Volumes/ramdisk/usr/local/bin/restored_external 63 | cp ramdisk_tools/restored_external /Volumes/ramdisk/usr/local/bin 64 | cp mtree /Volumes/ramdisk/usr/local/bin 65 | cp mtree_exclude /Volumes/ramdisk/etc 66 | 67 | cp ramdisk_tools/bruteforce ramdisk_tools/device_infos /Volumes/ramdisk/var/root 68 | cp ramdisk_tools/scripts/* /Volumes/ramdisk/var/root 69 | cp ramdisk_tools/ioflashstoragekit /Volumes/ramdisk/var/root 70 | 71 | #if present, copy ssh public key to ramdisk 72 | if [ -f ~/.ssh/id_rsa.pub ]; then 73 | mkdir /Volumes/ramdisk/var/root/.ssh 74 | cp ~/.ssh/id_rsa.pub /Volumes/ramdisk/var/root/.ssh/authorized_keys 75 | fi 76 | 77 | hdiutil eject /Volumes/ramdisk 78 | umount $IMG3MNT 79 | 80 | mv $RAMDISK $CUSTOMRAMDISK 81 | 82 | #echo "$CUSTOMRAMDISK created" 83 | 84 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/img3fs/Makefile: -------------------------------------------------------------------------------- 1 | img3fs: img3fs.c 2 | gcc -o $@ $^ -Wall -lfuse_ino64 -lcrypto -I/usr/local/include/osxfuse || gcc -o $@ $^ -Wall -losxfuse_i64 -lcrypto -I/usr/local/include/osxfuse -L/usr/local/lib 3 | 4 | clean: 5 | rm img3fs 6 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/img3fs/README: -------------------------------------------------------------------------------- 1 | FUSE img3 filesystem 2 | read/write/encryption support 3 | 4 | Usage example: 5 | 6 | mkdir /tmp/img3 7 | img3fs /tmp/img3 038-0032-002.dmg -iv 9b20ae16bebf4cf1b9101374c3ab0095 -key 06849aead2e9a6ca8a82c3929bad5c2368942e3681a3d5751720d2aacf0694c0 8 | hdiutil attach /tmp/img3/DATA.dmg 9 | rm -rf /Volumes/ramdisk/usr/local/standalone/firmware/* 10 | echo "Hello World!" > /Volumes/ramdisk/hello.txt 11 | hdiutil eject /Volumes/ramdisk 12 | umount /tmp/img3 -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/mtree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/ios-integrity-validator/2090e6321cd313493c6f3746866411d865cde6ab/vendor/iphone-dataprotection/mtree -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/mtree_exclude: -------------------------------------------------------------------------------- 1 | ./System/Library/Caches/com.apple.kernelcaches/kernelcache 2 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/README.txt: -------------------------------------------------------------------------------- 1 | Dependencies 2 | pycrypto (https://www.dlitz.net/software/pycrypto/) 3 | construct (http://construct.wikispaces.com/) -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/backup_tool.py: -------------------------------------------------------------------------------- 1 | from backups.backup3 import decrypt_backup3 2 | from backups.backup4 import MBDB 3 | from keystore.keybag import Keybag 4 | from util import readPlist, makedirs 5 | import os 6 | import sys 7 | import plistlib 8 | 9 | showinfo = ["Device Name", "Display Name", "Last Backup Date", "IMEI", 10 | "Serial Number", "Product Type", "Product Version", "iTunes Version"] 11 | 12 | def extract_backup(backup_path, output_path, password=""): 13 | if not os.path.exists(backup_path + "/Manifest.plist"): 14 | print "Manifest.plist not found" 15 | return 16 | manifest = readPlist(backup_path + "/Manifest.plist") 17 | 18 | info = readPlist( backup_path + "/Info.plist") 19 | for i in showinfo: 20 | print i + " : " + unicode(info.get(i, "missing")) 21 | 22 | print "Extract backup to %s ? (y/n)" % output_path 23 | if raw_input() == "n": 24 | return 25 | 26 | print "Backup is %sencrypted" % (int(not manifest["IsEncrypted"]) * "not ") 27 | 28 | if manifest["IsEncrypted"] and password == "": 29 | print "Enter backup password : " 30 | password = raw_input() 31 | 32 | if not manifest.has_key("BackupKeyBag"): 33 | print "No BackupKeyBag in manifest, assuming iOS 3.x backup" 34 | decrypt_backup3(backup_path, output_path, password) 35 | else: 36 | mbdb = MBDB(backup_path) 37 | 38 | kb = Keybag.createWithBackupManifest(manifest, password) 39 | if not kb: 40 | return 41 | manifest["password"] = password 42 | makedirs(output_path) 43 | plistlib.writePlist(manifest, output_path + "/Manifest.plist") 44 | 45 | mbdb.keybag = kb 46 | mbdb.extract_backup(output_path) 47 | 48 | print "You can decrypt the keychain using the following command : " 49 | print "python keychain_tool.py -d %s %s" % (output_path + "/keychain-backup.plist", output_path + "/Manifest.plist") 50 | 51 | def extract_all(): 52 | if sys.platform == "win32": 53 | mobilesync = os.environ["APPDATA"] + "/Apple Computer/MobileSync/Backup/" 54 | elif sys.platform == "darwin": 55 | mobilesync = os.environ["HOME"] + "/Library/Application Support/MobileSync/Backup/" 56 | else: 57 | print "Unsupported operating system" 58 | return 59 | print "-" * 60 60 | print "Searching for iTunes backups" 61 | print "-" * 60 62 | 63 | for udid in os.listdir(mobilesync): 64 | extract_backup(mobilesync + "/" + udid, udid + "_extract") 65 | 66 | def main(): 67 | if len(sys.argv) < 2: 68 | print "Usage: %s [output path]" % sys.argv[0] 69 | return 70 | backup_path = sys.argv[1] 71 | output_path = os.path.dirname(backup_path) + "_extract" 72 | if len(sys.argv) >= 3: 73 | output_path = sys.argv[2] 74 | 75 | extract_backup(backup_path, output_path) 76 | 77 | if __name__ == "__main__": 78 | main() 79 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/backups/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/ios-integrity-validator/2090e6321cd313493c6f3746866411d865cde6ab/vendor/iphone-dataprotection/python_scripts/backups/__init__.py -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/backups/backup3.py: -------------------------------------------------------------------------------- 1 | from crypto.PBKDF2 import PBKDF2 2 | from crypto.aes import AESdecryptCBC 3 | from util import read_file, write_file, makedirs, readPlist 4 | from util.bplist import BPlistReader 5 | import hashlib 6 | import struct 7 | import glob 8 | import sys 9 | import os 10 | 11 | """ 12 | decrypt iOS 3 backup blob (metadata and file contents) 13 | """ 14 | 15 | def decrypt_blob(blob, auth_key): 16 | len = struct.unpack(">H", blob[0:2])[0] 17 | if len != 66: 18 | print "blob len != 66" 19 | magic = struct.unpack(">H", blob[2:4])[0] 20 | if magic != 0x0100: 21 | print "magic != 0x0100" 22 | iv = blob[4:20] 23 | 24 | blob_key = AESdecryptCBC(blob[20:68], auth_key, iv)[:32] 25 | 26 | return AESdecryptCBC(blob[68:], blob_key, iv, padding=True) 27 | 28 | def decrypt_backup3(backupfolder, outputfolder, passphrase): 29 | auth_key = None 30 | manifest = readPlist(backupfolder + "/Manifest.plist") 31 | 32 | if manifest["IsEncrypted"]: 33 | manifest_data = manifest["Data"].data 34 | 35 | authdata = manifest["AuthData"].data 36 | 37 | pkbdf_salt = authdata[:8] 38 | iv = authdata[8:24] 39 | key = PBKDF2(passphrase,pkbdf_salt,iterations=2000).read(32) 40 | 41 | data = AESdecryptCBC(authdata[24:], key, iv) 42 | auth_key = data[:32] 43 | 44 | if hashlib.sha1(auth_key).digest() != data[32:52]: 45 | print "wrong auth key (hash mismatch) => wrong passphrase" 46 | return 47 | 48 | print "Passphrase seems OK" 49 | 50 | for mdinfo_name in glob.glob(backupfolder + "/*.mdinfo"): 51 | 52 | mddata_name = mdinfo_name[:-7] + ".mddata" 53 | mdinfo = readPlist(mdinfo_name) 54 | metadata = mdinfo["Metadata"].data 55 | if mdinfo["IsEncrypted"]: 56 | metadata = decrypt_blob(metadata, auth_key) 57 | metadata = BPlistReader.plistWithString(metadata) 58 | 59 | print metadata["Path"] 60 | 61 | filedata = read_file(mddata_name) 62 | if mdinfo["IsEncrypted"]: 63 | filedata = decrypt_blob(filedata, auth_key) 64 | 65 | filename = metadata["Path"] 66 | makedirs(outputfolder + "/" + os.path.dirname(filename)) 67 | write_file(outputfolder + "/" + filename, filedata) 68 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/backups/backup4.py: -------------------------------------------------------------------------------- 1 | from crypto.aes import AESdecryptCBC 2 | from hashlib import sha1 3 | from struct import unpack 4 | import os 5 | 6 | MBDB_SIGNATURE = 'mbdb\x05\x00' 7 | 8 | MASK_SYMBOLIC_LINK = 0xa000 9 | MASK_REGULAR_FILE = 0x8000 10 | MASK_DIRECTORY = 0x4000 11 | 12 | def warn(msg): 13 | print "WARNING: %s" % msg 14 | 15 | class MBFileRecord(object): 16 | def __init__(self, mbdb): 17 | self.domain = self._decode_string(mbdb) 18 | if self.domain is None: 19 | warn("Domain name missing from record") 20 | 21 | self.path = self._decode_string(mbdb) 22 | if self.path is None: 23 | warn("Relative path missing from record") 24 | 25 | self.target= self._decode_string(mbdb) # for symbolic links 26 | 27 | self.digest = self._decode_string(mbdb) 28 | self.encryption_key = self._decode_data(mbdb) 29 | 30 | data = mbdb.read(40) # metadata, fixed size 31 | 32 | self.mode, = unpack('>H', data[0:2]) 33 | if not(self.is_regular_file() or self.is_symbolic_link() or self.is_directory()): 34 | print self.mode 35 | warn("File type mising from record mode") 36 | 37 | if self.is_symbolic_link() and self.target is None: 38 | warn("Target required for symblolic links") 39 | 40 | self.inode_number = unpack('>Q', data[2:10]) 41 | self.user_id, = unpack('>I', data[10:14]) 42 | self.group_id = unpack('>I', data[14:18]) 43 | self.last_modification_time, = unpack('>i', data[18:22]) 44 | self.last_status_change_time, = unpack('>i', data[22:26]) 45 | self.birth_time, = unpack('>i', data[26:30]) 46 | self.size, = unpack('>q', data[30:38]) 47 | 48 | if self.size != 0 and not self.is_regular_file(): 49 | warn("Non-zero size for a record which is not a regular file") 50 | 51 | self.protection_class = ord(data[38]) 52 | 53 | num_attributes = ord(data[39]) 54 | if num_attributes == 0: 55 | self.extended_attributes = None 56 | else: 57 | self.extended_attributes = {} 58 | for i in xrange(num_attributes): 59 | k = self._decode_string(mbdb) 60 | v = self._decode_data(mbdb) 61 | self.extended_attributes[k] = v 62 | 63 | def _decode_string(self, s): 64 | s_len, = unpack('>H', s.read(2)) 65 | if s_len == 0xffff: 66 | return None 67 | return s.read(s_len) 68 | 69 | def _decode_data(self, s): 70 | return self._decode_string(s) 71 | 72 | def type(self): 73 | return self.mode & 0xf000 74 | 75 | def is_symbolic_link(self): 76 | return self.type() == MASK_SYMBOLIC_LINK 77 | 78 | def is_regular_file(self): 79 | return self.type() == MASK_REGULAR_FILE 80 | 81 | def is_directory(self): 82 | return self.type() == MASK_DIRECTORY 83 | 84 | class MBDB(object): 85 | def __init__(self, path): 86 | self.files = {} 87 | self.backup_path = path 88 | self.keybag = None 89 | # open the database 90 | mbdb = file(path + '/Manifest.mbdb', 'rb') 91 | 92 | # skip signature 93 | signature = mbdb.read(len(MBDB_SIGNATURE)) 94 | if signature != MBDB_SIGNATURE: 95 | raise Exception("Bad mbdb signature") 96 | try: 97 | while True: 98 | rec = MBFileRecord(mbdb) 99 | fn = rec.domain + "-" + rec.path 100 | sb = sha1(fn).digest().encode('hex') 101 | if len(sb) % 2 == 1: 102 | sb = '0'+sb 103 | self.files[sb] = rec 104 | except: 105 | mbdb.close() 106 | 107 | def get_file_by_name(self, filename): 108 | for (k, v) in self.files.iteritems(): 109 | if v.path == filename: 110 | return (k, v) 111 | return None 112 | 113 | def extract_backup(self, output_path): 114 | for record in self.files.values(): 115 | # create directories if they do not exist 116 | # makedirs throw an exception, my code is ugly =) 117 | if record.is_directory(): 118 | try: 119 | os.makedirs(os.path.join(output_path, record.domain, record.path)) 120 | except: 121 | pass 122 | 123 | for (filename, record) in self.files.items(): 124 | # skip directories 125 | if record.is_directory(): 126 | continue 127 | self.extract_file(filename, record, output_path) 128 | 129 | def extract_file(self, filename, record, output_path): 130 | # adjust output file name 131 | if record.is_symbolic_link(): 132 | out_file = record.target 133 | else: 134 | out_file = record.path 135 | 136 | file_data = self.read_file(filename, record) 137 | # write output file 138 | path = os.path.join(output_path, record.domain, out_file) 139 | if file_data: 140 | print("Writing %s" % path) 141 | f = file(path, 'wb') 142 | f.write(file_data) 143 | f.close() 144 | 145 | def read_file(self, filename, record): 146 | # read backup file 147 | try: 148 | f = file(self.backup_path + '/' + filename, 'rb') 149 | file_data = f.read() 150 | f.close() 151 | except(IOError): 152 | warn("File %s (%s) has not been found" % (filename, record.path)) 153 | return 154 | 155 | if record.encryption_key is not None and self.keybag: # file is encrypted! 156 | key = self.keybag.unwrapKeyForClass(record.protection_class, record.encryption_key[4:]) 157 | if not key: 158 | warn("Cannot unwrap key") 159 | return 160 | file_data = AESdecryptCBC(file_data, key) 161 | padding = file_data[record.size:] 162 | if len(padding) > 16 or padding != chr(len(padding)) * len(padding): 163 | warn("Incorrect padding for file %s" % record.path) 164 | file_data = file_data[:record.size] 165 | return file_data 166 | 167 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/crypto/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/ios-integrity-validator/2090e6321cd313493c6f3746866411d865cde6ab/vendor/iphone-dataprotection/python_scripts/crypto/__init__.py -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/crypto/aes.py: -------------------------------------------------------------------------------- 1 | from Crypto.Cipher import AES 2 | 3 | ZEROIV = "\x00"*16 4 | def removePadding(blocksize, s): 5 | 'Remove rfc 1423 padding from string.' 6 | n = ord(s[-1]) # last byte contains number of padding bytes 7 | if n > blocksize or n > len(s): 8 | raise Exception('invalid padding') 9 | return s[:-n] 10 | 11 | 12 | def AESdecryptCBC(data, key, iv=ZEROIV, padding=False): 13 | if len(data) % 16: 14 | print "AESdecryptCBC: data length not /16, truncating" 15 | data = data[0:(len(data)/16) * 16] 16 | data = AES.new(key, AES.MODE_CBC, iv).decrypt(data) 17 | if padding: 18 | return removePadding(16, data) 19 | return data 20 | 21 | def AESencryptCBC(data, key, iv=ZEROIV, padding=False): 22 | if len(data) % 16: 23 | print "AESdecryptCBC: data length not /16, truncating" 24 | data = data[0:(len(data)/16) * 16] 25 | data = AES.new(key, AES.MODE_CBC, iv).encrypt(data) 26 | return data 27 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/crypto/aeswrap.py: -------------------------------------------------------------------------------- 1 | import struct 2 | from Crypto.Cipher import AES 3 | 4 | """ 5 | http://www.ietf.org/rfc/rfc3394.txt 6 | quick'n'dirty AES wrap implementation 7 | used by iOS 4 KeyStore kernel extension for wrapping/unwrapping encryption keys 8 | """ 9 | def unpack64bit(s): 10 | return struct.unpack(">Q",s)[0] 11 | def pack64bit(s): 12 | return struct.pack(">Q",s) 13 | 14 | def AESUnwrap(kek, wrapped): 15 | C = [] 16 | for i in xrange(len(wrapped)/8): 17 | C.append(unpack64bit(wrapped[i*8:i*8+8])) 18 | n = len(C) - 1 19 | R = [0] * (n+1) 20 | A = C[0] 21 | 22 | for i in xrange(1,n+1): 23 | R[i] = C[i] 24 | 25 | for j in reversed(xrange(0,6)): 26 | for i in reversed(xrange(1,n+1)): 27 | todec = pack64bit(A ^ (n*j+i)) 28 | todec += pack64bit(R[i]) 29 | B = AES.new(kek).decrypt(todec) 30 | A = unpack64bit(B[:8]) 31 | R[i] = unpack64bit(B[8:]) 32 | 33 | #assert A == 0xa6a6a6a6a6a6a6a6, "AESUnwrap: integrity check FAIL, wrong kek ?" 34 | if A != 0xa6a6a6a6a6a6a6a6: 35 | #print "AESUnwrap: integrity check FAIL, wrong kek ?" 36 | return None 37 | res = "".join(map(pack64bit, R[1:])) 38 | return res 39 | 40 | def AESwrap(kek, data): 41 | A = 0xa6a6a6a6a6a6a6a6 42 | R = [0] 43 | for i in xrange(len(data)/8): 44 | R.append(unpack64bit(data[i*8:i*8+8])) 45 | n = len(R) - 1 46 | 47 | for j in xrange(0,6): 48 | for i in xrange(1,n+1): 49 | B = AES.new(kek).encrypt(pack64bit(A) + pack64bit(R[i])) 50 | A = unpack64bit(B[:8]) ^ (n*j+i) 51 | R[i] = unpack64bit(B[8:]) 52 | 53 | res = pack64bit(A) + "".join(map(pack64bit, R[1:])) 54 | return res 55 | 56 | if __name__ == "__main__": 57 | #format (kek, data, expected_ciphertext) 58 | test_vectors = [ 59 | ("000102030405060708090A0B0C0D0E0F", "00112233445566778899AABBCCDDEEFF", "1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5"), 60 | ("000102030405060708090A0B0C0D0E0F1011121314151617", "00112233445566778899AABBCCDDEEFF", "96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D"), 61 | ("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F", "00112233445566778899AABBCCDDEEFF", "64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7"), 62 | ("000102030405060708090A0B0C0D0E0F1011121314151617", "00112233445566778899AABBCCDDEEFF0001020304050607", "031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2"), 63 | ("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F", "00112233445566778899AABBCCDDEEFF0001020304050607", "A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1"), 64 | ("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F", "00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F", "28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21") 65 | ] 66 | for kek, data, expected in test_vectors: 67 | ciphertext = AESwrap(kek.decode("hex"), data.decode("hex")) 68 | assert ciphertext == expected.decode("hex") 69 | assert AESUnwrap(kek.decode("hex"), ciphertext) == data.decode("hex") 70 | print "All tests OK !" 71 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/crypto/curve25519.py: -------------------------------------------------------------------------------- 1 | from Crypto.Util import number 2 | 3 | CURVE_P = (2**255 - 19) 4 | CURVE_A = 121665 5 | 6 | def curve25519_monty(x1, z1, x2, z2, qmqp): 7 | a = (x1 + z1) * (x2 - z2) % CURVE_P 8 | b = (x1 - z1) * (x2 + z2) % CURVE_P 9 | x4 = (a + b) * (a + b) % CURVE_P 10 | 11 | e = (a - b) * (a - b) % CURVE_P 12 | z4 = e * qmqp % CURVE_P 13 | 14 | a = (x1 + z1) * (x1 + z1) % CURVE_P 15 | b = (x1 - z1) * (x1 - z1) % CURVE_P 16 | x3 = a * b % CURVE_P 17 | 18 | g = (a - b) % CURVE_P 19 | h = (a + CURVE_A * g) % CURVE_P 20 | z3 = (g * h) % CURVE_P 21 | 22 | return x3, z3, x4, z4 23 | 24 | def curve25519_mult(n, q): 25 | nqpqx, nqpqz = q, 1 26 | nqx, nqz = 1, 0 27 | 28 | for i in range(255, -1, -1): 29 | if (n >> i) & 1: 30 | nqpqx,nqpqz,nqx,nqz = curve25519_monty(nqpqx, nqpqz, nqx, nqz, q) 31 | else: 32 | nqx,nqz,nqpqx,nqpqz = curve25519_monty(nqx, nqz, nqpqx, nqpqz, q) 33 | return nqx, nqz 34 | 35 | def curve25519(secret, basepoint): 36 | a = ord(secret[0]) 37 | a &= 248 38 | b = ord(secret[31]) 39 | b &= 127 40 | b |= 64 41 | s = chr(a) + secret[1:-1] + chr(b) 42 | 43 | s = number.bytes_to_long(s[::-1]) 44 | basepoint = number.bytes_to_long(basepoint[::-1]) 45 | 46 | x, z = curve25519_mult(s, basepoint) 47 | zmone = number.inverse(z, CURVE_P) 48 | z = x * zmone % CURVE_P 49 | return number.long_to_bytes(z)[::-1] 50 | 51 | 52 | if __name__ == "__main__": 53 | from crypto.aeswrap import AESUnwrap 54 | from Crypto.Hash import SHA256 55 | 56 | z="04000000080000000200000048000000000000000000000000000000000000000000000002917dc2542198edeb1078c4d1ebab74d9ca87890657ba02b9825dadf20a002f44360c6f87743fac0236df1f9eedbea801e31677aef3a09adfb4e10a37ae27facf419ab3ea3f39f4".decode("hex") 57 | 58 | mysecret = "99b66345829d8c05041eea1ba1ed5b2984c3e5ec7a756ef053473c7f22b49f14".decode("hex") 59 | mypublic = "b1c652786697a5feef36a56f36fde524a21193f4e563627977ab515f600fdb3a".decode("hex") 60 | hispublic = z[36:36+32] 61 | 62 | #c4d9fe462a2ebbf0745195ce7dc5e8b49947bbd5b42da74175d5f8125b44582b 63 | shared = curve25519(mysecret, hispublic) 64 | print shared.encode("hex") 65 | 66 | h = SHA256.new() 67 | h.update('\x00\x00\x00\x01') 68 | h.update(shared) 69 | h.update(hispublic) 70 | h.update(mypublic) 71 | md = h.digest() 72 | 73 | #e442c81b91ea876d3cf42d3aea75f4b0c3f90f9fd045e1f5784b91260f3bdc9c 74 | print AESUnwrap(md, z[32+36:]).encode("hex") 75 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/crypto/gcm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from Crypto.Cipher import AES 4 | from Crypto.Util import strxor 5 | from struct import pack, unpack 6 | 7 | def gcm_rightshift(vec): 8 | for x in range(15, 0, -1): 9 | c = vec[x] >> 1 10 | c |= (vec[x-1] << 7) & 0x80 11 | vec[x] = c 12 | vec[0] >>= 1 13 | return vec 14 | 15 | def gcm_gf_mult(a, b): 16 | mask = [ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 ] 17 | poly = [ 0x00, 0xe1 ] 18 | 19 | Z = [0] * 16 20 | V = [c for c in a] 21 | 22 | for x in range(128): 23 | if b[x >> 3] & mask[x & 7]: 24 | Z = [V[y] ^ Z[y] for y in range(16)] 25 | bit = V[15] & 1 26 | V = gcm_rightshift(V) 27 | V[0] ^= poly[bit] 28 | return Z 29 | 30 | def ghash(h, auth_data, data): 31 | u = (16 - len(data)) % 16 32 | v = (16 - len(auth_data)) % 16 33 | 34 | x = auth_data + chr(0) * v + data + chr(0) * u 35 | x += pack('>QQ', len(auth_data) * 8, len(data) * 8) 36 | 37 | y = [0] * 16 38 | vec_h = [ord(c) for c in h] 39 | 40 | for i in range(0, len(x), 16): 41 | block = [ord(c) for c in x[i:i+16]] 42 | y = [y[j] ^ block[j] for j in range(16)] 43 | y = gcm_gf_mult(y, vec_h) 44 | 45 | return ''.join(chr(c) for c in y) 46 | 47 | def inc32(block): 48 | counter, = unpack('>L', block[12:]) 49 | counter += 1 50 | return block[:12] + pack('>L', counter) 51 | 52 | def gctr(k, icb, plaintext): 53 | y = '' 54 | if len(plaintext) == 0: 55 | return y 56 | 57 | aes = AES.new(k) 58 | cb = icb 59 | 60 | for i in range(0, len(plaintext), aes.block_size): 61 | cb = inc32(cb) 62 | encrypted = aes.encrypt(cb) 63 | plaintext_block = plaintext[i:i+aes.block_size] 64 | y += strxor.strxor(plaintext_block, encrypted[:len(plaintext_block)]) 65 | 66 | return y 67 | 68 | def gcm_decrypt(k, iv, encrypted, auth_data, tag): 69 | aes = AES.new(k) 70 | h = aes.encrypt(chr(0) * aes.block_size) 71 | 72 | if len(iv) == 12: 73 | y0 = iv + "\x00\x00\x00\x01" 74 | else: 75 | y0 = ghash(h, '', iv) 76 | 77 | decrypted = gctr(k, y0, encrypted) 78 | s = ghash(h, auth_data, encrypted) 79 | 80 | t = aes.encrypt(y0) 81 | T = strxor.strxor(s, t) 82 | if T != tag: 83 | raise ValueError('Decrypted data is invalid') 84 | else: 85 | return decrypted 86 | 87 | def gcm_encrypt(k, iv, plaintext, auth_data): 88 | aes = AES.new(k) 89 | h = aes.encrypt(chr(0) * aes.block_size) 90 | 91 | if len(iv) == 12: 92 | y0 = iv + "\x00\x00\x00\x01" 93 | else: 94 | y0 = ghash(h, '', iv) 95 | 96 | encrypted = gctr(k, y0, plaintext) 97 | s = ghash(h, auth_data, encrypted) 98 | 99 | t = aes.encrypt(y0) 100 | T = strxor.strxor(s, t) 101 | return (encrypted, T) 102 | 103 | def main(): 104 | #http://www.ieee802.org/1/files/public/docs2011/bn-randall-test-vectors-0511-v1.pdf 105 | k = 'AD7A2BD03EAC835A6F620FDCB506B345'.decode("hex") 106 | p = '' 107 | a = 'D609B1F056637A0D46DF998D88E5222AB2C2846512153524C0895E8108000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233340001'.decode("hex") 108 | iv = '12153524C0895E81B2C28465'.decode("hex") 109 | c, t = gcm_encrypt(k, iv, '', a) 110 | assert c == "" 111 | assert t == "f09478a9b09007d06f46e9b6a1da25dd".decode("hex") 112 | 113 | k = 'AD7A2BD03EAC835A6F620FDCB506B345'.decode("hex") 114 | p = '08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A0002'.decode("hex") 115 | a = 'D609B1F056637A0D46DF998D88E52E00B2C2846512153524C0895E81'.decode("hex") 116 | iv = '12153524C0895E81B2C28465'.decode("hex") 117 | c, t = gcm_encrypt(k, iv, p, a) 118 | assert c == '701AFA1CC039C0D765128A665DAB69243899BF7318CCDC81C9931DA17FBE8EDD7D17CB8B4C26FC81E3284F2B7FBA713D'.decode("hex") 119 | assert t == '4F8D55E7D3F06FD5A13C0C29B9D5B880'.decode("hex") 120 | 121 | key = "91bfb6cbcff07b93a4c68bbfe99ac63b713f0627025c0fb1ffc5b0812dc284f8".decode("hex") 122 | data = "020000000B00000028000000DE44D22E96B1966BAEF4CBEA8675871D40BA669401BD4EBB52AF9C025134187E70549012058456BF0EC0FA1F8FF9F822AC4312AB2141FA712E6D1482358EAC1421A1BFFA81EF38BD0BF2E52675D665EFE3C534E188F575774FAA92E74345575E370B9982661FAE8BD9243B7AD7D2105B275424C0CA1145B9D43AFF04F2747E40D62EC60563960D62A894BE66F267B14D75C0572BE60CC9B339D440FCB418D4F729BBF15C14E0D3A43E4A8B44523D8B3B0F3E7DF85AA67A707EE19CB893277D2392234D7DBC17DA4A0BD7F166189FC54C16C20D287E20FD2FB11BD2CE09ADBDABB95124CD4BFE219E34D3C80E69570A5A506555D7094916C5D75E0065F1796F556EDF0DAA1AA758E0C85AE3951BD363F26B1D43F6CBAEE12D97AD3B60CFA89C1C76BB29F2B54BE31B6CE166F4860C5E5DA92588EF53AA946DF159E60E6F05009D12FB1E37".decode("hex") 123 | ciphertext = data[12+40:-16] 124 | tag = data[-16:] 125 | print repr(gcm_decrypt(key, '', ciphertext, '', tag)) 126 | 127 | 128 | if __name__ == '__main__': 129 | main() 130 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/demo_backup_keychain.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys, os 4 | from PyQt4 import QtGui, QtCore 5 | from backups.backup4 import MBDB 6 | from keychain.keychain4 import Keychain4 7 | from util.bplist import BPlistReader 8 | from keystore.keybag import Keybag 9 | from util import readPlist 10 | 11 | class KeychainTreeWidget(QtGui.QTreeWidget): 12 | def __init__(self, parent=None): 13 | QtGui.QTreeWidget.__init__(self, parent) 14 | 15 | self.setGeometry(10, 10, 780, 380) 16 | self.header().hide() 17 | self.setColumnCount(2) 18 | 19 | class KeychainTreeWidgetItem(QtGui.QTreeWidgetItem): 20 | def __init__(self, title): 21 | QtGui.QTreeWidgetItem.__init__(self, [title]) 22 | 23 | fnt = self.font(0) 24 | fnt.setBold(True) 25 | self.setFont(0, fnt) 26 | self.setColors() 27 | 28 | def setText(self, column, title): 29 | QtGui.QTreeWidgetItem.setText(self, column, title) 30 | 31 | def setColors(self): 32 | self.setForeground(0, QtGui.QBrush(QtGui.QColor(80, 80, 80))) 33 | self.setBackground(0, QtGui.QBrush(QtGui.QColor(230, 230, 230))) 34 | self.setBackground(1, QtGui.QBrush(QtGui.QColor(230, 230, 230))) 35 | 36 | class LockedKeychainTreeWidgetItem(KeychainTreeWidgetItem): 37 | def setColors(self): 38 | self.setForeground(0, QtGui.QBrush(QtGui.QColor(255, 80, 80))) 39 | self.setBackground(0, QtGui.QBrush(QtGui.QColor(255, 230, 230))) 40 | self.setBackground(1, QtGui.QBrush(QtGui.QColor(255, 230, 230))) 41 | 42 | class KeychainWindow(QtGui.QWidget): 43 | def __init__(self, parent=None): 44 | QtGui.QWidget.__init__(self, parent) 45 | 46 | self.setGeometry(100, 100, 800, 400) 47 | self.setWindowTitle('Keychain Explorer') 48 | 49 | self.passwordTree = KeychainTreeWidget(parent=self) 50 | 51 | def setGenericPasswords(self, pwds): 52 | self.genericPasswords = pwds 53 | 54 | self.passwordItems = KeychainTreeWidgetItem('Generic Passwords') 55 | 56 | for pwd in self.genericPasswords: 57 | if not pwd.has_key('acct'): 58 | continue 59 | if len(pwd['acct']) > 0: 60 | item_title = '%s (%s)' % (pwd['svce'], pwd['acct']) 61 | else: 62 | item_title = pwd['svce'] 63 | 64 | if pwd['data'] is None: 65 | item = LockedKeychainTreeWidgetItem(item_title) 66 | else: 67 | item = KeychainTreeWidgetItem(item_title) 68 | 69 | item.addChild(QtGui.QTreeWidgetItem(['Service', pwd['svce']])) 70 | item.addChild(QtGui.QTreeWidgetItem(['Account', pwd['acct']])) 71 | if pwd['data'] is not None: 72 | item.addChild(QtGui.QTreeWidgetItem(['Data', pwd['data']])) 73 | else: 74 | item.addChild(QtGui.QTreeWidgetItem(['Data', 'N/A'])) 75 | item.addChild(QtGui.QTreeWidgetItem(['Access Group', pwd['agrp']])) 76 | 77 | self.passwordItems.addChild(item) 78 | 79 | self.passwordTree.addTopLevelItem(self.passwordItems) 80 | 81 | self.passwordTree.expandAll() 82 | self.passwordTree.resizeColumnToContents(0) 83 | 84 | def setInternetPasswords(self, pwds): 85 | self.internetPasswords = pwds 86 | 87 | self.internetPasswordItems = KeychainTreeWidgetItem('Internet Passwords') 88 | 89 | for pwd in pwds: 90 | item_title = '%s (%s)' % (pwd['srvr'], pwd['acct']) 91 | 92 | item = KeychainTreeWidgetItem(item_title) 93 | 94 | item.addChild(QtGui.QTreeWidgetItem(['Server', pwd['srvr']])) 95 | item.addChild(QtGui.QTreeWidgetItem(['Account', pwd['acct']])) 96 | if pwd['data'] is not None: 97 | item.addChild(QtGui.QTreeWidgetItem(['Data', pwd['data']])) 98 | else: 99 | item.addChild(QtGui.QTreeWidgetItem(['Data', 'N/A'])) 100 | 101 | item.addChild(QtGui.QTreeWidgetItem(['Port', str(pwd['port'])])) 102 | item.addChild(QtGui.QTreeWidgetItem(['Access Group', pwd['agrp']])) 103 | 104 | self.internetPasswordItems.addChild(item) 105 | 106 | self.passwordTree.addTopLevelItem(self.internetPasswordItems) 107 | 108 | self.passwordTree.expandAll() 109 | self.passwordTree.resizeColumnToContents(0) 110 | 111 | def warn(msg): 112 | print "WARNING: %s" % msg 113 | 114 | def getBackupKeyBag(backupfolder, passphrase): 115 | manifest = readPlist(backupfolder + "/Manifest.plist") 116 | 117 | kb = Keybag(manifest["BackupKeyBag"].data) 118 | 119 | if kb.unlockBackupKeybagWithPasscode(passphrase): 120 | print "BackupKeyBag unlock OK" 121 | return kb 122 | else: 123 | return None 124 | 125 | def main(): 126 | app = QtGui.QApplication(sys.argv) 127 | init_path = "{0:s}/Apple Computer/MobileSync/Backup".format(os.getenv('APPDATA')) 128 | dirname = QtGui.QFileDialog.getExistingDirectory(None, "Select iTunes backup directory", init_path) 129 | kb = getBackupKeyBag(dirname, 'pouet') #XXX: hardcoded password for demo 130 | if not kb: 131 | warn("Backup keybag unlock fail : wrong passcode?") 132 | return 133 | db = MBDB(dirname) 134 | db.keybag = kb 135 | filename, record = db.get_file_by_name("keychain-backup.plist") 136 | keychain_data = db.read_file(filename, record) 137 | 138 | f = file('keychain.tmp', 'wb') 139 | f.write(keychain_data) 140 | f.close() 141 | 142 | kc = Keychain4('keychain.tmp', kb) 143 | 144 | pwds = kc.get_passwords() 145 | inet_pwds = kc.get_inet_passwords() 146 | 147 | qb = KeychainWindow() 148 | qb.setGenericPasswords(pwds) 149 | qb.setInternetPasswords(inet_pwds) 150 | qb.show() 151 | 152 | sys.exit(app.exec_()) 153 | pass 154 | 155 | if __name__ == '__main__': 156 | main() 157 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/demo_bruteforce.py: -------------------------------------------------------------------------------- 1 | import plistlib 2 | import os 3 | from keystore.keybag import Keybag 4 | from keychain.keychain4 import Keychain4 5 | from keychain.managedconfiguration import bruteforce_old_pass 6 | from util.ramdiskclient import RamdiskToolClient 7 | from util import write_file 8 | 9 | def checkPasscodeComplexity(rdclient): 10 | pl = rdclient.downloadFile("/mnt2/mobile/Library/ConfigurationProfiles/PublicInfo/EffectiveUserSettings.plist") 11 | if not pl: 12 | print "Failed to download UserSettings.plist, assuming simple passcode" 13 | return 0 14 | pl = plistlib.readPlistFromString(pl) 15 | print "passcodeKeyboardComplexity :", pl["restrictedValue"]["passcodeKeyboardComplexity"] 16 | return pl["restrictedValue"]["passcodeKeyboardComplexity"]["value"] 17 | 18 | def bf_system(): 19 | curdir = os.path.dirname(os.path.abspath(__file__)) 20 | client = RamdiskToolClient() 21 | di = client.getDeviceInfos() 22 | devicedir = di["udid"] 23 | if os.getcwd().find(devicedir) == -1: 24 | try: 25 | os.mkdir(devicedir) 26 | except: 27 | pass 28 | os.chdir(devicedir) 29 | key835 = di.get("key835").decode("hex") 30 | 31 | systembag = client.getSystemKeyBag() 32 | kbkeys = systembag["KeyBagKeys"].data 33 | kb = Keybag.createWithDataSignBlob(kbkeys, key835) 34 | keybags = di.setdefault("keybags", {}) 35 | kbuuid = kb.uuid.encode("hex") 36 | print "Keybag UUID :", kbuuid 37 | if True and keybags.has_key(kbuuid) and keybags[kbuuid].has_key("passcodeKey"): 38 | print "We've already seen this keybag" 39 | passcodeKey = keybags[kbuuid].get("passcodeKey").decode("hex") 40 | print kb.unlockWithPasscodeKey(passcodeKey) 41 | kb.printClassKeys() 42 | else: 43 | keybags[kbuuid] = {"KeyBagKeys": systembag["KeyBagKeys"]} 44 | di["KeyBagKeys"] = systembag["KeyBagKeys"] 45 | di.save() 46 | print "Enter passcode or leave blank for bruteforce:" 47 | z = raw_input() 48 | res = client.getPasscodeKey(systembag["KeyBagKeys"].data, z) 49 | if kb.unlockWithPasscodeKey(res.get("passcodeKey").decode("hex")): 50 | print "Passcode \"%s\" OK" % z 51 | di.update(res) 52 | keybags[kbuuid].update(res) 53 | di.save() 54 | keychain_blob = client.downloadFile("/mnt2/Keychains/keychain-2.db") 55 | write_file("keychain-2.db", keychain_blob) 56 | print "Downloaded keychain database, use keychain_tool.py to decrypt secrets" 57 | return 58 | if z != "": 59 | print "Wrong passcode, trying to bruteforce !" 60 | if checkPasscodeComplexity(client) == 0: 61 | print "Trying all 4-digits passcodes..." 62 | bf = client.bruteforceKeyBag(systembag["KeyBagKeys"].data) 63 | if bf: 64 | di.update(bf) 65 | keybags[kbuuid].update(bf) 66 | print bf 67 | print kb.unlockWithPasscodeKey(bf.get("passcodeKey").decode("hex")) 68 | kb.printClassKeys() 69 | di["classKeys"] = kb.getClearClassKeysDict() 70 | di.save() 71 | else: 72 | print "Complex passcode used, trying dictionary attack ..." 73 | dictfile = os.path.join(curdir, 'wordlist.dict') 74 | try: 75 | wordlist = open(dictfile, 'r').readlines() 76 | except (OSError, IOError), e: 77 | exit(e) 78 | for line in wordlist: 79 | res = client.getPasscodeKey(systembag["KeyBagKeys"].data, line.rstrip('\n')) 80 | if kb.unlockWithPasscodeKey(res.get("passcodeKey").decode("hex")): 81 | print "Passcode \"%s\" OK" % line.rstrip('\n') 82 | di.update(res) 83 | keybags[kbuuid].update(res) 84 | di.save() 85 | keychain_blob = client.downloadFile("/mnt2/Keychains/keychain-2.db") 86 | write_file("keychain-2.db", keychain_blob) 87 | print "Downloaded keychain database, use keychain_tool.py to decrypt secrets" 88 | return 89 | print "Passcode not found!" 90 | return 91 | 92 | #keychain_blob = client.downloadFile("/private/var/Keychains/keychain-2.db") 93 | keychain_blob = client.downloadFile("/mnt2/Keychains/keychain-2.db") 94 | write_file("keychain-2.db", keychain_blob) 95 | print "Downloaded keychain database, use keychain_tool.py to decrypt secrets" 96 | 97 | bf_system() 98 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/demo_escrow.py: -------------------------------------------------------------------------------- 1 | import os 2 | import plistlib 3 | from keystore.keybag import Keybag 4 | from util.ramdiskclient import RamdiskToolClient 5 | 6 | """ 7 | this wont work on iOS 5 unless the passcode was already bruteforced 8 | """ 9 | def escrow(): 10 | client = RamdiskToolClient() 11 | di = client.getDeviceInfos() 12 | key835 = di.get("key835").decode("hex") 13 | 14 | plist = os.environ["ALLUSERSPROFILE"] + "/Apple/Lockdown/%s.plist" % di["udid"] 15 | lockdown = plistlib.readPlist(plist) 16 | kb = Keybag.createWithDataSignBlob(lockdown["EscrowBag"].data, key835) 17 | 18 | keybags = di.setdefault("keybags", {}) 19 | kbuuid = kb.uuid.encode("hex") 20 | if not keybags.has_key(kbuuid): 21 | print lockdown["HostID"] 22 | res = client.getEscrowRecord(lockdown["HostID"]) 23 | bagkey = res.get("BagKey") 24 | print "Bag key" + bagkey.data.encode("hex") 25 | res = client.getPasscodeKey(lockdown["EscrowBag"].data, bagkey) 26 | print res 27 | passcodeKey = res["passcodeKey"].decode("hex") 28 | keybags[kbuuid] = {"KeyBagKeys": lockdown["EscrowBag"], 29 | "passcode": bagkey, 30 | "passcodeKey": passcodeKey.encode("hex")} 31 | pl.update(keybags[kbuuid]) 32 | else: 33 | passcodeKey = keybags[kbuuid].get("passcodeKey").decode("hex") 34 | 35 | print kb.unlockWithPasscodeKey(passcodeKey) 36 | kb.printClassKeys() 37 | 38 | escrow() -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/emf_decrypter.py: -------------------------------------------------------------------------------- 1 | from optparse import OptionParser 2 | from hfs.emf import EMFVolume 3 | from util.bdev import FileBlockDevice 4 | import plistlib 5 | 6 | def main(): 7 | parser = OptionParser(usage="emf_decrypter.py disk_image.bin") 8 | parser.add_option("-w", "--nowrite", dest="write", action="store_false", default=True, 9 | help="disable modifications of input file, for testing") 10 | (options, args) = parser.parse_args() 11 | if len(args) < 1: 12 | parser.print_help() 13 | return 14 | device_infos = None 15 | if len(args) >= 2: device_infos = plistlib.readPlist(args[1]) 16 | 17 | p = FileBlockDevice(args[0], 0, options.write) 18 | v = EMFVolume(p, device_infos) 19 | if not v.keybag.unlocked: 20 | print "Keybag locked, protected files won't be decrypted, continue anyway ?" 21 | if raw_input() == "n": 22 | return 23 | if options.write: 24 | print "WARNING ! This tool will modify the hfs image and possibly wreck it if something goes wrong !" 25 | print "Make sure to backup the image before proceeding" 26 | print "You can use the --nowrite option to do a dry run instead" 27 | else: 28 | print "Test mode : the input file will not be modified" 29 | print "Press a key to continue or CTRL-C to abort" 30 | raw_input() 31 | v.decryptAllFiles() 32 | 33 | if __name__ == "__main__": 34 | main() 35 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/emf_undelete.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from hfs.emf import EMFVolume 4 | from hfs.journal import do_emf_carving 5 | from util.bdev import FileBlockDevice 6 | 7 | if __name__ == "__main__": 8 | if len(sys.argv) < 2: 9 | print "Usage: emf_undelete.py disk_image.bin" 10 | sys.exit(0) 11 | filename = sys.argv[1] 12 | volume = EMFVolume(FileBlockDevice(filename), None) 13 | dirname = os.path.dirname(filename) 14 | if dirname == "": 15 | dirname = "." 16 | outdir = dirname + "/" + volume.volumeID().encode("hex") + "_" + os.path.basename(filename) 17 | carveokdir = outdir + "/undelete/" 18 | carvenokdir = outdir + "/junk/" 19 | try: 20 | os.makedirs(carveokdir) 21 | os.makedirs(carvenokdir) 22 | except: 23 | pass 24 | 25 | do_emf_carving(volume, carveokdir, carvenokdir) 26 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/firmware/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/ios-integrity-validator/2090e6321cd313493c6f3746866411d865cde6ab/vendor/iphone-dataprotection/python_scripts/firmware/__init__.py -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/firmware/img2.py: -------------------------------------------------------------------------------- 1 | from construct.core import Struct 2 | from construct.macros import * 3 | 4 | IMG2 = Struct("IMG2", 5 | String("magic",4), 6 | ULInt32("block_size"), 7 | ULInt32("images_offset"), 8 | ULInt32("images_block"), 9 | ULInt32("images_length"), 10 | Padding(0x1C), 11 | ULInt32("crc32"), 12 | ) -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/firmware/scfg.py: -------------------------------------------------------------------------------- 1 | from construct.core import Struct 2 | from construct.macros import * 3 | from construct import RepeatUntil, OneOf 4 | from util import hexdump 5 | 6 | SCFGItem = Struct("SCFGItem", 7 | String("tag", 4), 8 | String("data", 16, padchar="\x00") 9 | ) 10 | 11 | SCFG = Struct("SCFG", 12 | OneOf(String("magic", 4), ["gfCS"]), 13 | ULInt32("length"), 14 | ULInt32("unk1"), 15 | ULInt32("unk2"), 16 | ULInt32("unk3"), 17 | ULInt32("unk4") 18 | ) 19 | 20 | def parse_SCFG(data): 21 | res = {} 22 | scfg = SCFG.parse(data) 23 | assert scfg.length > 0x18 24 | for i in Array((scfg.length - 0x18) / 20, SCFGItem).parse(data[0x18:scfg.length]): 25 | if i.tag != "\xFF\xFF\xFF\xFF": 26 | res[str(i.tag)[::-1]] = str(i.data) 27 | return res 28 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/hfs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/ios-integrity-validator/2090e6321cd313493c6f3746866411d865cde6ab/vendor/iphone-dataprotection/python_scripts/hfs/__init__.py -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/hfs/journal.py: -------------------------------------------------------------------------------- 1 | from crypto.aes import AESencryptCBC, AESdecryptCBC 2 | from emf import cprotect_xattr, EMFFile 3 | from structs import * 4 | from util import write_file, sizeof_fmt 5 | import hashlib 6 | 7 | """ 8 | Implementation of the following paper : 9 | Using the HFS+ Journal For Deleted File Recovery. Aaron Burghardt, Adam Feldman. DFRWS 2008 10 | http://www.dfrws.org/2008/proceedings/p76-burghardt.pdf 11 | http://www.dfrws.org/2008/proceedings/p76-burghardt_pres.pdf 12 | """ 13 | 14 | def carveBtreeNode(node, kClass, dClass): 15 | try: 16 | btnode = BTNodeDescriptor.parse(node) 17 | 18 | if btnode.kind == kBTLeafNode: 19 | off = BTNodeDescriptor.sizeof() 20 | recs = [] 21 | offsets = Array(btnode.numRecords, UBInt16("off")).parse(node[-2*btnode.numRecords:]) 22 | for i in xrange(btnode.numRecords): 23 | off = offsets[btnode.numRecords-i-1] 24 | k = kClass.parse(node[off:]) 25 | off += 2 + k.keyLength 26 | d = dClass.parse(node[off:]) 27 | recs.append((k,d)) 28 | return recs 29 | return [] 30 | except: 31 | return [] 32 | 33 | """ 34 | for standard HFS volumes 35 | """ 36 | def carveHFSVolumeJournal(volume): 37 | journal = volume.readJournal() 38 | hdr = journal_header.parse(journal) 39 | sector_size = hdr.jhdr_size 40 | nodeSize = volume.catalogTree.nodeSize 41 | 42 | f={} 43 | for i in xrange(0,len(journal), sector_size): 44 | for k,v in carveBtreeNode(journal[i:i+nodeSize],HFSPlusCatalogKey, HFSPlusCatalogData): 45 | if v.recordType == kHFSPlusFileRecord: 46 | name = getString(k) 47 | h = hashlib.sha1(HFSPlusCatalogKey.build(k)).digest() 48 | if f.has_key(h): 49 | continue 50 | if volume.catalogTree.searchByCNID(v.data.fileID) == (None, None): 51 | if volume.isBlockInUse(v.data.dataFork.HFSPlusExtentDescriptor[0].startBlock) == False: 52 | print "deleted file", v.data.fileID, name 53 | fileid = v.data.fileID 54 | f[h]=(name, v) 55 | return f.values() 56 | 57 | 58 | magics=["SQLite", "bplist", "= 4: 11 | return Keychain4(filename, keybag) 12 | raise Exception("Unknown keychain version %d" % version) 13 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/keychain/keychain3.py: -------------------------------------------------------------------------------- 1 | from keychain import Keychain 2 | from crypto.aes import AESdecryptCBC, AESencryptCBC 3 | import hashlib 4 | 5 | class Keychain3(Keychain): 6 | def __init__(self, filename, key835=None): 7 | Keychain.__init__(self, filename) 8 | self.key835 = key835 9 | 10 | def decrypt_data(self, data): 11 | if data == None: 12 | return "" 13 | data = str(data) 14 | 15 | if not self.key835: 16 | print "Key 835 not availaible" 17 | return "" 18 | 19 | data = AESdecryptCBC(data[16:], self.key835, data[:16], padding=True) 20 | 21 | #data_column = iv + AES128_K835(iv, data + sha1(data)) 22 | if hashlib.sha1(data[:-20]).digest() != data[-20:]: 23 | print "data field hash mismatch : bad key ?" 24 | return "ERROR decrypting data : bad key ?" 25 | 26 | return data[:-20] 27 | 28 | def change_key835(self, newkey): 29 | tables = {"genp": "SELECT rowid, data FROM genp", 30 | "inet": "SELECT rowid, data FROM inet", 31 | "cert": "SELECT rowid, data FROM cert", 32 | "keys": "SELECT rowid, data FROM keys"} 33 | 34 | for t in tables.keys(): 35 | for row in self.conn.execute(tables[t]): 36 | rowid = row["rowid"] 37 | data = str(row["data"]) 38 | iv = data[:16] 39 | data = AESdecryptCBC(data[16:], self.key835, iv) 40 | data = AESencryptCBC(data, newkey, iv) 41 | data = iv + data 42 | data = buffer(data) 43 | self.conn.execute("UPDATE %s SET data=? WHERE rowid=?" % t, (data, rowid)) 44 | self.conn.commit() -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/keychain/keychain4.py: -------------------------------------------------------------------------------- 1 | from crypto.aes import AESdecryptCBC 2 | import struct 3 | 4 | """ 5 | iOS 4 keychain-2.db data column format 6 | 7 | version 0x00000000 8 | key class 0x00000008 9 | kSecAttrAccessibleWhenUnlocked 6 10 | kSecAttrAccessibleAfterFirstUnlock 7 11 | kSecAttrAccessibleAlways 8 12 | kSecAttrAccessibleWhenUnlockedThisDeviceOnly 9 13 | kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly 10 14 | kSecAttrAccessibleAlwaysThisDeviceOnly 11 15 | wrapped AES256 key 0x28 bytes (passed to kAppleKeyStoreKeyUnwrap) 16 | encrypted data (AES 256 CBC zero IV) 17 | """ 18 | from keychain import Keychain 19 | from crypto.gcm import gcm_decrypt 20 | from util.bplist import BPlistReader 21 | 22 | KSECATTRACCESSIBLE = { 23 | 6: "kSecAttrAccessibleWhenUnlocked", 24 | 7: "kSecAttrAccessibleAfterFirstUnlock", 25 | 8: "kSecAttrAccessibleAlways", 26 | 9: "kSecAttrAccessibleWhenUnlockedThisDeviceOnly", 27 | 10: "kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly", 28 | 11: "kSecAttrAccessibleAlwaysThisDeviceOnly" 29 | } 30 | 31 | class Keychain4(Keychain): 32 | def __init__(self, filename, keybag): 33 | if not keybag.unlocked: 34 | print "Keychain object created with locked keybag, some items won't be decrypted" 35 | Keychain.__init__(self, filename) 36 | self.keybag = keybag 37 | 38 | def decrypt_item(self, row): 39 | version, clas = struct.unpack("= 9 and not self.keybag.deviceKey: 42 | return {} 43 | if version >= 2: 44 | dict = self.decrypt_blob(row["data"]) 45 | if not dict: 46 | return {"clas": clas, "rowid": row["rowid"]} 47 | if dict.has_key("v_Data"): 48 | dict["data"] = dict["v_Data"].data 49 | else: 50 | dict["data"] = "" 51 | dict["rowid"] = row["rowid"] 52 | dict["clas"] = clas 53 | return dict 54 | row["clas"] = clas 55 | return Keychain.decrypt_item(self, row) 56 | 57 | def decrypt_data(self, data): 58 | data = self.decrypt_blob(data) 59 | if type(data) == dict: 60 | return data["v_Data"].data 61 | return data 62 | 63 | def decrypt_blob(self, blob): 64 | if blob == None: 65 | return "" 66 | 67 | if len(blob) < 48: 68 | print "keychain blob length must be >= 48" 69 | return 70 | 71 | version, clas = struct.unpack(" gpt.current_lba 94 | check = gpt.crc 95 | gpt.crc = 0 96 | actual = crc32(GPT_header.build(gpt)) 97 | if actual != check: 98 | print "GPT crc check fail %d vs %d" % (actual, check) 99 | return None 100 | return gpt 101 | 102 | def parse_lwvm(data, pageSize): 103 | try: 104 | hdr = LWVM_header.parse(data) 105 | if hdr.type != LWVM_MAGIC: 106 | print "LwVM magic mismatch" 107 | return 108 | tocheck = data[:44] + "\x00\x00\x00\x00" + data[48:0x1000] 109 | check = crc32(tocheck) & 0xffffffff 110 | if check != hdr.crc32: 111 | return None 112 | print "LwVM header CRC OK" 113 | partitions = hdr.LWVM_partitionRecord[:hdr.numPartitions] 114 | deviceSize=0 115 | #XXX: HAAAAAAAX 116 | for s in [8, 16, 32, 64, 128]: 117 | if hdr.mediaSize < (s* 1024*1024*1024): 118 | deviceSize = s 119 | break 120 | for i in xrange(len(hdr.chunks)): 121 | if hdr.chunks[i] == 0x0: 122 | lba0 = (i * deviceSize*1024*1024) / pageSize 123 | partitions[0].first_lba = lba0 124 | partitions[0].last_lba = lba0 + (partitions[0].end - partitions[0].begin) / pageSize 125 | elif hdr.chunks[i] == 0x1000: 126 | lbad = (i * deviceSize*1024*1024) / pageSize 127 | partitions[1].first_lba = lbad 128 | partitions[1].last_lba = lbad + (partitions[1].end - partitions[1].begin) / pageSize 129 | return partitions 130 | except: 131 | return None 132 | 133 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/nand/remote.py: -------------------------------------------------------------------------------- 1 | from progressbar import ProgressBar 2 | from usbmux import usbmux 3 | from util import hexdump, sizeof_fmt 4 | import datetime 5 | import hashlib 6 | import struct 7 | import os 8 | 9 | CMD_DUMP = 0 10 | CMD_PROXY = 1 11 | kIOFlashStorageOptionRawPageIO = 0x002 12 | kIOFlashStorageOptionBootPageIO = 0x100 13 | 14 | class IOFlashStorageKitClient(object): 15 | def __init__(self, udid=None, host="localhost", port=2000): 16 | self.host = host 17 | self.port = port 18 | self.connect(udid) 19 | 20 | def connect(self, udid=None): 21 | mux = usbmux.USBMux() 22 | mux.process(1.0) 23 | if not mux.devices: 24 | print "Waiting for iOS device" 25 | while not mux.devices: 26 | mux.process(1.0) 27 | if not mux.devices: 28 | print "No device found" 29 | return 30 | dev = mux.devices[0] 31 | try: 32 | self.s = mux.connect(dev, self.port) 33 | except: 34 | raise Exception("Connexion to device %s port %d failed" % (dev.serial, self.port)) 35 | 36 | def send_command(self, cmd): 37 | return self.s.send(struct.pack("= 1099511627776: 70 | terabytes = bytes / 1099511627776 71 | size = '%.2fT' % terabytes 72 | elif bytes >= 1073741824: 73 | gigabytes = bytes / 1073741824 74 | size = '%.2fG' % gigabytes 75 | elif bytes >= 1048576: 76 | megabytes = bytes / 1048576 77 | size = '%.2fM' % megabytes 78 | elif bytes >= 1024: 79 | kilobytes = bytes / 1024 80 | size = '%.2fK' % kilobytes 81 | else: 82 | size = '%.2fb' % bytes 83 | return size 84 | 85 | def xor_strings(a,b): 86 | r="" 87 | for i in xrange(len(a)): 88 | r+= chr(ord(a[i])^ord(b[i])) 89 | return r 90 | 91 | hex = lambda data: " ".join("%02X" % ord(i) for i in data) 92 | ascii = lambda data: "".join(c if 31 < ord(c) < 127 else "." for c in data) 93 | 94 | def hexdump(d): 95 | for i in xrange(0,len(d),16): 96 | data = d[i:i+16] 97 | print "%08X | %s | %s" % (i, hex(data).ljust(47), ascii(data)) 98 | 99 | def search_plist(directory, matchDict): 100 | for p in map(os.path.normpath, glob.glob(directory + "/*.plist")): 101 | try: 102 | d = plistlib.readPlist(p) 103 | ok = True 104 | for k,v in matchDict.items(): 105 | if d.get(k) != v: 106 | ok = False 107 | break 108 | if ok: 109 | print "Using plist file %s" % p 110 | return d 111 | except: 112 | continue 113 | 114 | def save_pickle(filename,data): 115 | f = gzip.open(filename,"wb") 116 | cPickle.dump(data, f, cPickle.HIGHEST_PROTOCOL) 117 | f.close() 118 | 119 | def load_pickle(filename): 120 | f = gzip.open(filename,"rb") 121 | data = cPickle.load(f) 122 | f.close() 123 | return data 124 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/util/asciitables.py: -------------------------------------------------------------------------------- 1 | 2 | def print_table(title, headers, rows): 3 | widths = [] 4 | 5 | for i in xrange(len(headers)): 6 | z = map(len, [str(row[i]) for row in rows]) 7 | z.append(len(headers[i])) 8 | widths.append(max(z)) 9 | 10 | width = sum(widths) + len(headers) + 1 11 | print "-"* width 12 | print "|" + title.center(width-2) + "|" 13 | print "-"* width 14 | hline = "|" 15 | for i in xrange(len(headers)): 16 | hline += headers[i].ljust(widths[i]) + "|" 17 | print hline 18 | 19 | print "-"* width 20 | for row in rows: 21 | line = "|" 22 | for i in xrange(len(row)): 23 | line += str(row[i]).ljust(widths[i]) + "|" 24 | print line 25 | 26 | if len(rows) == 0: 27 | print "|" + "No entries".center(width-2) + "|" 28 | print "-"* width 29 | print "" 30 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/util/bdev.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from util import sizeof_fmt, hexdump 4 | from progressbar import ProgressBar 5 | from crypto.aes import AESdecryptCBC, AESencryptCBC 6 | 7 | class FileBlockDevice(object): 8 | def __init__(self, filename, offset=0, write=False): 9 | flag = os.O_RDONLY if not write else os.O_RDWR 10 | if sys.platform == 'win32': 11 | flag = flag | os.O_BINARY 12 | self.filename = filename 13 | self.fd = os.open(filename, flag) 14 | self.offset = offset 15 | self.writeFlag = write 16 | self.size = os.path.getsize(filename) 17 | self.setBlockSize(8192) 18 | 19 | def setBlockSize(self, bs): 20 | self.blockSize = bs 21 | self.nBlocks = self.size / bs 22 | 23 | def readBlock(self, blockNum): 24 | os.lseek(self.fd, self.offset + self.blockSize * blockNum, os.SEEK_SET) 25 | return os.read(self.fd, self.blockSize) 26 | 27 | def write(self, offset, data): 28 | if self.writeFlag: #fail silently for testing 29 | os.lseek(self.fd, self.offset + offset, os.SEEK_SET) 30 | return os.write(self.fd, data) 31 | 32 | def writeBlock(self, lba, block): 33 | return self.write(lba*self.blockSize, block) 34 | 35 | class FTLBlockDevice(object): 36 | def __init__(self, nand, first_lba, last_lba, defaultKey=None): 37 | self.nand = nand 38 | self.pageSize = nand.pageSize 39 | self.blockSize = 0 #not used 40 | self.key = defaultKey 41 | self.lbaoffset = first_lba 42 | self.last_lba = last_lba 43 | self.setBlockSize(self.pageSize) 44 | 45 | def setBlockSize(self, bs): 46 | self.blockSize = bs 47 | self.lbasPerPage = self.pageSize / bs 48 | self.lbaToLpnFactor = bs / (self.pageSize+0.0) 49 | self.pagesPerLBA = bs / self.pageSize 50 | if bs > self.pageSize: 51 | pass#raise Exception("FTLBlockDevice lba-size > pageSize not handled") 52 | 53 | def readBlock(self, blockNum): 54 | #if (self.lbaoffset + blockNum / self.lbasPerPage) > self.last_lba: 55 | # print "readBlock past last lba", blockNum 56 | # print "readBlock past last lba", blockNum 57 | # return "\x00" * self.blockSize 58 | lpn = int(self.lbaoffset + blockNum * self.lbaToLpnFactor) 59 | d = self.nand.readLPN(lpn, self.key) 60 | for i in xrange(1, self.pagesPerLBA): 61 | d += self.nand.readLPN(lpn + i, self.key) 62 | if self.lbasPerPage: 63 | zz = blockNum % self.lbasPerPage 64 | return d[zz*self.blockSize:(zz+1)*self.blockSize] 65 | return d 66 | 67 | def write(self, offset, data): 68 | raise Exception("FTLBlockDevice write method not implemented") 69 | 70 | def writeBlock(self, lba, block): 71 | raise Exception("FTLBlockDevice writeBlock method not implemented") 72 | 73 | def dumpToFile(self, outputfilename): 74 | hs = sizeof_fmt((self.last_lba - self.lbaoffset) * self.pageSize) 75 | print "Dumping partition to %s (%s)" % (outputfilename, hs) 76 | flags = os.O_CREAT | os.O_RDWR 77 | if sys.platform == "win32": 78 | flags |= os.O_BINARY 79 | fd=os.open(outputfilename, flags) 80 | 81 | pbar = ProgressBar(self.last_lba - self.lbaoffset - 1) 82 | pbar.start() 83 | for i in xrange(self.lbaoffset, self.last_lba): 84 | pbar.update(i-self.lbaoffset) 85 | d = self.nand.readLPN(i, self.key) 86 | if i == self.lbaoffset and d[0x400:0x402] != "HX": 87 | print "FAIL? Not HFS partition or wrong key" 88 | os.write(fd, d) 89 | pbar.finish() 90 | os.close(fd) 91 | 92 | class IMG3BlockDevice(object): 93 | def __init__(self, filename, key, iv, write=False): 94 | flag = os.O_RDONLY if not write else os.O_RDWR 95 | if sys.platform == 'win32': 96 | flag = flag | os.O_BINARY 97 | self.filename = filename 98 | self.fd = os.open(filename, flag) 99 | self.writeFlag = write 100 | d = os.read(self.fd, 8192) 101 | if d[:4] != "3gmI": 102 | raise Exception("IMG3BlockDevice bad magic %s" % d[:4]) 103 | if d[0x34:0x38] != "ATAD": 104 | raise Exception("Fu") 105 | self.encrypted = True 106 | self.key = key 107 | self.iv0 = iv 108 | self.offset = 0x40 109 | self.size = os.path.getsize(filename) 110 | self.setBlockSize(8192) 111 | 112 | def setBlockSize(self, bs): 113 | self.blockSize = bs 114 | self.nBlocks = self.size / bs 115 | self.ivs = {0: self.iv0} 116 | 117 | def getIVforBlock(self, blockNum): 118 | #read last 16 bytes of previous block to get IV 119 | if not self.ivs.has_key(blockNum): 120 | os.lseek(self.fd, self.offset + self.blockSize * blockNum - 16, os.SEEK_SET) 121 | self.ivs[blockNum] = os.read(self.fd, 16) 122 | return self.ivs[blockNum] 123 | 124 | def readBlock(self, blockNum): 125 | os.lseek(self.fd, self.offset + self.blockSize * blockNum, os.SEEK_SET) 126 | data = os.read(self.fd, self.blockSize) 127 | if self.encrypted: 128 | data = AESdecryptCBC(data, self.key, self.getIVforBlock(blockNum)) 129 | return data 130 | 131 | def _write(self, offset, data): 132 | if self.writeFlag: #fail silently for testing 133 | os.lseek(self.fd, self.offset + offset, os.SEEK_SET) 134 | return os.write(self.fd, data) 135 | 136 | def writeBlock(self, lba, data): 137 | if self.encrypted: 138 | data = AESencryptCBC(data, self.key, self.getIVforBlock(lba)) 139 | return self._write(lba*self.blockSize, data) 140 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/util/bruteforce.py: -------------------------------------------------------------------------------- 1 | from keystore.keybag import Keybag 2 | from keystore.effaceable import EffaceableLockers 3 | from util.ramdiskclient import RamdiskToolClient 4 | import plistlib 5 | 6 | COMPLEXITY={ 7 | 0: "4 digits", 8 | 1: "n digits", 9 | 2: "n alphanum" 10 | } 11 | 12 | def checkPasscodeComplexity(data_volume): 13 | pl = data_volume.readFile("/mobile/Library/ConfigurationProfiles/UserSettings.plist", returnString=True) 14 | if not pl: 15 | print "Failed to read UserSettings.plist, assuming simple passcode" 16 | return 0 17 | pl = plistlib.readPlistFromString(pl) 18 | #print "passcodeKeyboardComplexity :", pl["restrictedValue"]["passcodeKeyboardComplexity"] 19 | value = pl["restrictedValue"]["passcodeKeyboardComplexity"]["value"] 20 | print "passcodeKeyboardComplexity %d => %s" % (value, COMPLEXITY.get(value)) 21 | return pl["restrictedValue"]["passcodeKeyboardComplexity"]["value"] 22 | 23 | def loadKeybagFromVolume(volume, device_infos): 24 | systembag = volume.readFile("/keybags/systembag.kb", returnString=True) 25 | if not systembag or not systembag.startswith("bplist"): 26 | print "FAIL: could not read /keybags/systembag.kb from data partition" 27 | return False 28 | lockers = EffaceableLockers(device_infos["lockers"].data) 29 | bag1key = lockers.get("BAG1")[-32:] 30 | keybag = Keybag.createWithSystemkbfile(systembag, bag1key, device_infos.get("key835", "").decode("hex")) 31 | keybag.setDKey(device_infos) 32 | if device_infos.has_key("passcodeKey"): 33 | keybag.unlockWithPasscodeKey(device_infos.get("passcodeKey").decode("hex")) 34 | return keybag 35 | 36 | def bruteforcePasscode(device_infos, data_volume): 37 | if device_infos.has_key("passcode"): 38 | print "Passcode already found, no bruteforce required" 39 | return False 40 | kb = data_volume.keybag 41 | if not kb: 42 | return False 43 | 44 | rd = RamdiskToolClient.get() 45 | if rd.device_infos.udid != device_infos.udid: 46 | print "Wrong device connected" 47 | return 48 | 49 | print "Enter passcode or leave blank for bruteforce:" 50 | z = raw_input() 51 | bf = rd.getPasscodeKey(kb.KeyBagKeys, z) 52 | if kb.unlockWithPasscodeKey(bf.get("passcodeKey").decode("hex")): 53 | print "Passcode \"%s\" OK" % z 54 | else: 55 | if z != "": 56 | print "Wrong passcode, trying to bruteforce !" 57 | if checkPasscodeComplexity(data_volume) != 0: 58 | print "Complex passcode used, not bruteforcing" 59 | return False 60 | 61 | bf = rd.bruteforceKeyBag(kb.KeyBagKeys) 62 | if bf and kb.unlockWithPasscodeKey(bf.get("passcodeKey").decode("hex")): 63 | print "Bruteforce successful, passcode : %s" % bf["passcode"] 64 | print "Passcode key : %s" % bf.get("passcodeKey") 65 | if kb.unlocked: 66 | device_infos.update(bf) 67 | device_infos["classKeys"] = kb.getClearClassKeysDict() 68 | device_infos["KeyBagKeys"] = plistlib.Data(kb.KeyBagKeys) 69 | return True 70 | return False 71 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/util/cert.py: -------------------------------------------------------------------------------- 1 | import base64 2 | 3 | def chunks(l, n): 4 | return (l[i:i+n] for i in xrange(0, len(l), n)) 5 | 6 | def RSA_KEY_DER_to_PEM(data): 7 | a = ["-----BEGIN RSA PRIVATE KEY-----"] 8 | a.extend(chunks(base64.b64encode(data),64)) 9 | a.append("-----END RSA PRIVATE KEY-----") 10 | return "\n".join(a) 11 | 12 | def CERT_DER_to_PEM(data): 13 | a = ["-----BEGIN CERTIFICATE-----"] 14 | a.extend(chunks(base64.b64encode(data),64)) 15 | a.append("-----END CERTIFICATE-----") 16 | return "\n".join(a) -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/util/lzss.py: -------------------------------------------------------------------------------- 1 | """ 2 | /************************************************************** 3 | LZSS.C -- A Data Compression Program 4 | *************************************************************** 5 | 4/6/1989 Haruhiko Okumura 6 | Use, distribute, and modify this program freely. 7 | Please send me your improved versions. 8 | PC-VAN SCIENCE 9 | NIFTY-Serve PAF01022 10 | CompuServe 74050,1022 11 | 12 | **************************************************************/ 13 | /* 14 | * lzss.c - Package for decompressing lzss compressed objects 15 | * 16 | * Copyright (c) 2003 Apple Computer, Inc. 17 | * 18 | * DRI: Josh de Cesare 19 | */ 20 | """ 21 | from array import array 22 | import struct 23 | 24 | N = 4096 25 | F = 18 26 | THRESHOLD = 2 27 | NIL = N 28 | 29 | def decompress_lzss(str): 30 | if str[:8] !="complzss": 31 | print "decompress_lzss: complzss magic missing" 32 | return 33 | decompsize = struct.unpack(">L", str[12:16])[0] 34 | text_buf = array("B", " "*(N + F - 1)) 35 | src = array("B", str[0x180:]) 36 | srclen = len(src) 37 | dst = array("B", " "*decompsize) 38 | r = N - F 39 | srcidx, dstidx, flags, c = 0, 0, 0, 0 40 | 41 | while True: 42 | flags >>= 1 43 | if ((flags & 0x100) == 0): 44 | if (srcidx >= srclen): 45 | break 46 | c = src[srcidx]; srcidx += 1 47 | flags = c | 0xFF00; 48 | 49 | if (flags & 1): 50 | if (srcidx >= srclen): 51 | break 52 | c = src[srcidx]; srcidx += 1 53 | dst[dstidx] = c; dstidx += 1 54 | text_buf[r] = c; r += 1 55 | r &= (N - 1); 56 | else: 57 | if (srcidx >= srclen): 58 | break 59 | i = src[srcidx]; srcidx += 1 60 | if (srcidx >= srclen): 61 | break 62 | j = src[srcidx]; srcidx += 1 63 | i |= ((j & 0xF0) << 4) 64 | j = (j & 0x0F) + THRESHOLD 65 | for k in xrange(j+1): 66 | c = text_buf[(i + k) & (N - 1)] 67 | dst[dstidx] = c; dstidx += 1 68 | text_buf[r] = c; r += 1 69 | r &= (N - 1) 70 | return dst.tostring() 71 | 72 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/util/ramdiskclient.py: -------------------------------------------------------------------------------- 1 | import plistlib 2 | import struct 3 | import socket 4 | from datetime import datetime 5 | from progressbar import ProgressBar, Percentage, Bar, SimpleProgress, ETA 6 | from usbmux import usbmux 7 | from util import sizeof_fmt 8 | 9 | kIOAESAcceleratorEncrypt = 0 10 | kIOAESAcceleratorDecrypt = 1 11 | 12 | kIOAESAcceleratorGIDMask = 0x3E8 13 | kIOAESAcceleratorUIDMask = 0x7D0 14 | 15 | 16 | class DeviceInfo(dict): 17 | @staticmethod 18 | def create(dict): 19 | try: 20 | assert dict.has_key("dataVolumeUUID") 21 | filename = "%s.plist" % dict.get("dataVolumeUUID") 22 | return DeviceInfo(plistlib.readPlist(filename)) 23 | except: 24 | return DeviceInfo(dict) 25 | 26 | def save(self): 27 | filename = "%s.plist" % self.get("dataVolumeUUID", "unk") 28 | plistlib.writePlist(self, filename) 29 | 30 | #stop doing magic stuff 31 | #def __del__(self): 32 | # self.save() 33 | 34 | class RamdiskToolClient(object): 35 | instance = None 36 | @staticmethod 37 | def get(): 38 | if not RamdiskToolClient.instance: 39 | RamdiskToolClient.instance = RamdiskToolClient() 40 | return RamdiskToolClient.instance 41 | 42 | def __init__(self, udid=None, host="localhost", port=1999): 43 | self.host = host 44 | self.port = port 45 | self.device_infos = {} 46 | self.s = None 47 | self.connect(udid) 48 | self.getDeviceInfos() 49 | 50 | def close(self): 51 | if self.s: 52 | self.s.close() 53 | self.s = None 54 | 55 | def connect(self, udid=None): 56 | mux = usbmux.USBMux() 57 | mux.process(1.0) 58 | if not mux.devices: 59 | print "Waiting for iOS device" 60 | while not mux.devices: 61 | mux.process(1.0) 62 | if not mux.devices: 63 | print "No device found" 64 | return 65 | dev = mux.devices[0] 66 | print "Connecting to device : " + dev.serial 67 | try: 68 | self.s = mux.connect(dev, self.port) 69 | except: 70 | raise Exception("Connexion to device port %d failed" % self.port) 71 | 72 | def getDeviceInfos(self): 73 | self.device_infos = self.send_req({"Request":"DeviceInfo"}) 74 | keys = self.grabDeviceKeys() 75 | if keys: 76 | self.device_infos.update(keys) 77 | return DeviceInfo.create(self.device_infos) 78 | 79 | def downloadFile(self, path): 80 | res = self.send_req({"Request": "DownloadFile", 81 | "Path": path}) 82 | if type(res) == plistlib._InternalDict and res.has_key("Data"): 83 | return res["Data"].data 84 | 85 | def getSystemKeyBag(self): 86 | return self.send_req({"Request":"GetSystemKeyBag"}) 87 | 88 | def bruteforceKeyBag(self, KeyBagKeys): 89 | return self.send_req({"Request":"BruteforceSystemKeyBag", 90 | "KeyBagKeys": plistlib.Data(KeyBagKeys)}) 91 | 92 | def getEscrowRecord(self, hostID): 93 | return self.send_req({"Request":"GetEscrowRecord", 94 | "HostID": hostID}) 95 | 96 | def getPasscodeKey(self, keybagkeys, passcode): 97 | return self.send_req({"Request":"KeyBagGetPasscodeKey", 98 | "KeyBagKeys": plistlib.Data(keybagkeys), 99 | "passcode": passcode}) 100 | 101 | def send_msg(self, dict): 102 | plist = plistlib.writePlistToString(dict) 103 | data = struct.pack("L",blob[i+4:i+8])[0] 17 | data = blob[i+8:i+8+length] 18 | yield (tag,data) 19 | i += 8 + length -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/windows_redsn0w_keys.py: -------------------------------------------------------------------------------- 1 | #HAX 2 | 3 | d=open("redsn0w_win_0.9.9b4/redsn0w.exe", "rb").read() 4 | 5 | i = d.find("IV") 6 | i = d.rfind("", i) 8 | 9 | assert i != -1 10 | assert j != -1 11 | 12 | open("Keys.plist", "wb").write(d[i:j+8]) 13 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/python_scripts/wordlist.dict: -------------------------------------------------------------------------------- 1 | 12345 2 | 123456 3 | 123456 4 | 1234567 5 | 12345678 6 | 123456789 7 | 1234567890 8 | 09876 9 | 098765 10 | 0987654 11 | 09876543 12 | 098765432 13 | 0987654321 14 | abcd 15 | abcd1 16 | abcde 17 | abcde1 18 | abcdef 19 | abcdef1 20 | abcdefg 21 | abcdefg1 22 | qwer 23 | qwer1 24 | qwert 25 | qwert1 26 | qwertz 27 | qwertz1 28 | asdf 29 | asdfg 30 | asdfg1 31 | asdfgh 32 | asdfgh1 33 | yxcv 34 | yxcv1 35 | yxcvb 36 | yxcvb1 37 | yxcvbn 38 | yxcvbn1 39 | yxcvbnm 40 | yxcvbnm1 41 | mnbv 42 | mnbv1 43 | mnbvc 44 | mnbvc1 45 | mnbvcx 46 | mnbvcx1 47 | mnbvcxy 48 | mnbvcxy1 -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/ios-integrity-validator/2090e6321cd313493c6f3746866411d865cde6ab/vendor/iphone-dataprotection/ramdisk_tools/.DS_Store -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/AppleEffaceableStorage.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "AppleEffaceableStorage.h" 6 | #include "IOKit.h" 7 | 8 | int AppleEffaceableStorage__getLocker(uint32_t lockerId, uint8_t* buffer, size_t len) { 9 | uint64_t outScalar = 0; 10 | uint32_t one = 1; 11 | uint64_t inScalar = lockerId; 12 | 13 | return IOKit_call("AppleEffaceableStorage", 14 | kAppleEffaceableStorageGetLocker, 15 | &inScalar, 16 | 1, 17 | NULL, 18 | 0, 19 | &outScalar, 20 | &one, 21 | buffer, 22 | &len); 23 | } 24 | 25 | int AppleEffaceableStorage__getBytes(uint8_t* buffer, size_t len) 26 | { 27 | const uint64_t offset = 0; 28 | 29 | return IOKit_call("AppleEffaceableStorage", 30 | kAppleEffaceableStorageGetBytes, 31 | &offset, 32 | 1, 33 | NULL, 34 | 0, 35 | NULL, 36 | NULL, 37 | buffer, 38 | &len); 39 | } 40 | 41 | 42 | int AppleEffaceableStorage__getLockerFromBytes(uint32_t tag, uint8_t* lockers, size_t lockers_len, uint8_t* buffer, size_t len) 43 | { 44 | struct EffaceableLocker* p = (struct EffaceableLocker*) lockers; 45 | unsigned int i=0; 46 | 47 | while (i < lockers_len) 48 | { 49 | //printf("p->magic=%x\n", p->magic); 50 | if (p->magic != 'Lk') //0x4c6B 51 | break; 52 | if (p->len == 0 || ((i+8+p->len) > lockers_len)) 53 | break; 54 | //printf("p->tag=%x\n", p->tag); 55 | if ((p->tag & ~0x80000000) == tag) 56 | { 57 | len = len < p->len ? len : p->len; 58 | memcpy(buffer, p->data, len); 59 | return 0; 60 | } 61 | i = i + 8 + p->len; 62 | p = (struct EffaceableLocker*) (&lockers[i]); 63 | } 64 | return -1; 65 | 66 | } 67 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/AppleEffaceableStorage.h: -------------------------------------------------------------------------------- 1 | /* 2 | AppleEffaceableStorage 3 | 0 : getCapacity 4 | 1 : getBytes (kernel debug) 5 | 2 : setBytes (kernel debug) 6 | 3 : isFormatted 7 | 4 : format 8 | 5 : getLocker 9 | 6 : setLocker 10 | 7 : effaceLocker 11 | 8 : lockerSpace 12 | */ 13 | #define kAppleEffaceableStorageGetBytes 1 14 | #define kAppleEffaceableStorageGetLocker 5 15 | 16 | 17 | #define LOCKER_DKEY 0x446B6579 18 | #define LOCKER_EMF 0x454D4621 19 | #define LOCKER_BAG1 0x42414731 20 | #define LOCKER_LWVM 0x4C77564d 21 | 22 | struct EffaceableLocker 23 | { 24 | unsigned short magic; //0x4c6B = "kL" 25 | unsigned short len; 26 | unsigned int tag; //BAG1, EMF, Dkey, DONE 27 | unsigned char data[1]; 28 | }; 29 | 30 | struct BAG1Locker 31 | { 32 | unsigned int magic;//'BAG1'; 33 | unsigned char iv[16]; 34 | unsigned char key[32]; 35 | }; 36 | 37 | int AppleEffaceableStorage__getLocker(uint32_t lockerId, uint8_t* buffer, size_t len); 38 | int AppleEffaceableStorage__getBytes(uint8_t* buffer, size_t len); 39 | int AppleEffaceableStorage__getLockerFromBytes(uint32_t tag, uint8_t* lockers, size_t lockers_len, uint8_t* buffer, size_t len); 40 | 41 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/AppleKeyStore.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* 4 | AppleKeyStore 5 | 0 : initUserClient scalarOutSize=1 6 | 1 : 7 | 2 : AppleKeyStoreKeyBagCreate 8 | 3 : AppleKeyStoreKeyBagCopyData inscalars=id structOutSize=0x8000 9 | 4 : keybagrelease inscalars":[0]} 10 | 5 : AppleKeyStoreKeyBagSetSystem 11 | 6 : AppleKeyStoreKeyBagCreateWithData 12 | 7 : getlockstate "inscalars":[0], "scalarOutSize":1} 13 | 8 : AppleKeyStoreLockDevice 14 | 9 : AppleKeyStoreUnlockDevice instruct 15 | 10: AppleKeyStoreKeyWrap 16 | 11: AppleKeyStoreKeyUnwrap 17 | 12: AppleKeyStoreKeyBagUnlock 18 | 13: AppleKeyStoreKeyBagLock 19 | 14: AppleKeyStoreKeyBagGetSystem scalarOutSize=1 20 | 15: AppleKeyStoreKeyBagChangeSecret 21 | 17: AppleKeyStoreGetDeviceLockState scalarOutSize=1 22 | 18: AppleKeyStoreRecoverWithEscrowBag 23 | 19: AppleKeyStoreOblitClassD 24 | */ 25 | #define kAppleKeyStoreInitUserClient 0 26 | #define kAppleKeyStoreKeyBagSetSystem 5 27 | #define kAppleKeyStoreKeyBagCreateWithData 6 28 | #define kAppleKeyStoreUnlockDevice 9 29 | 30 | #define MAX_CLASS_KEYS 20 31 | 32 | struct KeyBagBlobItem 33 | { 34 | unsigned int tag; 35 | unsigned int len; 36 | union 37 | { 38 | unsigned int intvalue; 39 | unsigned char bytes[1]; 40 | } data; 41 | }; 42 | 43 | typedef struct ClassKey 44 | { 45 | unsigned char uuid[16]; 46 | unsigned int clas; 47 | unsigned int wrap; 48 | unsigned char wpky[40]; 49 | } ClassKey; 50 | 51 | typedef struct KeyBag 52 | { 53 | unsigned int version; 54 | unsigned int type; 55 | unsigned char uuid[16]; 56 | unsigned char hmck[40]; 57 | unsigned char salt[20]; 58 | unsigned int iter; 59 | 60 | unsigned int numKeys; 61 | 62 | struct ClassKey keys[MAX_CLASS_KEYS]; 63 | } KeyBag; 64 | 65 | 66 | int AppleKeyStoreKeyBagInit(); 67 | CFDictionaryRef AppleKeyStore_loadKeyBag(const char* folder, const char* filename); 68 | int AppleKeyStoreKeyBagCreateWithData(CFDataRef data, uint64_t* keybagId); 69 | int AppleKeyStoreKeyBagSetSystem(uint64_t keybagId); 70 | int AppleKeyStoreUnlockDevice(io_connect_t conn, CFDataRef passcode); 71 | 72 | KeyBag* AppleKeyStore_parseBinaryKeyBag(CFDataRef kb); 73 | void AppleKeyStore_printKeyBag(KeyBag* kb); 74 | 75 | int AppleKeyStore_getPasscodeKey(KeyBag* keybag, 76 | const char* passcode, 77 | size_t passcodeLen, 78 | uint8_t* passcodeKey); 79 | 80 | int AppleKeyStore_unlockKeybagFromUserland(KeyBag* kb, 81 | const char* passcode, 82 | size_t passcodeLen, 83 | uint8_t* key835); 84 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/AppleKeyStore_kdf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "IOKit.h" 6 | #include "IOAESAccelerator.h" 7 | #include "AppleEffaceableStorage.h" 8 | #include "AppleKeyStore.h" 9 | #include "bsdcrypto/pbkdf2.h" 10 | #include "bsdcrypto/rijndael.h" 11 | #include "bsdcrypto/key_wrap.h" 12 | 13 | int AppleKeyStore_derivation(void* data, uint32_t dataLength, uint32_t iter, uint32_t vers); 14 | uint32_t AppleKeyStore_xorExpand(uint32_t* dst, uint32_t dstLen, uint32_t* input, uint32_t inLen, uint32_t xorKey); 15 | void AppleKeyStore_xorCompress(uint32_t* input, uint32_t inputLen, uint32_t* output, uint32_t outputLen); 16 | 17 | #define DERIVATION_BUFFER_SIZE 4096 18 | uint8_t buf1[DERIVATION_BUFFER_SIZE]; 19 | uint8_t buf2[DERIVATION_BUFFER_SIZE]; 20 | 21 | IOByteCount IOAESStructSize1 = sizeof(IOAESStruct); 22 | IOAESStruct in ={buf1,buf2,DERIVATION_BUFFER_SIZE,{0},0,128,{0},kIOAESAcceleratorUIDMask,0}; 23 | IOAESStruct out = {0}; 24 | 25 | int AppleKeyStore_getPasscodeKey(KeyBag* keybag, 26 | const char* passcode, 27 | size_t passcodeLen, 28 | uint8_t* passcodeKey) 29 | { 30 | //One PBKDF2 iter, hardcoded salt length 31 | pkcs5_pbkdf2(passcode, passcodeLen, keybag->salt, 20, passcodeKey, 32, 1); 32 | 33 | return AppleKeyStore_derivation(passcodeKey, 32, keybag->iter, keybag->version); 34 | } 35 | 36 | int AppleKeyStore_derivation(void* data, uint32_t dataLength, uint32_t iter, uint32_t vers) 37 | { 38 | IOReturn ret; 39 | io_connect_t conn = IOAESAccelerator_getIOconnect(); 40 | memset(in.iv, 0, 16); 41 | 42 | uint32_t r4; 43 | uint32_t nBlocks = DERIVATION_BUFFER_SIZE / dataLength; //4096/32=128 44 | uint32_t xorkey = 1; 45 | 46 | uint32_t* buffer2 = data; 47 | if (vers >= 2) 48 | { 49 | buffer2 = malloc(dataLength); 50 | memcpy(buffer2, data, dataLength); 51 | } 52 | while (iter > 0) 53 | { 54 | //version=1 xorKey alawys=1, buffer2 changes at each iter 55 | //version=2 xorKey changes at each iter, buffer2 is always the input (pbkdf2(passcode)) 56 | r4 = AppleKeyStore_xorExpand((uint32_t*)buf1, DERIVATION_BUFFER_SIZE, buffer2, dataLength, xorkey); 57 | if (vers >= 2) 58 | xorkey = r4; 59 | 60 | if((ret = IOConnectCallStructMethod(conn, kIOAESAcceleratorTask, &in, IOAESStructSize1, &out, &IOAESStructSize1)) != kIOReturnSuccess) 61 | { 62 | fprintf(stderr, "IOConnectCallStructMethod fail : %x\n", ret); 63 | return -1; 64 | } 65 | memcpy(in.iv, out.iv, 16); 66 | 67 | r4 = nBlocks; 68 | if (r4 >= iter) 69 | { 70 | r4 = iter; 71 | } 72 | AppleKeyStore_xorCompress((uint32_t*) buf2, r4 * dataLength, data, dataLength); 73 | iter -= r4; 74 | } 75 | if (vers >= 2) 76 | { 77 | free(buffer2); 78 | } 79 | return 0; 80 | } 81 | 82 | /* 83 | uint32_t paddedLen = (inLen + 3) & (~3);//aligne sur 4 octets 84 | if (dstLen % paddedLen) 85 | return; 86 | uint32_t localBuf[inLen/4]; 87 | 88 | memcpy(localBuf, input, inLen); 89 | memset(&localBuf[inLen], 0, paddedLen - inLen);*/ 90 | uint32_t AppleKeyStore_xorExpand(uint32_t* dst, uint32_t dstLen, uint32_t* input, uint32_t inLen, uint32_t xorKey) 91 | { 92 | uint32_t* dstEnd = &dst[dstLen/4]; 93 | uint32_t i = 0; 94 | 95 | while (dst < dstEnd) 96 | { 97 | i = 0; 98 | while (i < inLen/4) 99 | { 100 | *dst = input[i] ^ xorKey; 101 | dst++; 102 | i++; 103 | } 104 | xorKey++; 105 | } 106 | return xorKey; 107 | } 108 | 109 | void AppleKeyStore_xorCompress(uint32_t* input, uint32_t inputLen, uint32_t* output, uint32_t outputLen) 110 | { 111 | uint32_t i; 112 | 113 | for (i=0; i < (inputLen/4); i++) 114 | { 115 | output[i%(outputLen/4)] ^= input[i]; 116 | } 117 | } 118 | 119 | int AppleKeyStore_unlockKeybagFromUserland(KeyBag* kb, const char* passcode, size_t passcodeLen, uint8_t* key835) 120 | { 121 | u_int8_t passcodeKey[32]={0}; 122 | u_int8_t unwrappedKey[40]={0}; 123 | aes_key_wrap_ctx ctx; 124 | int i; 125 | 126 | AppleKeyStore_getPasscodeKey(kb, passcode, passcodeLen, passcodeKey); 127 | aes_key_wrap_set_key(&ctx, passcodeKey, 32); 128 | 129 | for (i=0; i < kb->numKeys; i++) 130 | { 131 | if (kb->keys[i].wrap & 2) 132 | { 133 | if(aes_key_unwrap(&ctx, kb->keys[i].wpky, unwrappedKey, 4)) 134 | return 0; 135 | memcpy(kb->keys[i].wpky, unwrappedKey, 32); 136 | kb->keys[i].wrap &= ~2; 137 | } 138 | if (kb->keys[i].wrap & 1) 139 | { 140 | doAES(kb->keys[i].wpky, kb->keys[i].wpky, 32, kIOAESAcceleratorCustomMask, key835, NULL, kIOAESAcceleratorDecrypt, 128); 141 | kb->keys[i].wrap &= ~1; 142 | } 143 | } 144 | return 1; 145 | } 146 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/IOAESAccelerator.c: -------------------------------------------------------------------------------- 1 | /** 2 | https://github.com/planetbeing/xpwn/blob/master/crypto/aes.c 3 | **/ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "IOAESAccelerator.h" 11 | #include "IOKit.h" 12 | 13 | io_connect_t conn = 0; 14 | IOByteCount IOAESStructSize = sizeof(IOAESStruct); 15 | pthread_once_t once_control = PTHREAD_ONCE_INIT; 16 | 17 | //see com.apple.driver.AppleCDMA 18 | typedef struct 19 | { 20 | uint32_t key_id; 21 | uint32_t hw_key_id; 22 | uint8_t nonce_to_encrypt_with_hw_key[16]; 23 | uint8_t* value; 24 | } device_key_descriptor; 25 | 26 | #define NUM_DEVICE_KEYS 4 27 | device_key_descriptor ios_device_keys[NUM_DEVICE_KEYS]= { 28 | {0x835, kIOAESAcceleratorUIDMask, {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, NULL}, 29 | {0x899, kIOAESAcceleratorUIDMask, {0xD1, 0xE8, 0xFC, 0xB5, 0x39, 0x37, 0xBF, 0x8D, 0xEF, 0xC7, 0x4C, 0xD1, 0xD0, 0xF1, 0xD4, 0xB0}, NULL}, 30 | {0x89B, kIOAESAcceleratorUIDMask, {0x18, 0x3E, 0x99, 0x67, 0x6B, 0xB0, 0x3C, 0x54, 0x6F, 0xA4, 0x68, 0xF5, 0x1C, 0x0C, 0xBD, 0x49}, NULL}, 31 | {0x89A, kIOAESAcceleratorUIDMask, {0xDB, 0x1F, 0x5B, 0x33, 0x60, 0x6C, 0x5F, 0x1C, 0x19, 0x34, 0xAA, 0x66, 0x58, 0x9C, 0x06, 0x61}, NULL}, 32 | }; 33 | 34 | void aes_init() 35 | { 36 | conn = IOKit_getConnect("IOAESAccelerator"); 37 | } 38 | 39 | io_connect_t IOAESAccelerator_getIOconnect() 40 | { 41 | pthread_once(&once_control, aes_init); 42 | return conn; 43 | } 44 | 45 | 46 | int doAES(void* inbuf, void *outbuf, uint32_t size, uint32_t keyMask, void* key, void* iv, int mode, int bits) { 47 | IOReturn ret; 48 | IOAESStruct in; 49 | 50 | pthread_once(&once_control, aes_init); 51 | 52 | in.mode = mode; 53 | in.bits = bits; 54 | in.inbuf = inbuf; 55 | in.outbuf = outbuf; 56 | in.size = size; 57 | in.mask = keyMask; 58 | 59 | memset(in.keybuf, 0, sizeof(in.keybuf)); 60 | 61 | if(key) 62 | memcpy(in.keybuf, key, in.bits / 8); 63 | 64 | if(iv) 65 | memcpy(in.iv, iv, 16); 66 | else 67 | memset(in.iv, 0, 16); 68 | 69 | ret = IOConnectCallStructMethod(conn, kIOAESAcceleratorTask, &in, IOAESStructSize, &in, &IOAESStructSize); 70 | if(ret == kIOReturnBadArgument) { 71 | IOAESStructSize = IOAESStruct_sizeold; 72 | ret = IOConnectCallStructMethod(conn, kIOAESAcceleratorTask, &in, IOAESStructSize, &in, &IOAESStructSize); 73 | } 74 | 75 | if(iv) 76 | memcpy(iv, in.iv, 16); 77 | 78 | return ret; 79 | } 80 | 81 | IOReturn doAES_wrapper(void* thisxxx, int mode, void* iv, void* outbuf, void *inbuf, uint32_t size, uint32_t keyMask) 82 | { 83 | int x = doAES(inbuf, outbuf, size, keyMask, NULL, iv, mode, 128); 84 | return !x; 85 | } 86 | 87 | int patch_IOAESAccelerator(); 88 | 89 | int AES_UID_Encrypt(void* input2, void* output, size_t len) 90 | { 91 | IOAESStruct in; 92 | IOReturn ret; 93 | static int triedToPatchKernelAlready = 0; 94 | unsigned char* input = valloc(16); 95 | 96 | memcpy(input, input2, 16); 97 | 98 | pthread_once(&once_control, aes_init); 99 | 100 | in.mode = kIOAESAcceleratorEncrypt; 101 | in.mask = kIOAESAcceleratorUIDMask; 102 | in.bits = 128; 103 | in.inbuf = input; 104 | in.outbuf = output; 105 | in.size = len; 106 | 107 | memset(in.keybuf, 0, sizeof(in.keybuf)); 108 | memset(in.iv, 0, 16); 109 | 110 | ret = IOConnectCallStructMethod(conn, kIOAESAcceleratorTask, &in, IOAESStructSize, &in, &IOAESStructSize); 111 | if(ret == kIOReturnBadArgument) { 112 | IOAESStructSize = IOAESStruct_sizeold; 113 | ret = IOConnectCallStructMethod(conn, kIOAESAcceleratorTask, &in, IOAESStructSize, &in, &IOAESStructSize); 114 | } 115 | 116 | if(ret == kIOReturnNotPrivileged && !triedToPatchKernelAlready) { 117 | triedToPatchKernelAlready = 1; 118 | fprintf(stderr, "Trying to patch IOAESAccelerator kernel extension to allow UID key usage\n"); 119 | patch_IOAESAccelerator(); 120 | ret = AES_UID_Encrypt(input2, output, len); 121 | } 122 | if(ret != kIOReturnSuccess) { 123 | fprintf(stderr, "IOAESAccelerator returned: %x\n", ret); 124 | } 125 | return ret; 126 | } 127 | 128 | uint8_t* IOAES_get_device_key(uint32_t id) 129 | { 130 | static uint8_t nullkey[16] = {0}; 131 | int i; 132 | for(i=0; i < NUM_DEVICE_KEYS; i++) 133 | { 134 | if (ios_device_keys[i].key_id != id) 135 | continue; 136 | if (ios_device_keys[i].value != NULL) 137 | return ios_device_keys[i].value; 138 | 139 | ios_device_keys[i].value = (uint8_t*) valloc(16); //on ARMv6 devices stuff needs to be aligned 140 | memcpy(ios_device_keys[i].value, ios_device_keys[i].nonce_to_encrypt_with_hw_key, 16); 141 | AES_UID_Encrypt(ios_device_keys[i].value, ios_device_keys[i].value, 16); 142 | return ios_device_keys[i].value; 143 | } 144 | return nullkey; 145 | 146 | } 147 | uint8_t* IOAES_key835() 148 | { 149 | return IOAES_get_device_key(0x835); 150 | } 151 | 152 | uint8_t* IOAES_key89B() 153 | { 154 | return IOAES_get_device_key(0x89B); 155 | } 156 | 157 | uint8_t* IOAES_key89A() 158 | { 159 | return IOAES_get_device_key(0x89A); 160 | } -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/IOAESAccelerator.h: -------------------------------------------------------------------------------- 1 | #define kIOAESAcceleratorInfo 0 2 | #define kIOAESAcceleratorTask 1 3 | #define kIOAESAcceleratorTest 2 4 | 5 | #define kIOAESAcceleratorEncrypt 0 6 | #define kIOAESAcceleratorDecrypt 1 7 | 8 | #define kIOAESAcceleratorGIDMask 0x3E8 9 | #define kIOAESAcceleratorUIDMask 0x7D0 10 | #define kIOAESAcceleratorCustomMask 0 11 | 12 | typedef struct 13 | { 14 | void* inbuf; 15 | void* outbuf; 16 | uint32_t size; 17 | uint8_t iv[16]; 18 | uint32_t mode; 19 | uint32_t bits; 20 | uint8_t keybuf[32]; 21 | uint32_t mask; 22 | uint32_t zero; //ios 4.2.1 23 | } IOAESStruct; 24 | 25 | #define IOAESStruct_size41 (sizeof(IOAESStruct)) 26 | #define IOAESStruct_sizeold (sizeof(IOAESStruct) - 4) 27 | 28 | void aes_init(); 29 | io_connect_t IOAESAccelerator_getIOconnect(); 30 | int doAES(void* inbuf, void *outbuf, uint32_t size, uint32_t keyMask, void* key, void* iv, int mode, int bits); 31 | int AES_UID_Encrypt(void* input, void* output, size_t len); 32 | 33 | uint8_t* IOAES_key835(); 34 | uint8_t* IOAES_key89A(); 35 | uint8_t* IOAES_key89B(); 36 | 37 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/IOKit: -------------------------------------------------------------------------------- 1 | /System/Library/Frameworks/IOKit.framework/Versions/Current/Headers -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/IOKit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "IOKit.h" 4 | 5 | struct ioconnectCache { 6 | const char* serviceName; 7 | io_connect_t conn; 8 | }; 9 | 10 | struct ioconnectCache cache[10]={{NULL, 0}}; 11 | 12 | void __attribute__((destructor)) IOKit_destruct() 13 | { 14 | int i; 15 | for (i=0; i < 10 && cache[i].conn != 0; i++) { 16 | //printf("Closing %s\n", cache[i].serviceName); 17 | IOServiceClose(cache[i].conn); 18 | } 19 | } 20 | 21 | io_connect_t IOKit_getConnect(const char* serviceName) 22 | { 23 | IOReturn ret; 24 | io_connect_t conn = 0; 25 | int i; 26 | 27 | for (i=0; i < 10 && cache[i].serviceName != NULL; i++) { 28 | if (!strcmp(serviceName, cache[i].serviceName)) 29 | { 30 | //printf("got cache for %s\n", serviceName); 31 | return cache[i].conn; 32 | } 33 | } 34 | 35 | CFMutableDictionaryRef dict = IOServiceMatching(serviceName); 36 | io_service_t dev = IOServiceGetMatchingService(kIOMasterPortDefault, dict); 37 | 38 | if(!dev) { 39 | fprintf(stderr, "FAIL: Could not get %s service\n", serviceName); 40 | return -1; 41 | } 42 | 43 | ret = IOServiceOpen(dev, mach_task_self(), 0, &conn); 44 | 45 | IOObjectRelease(dev); 46 | if(ret != kIOReturnSuccess) { 47 | fprintf(stderr, "FAIL: Cannot open service %s\n", serviceName); 48 | return -1; 49 | } 50 | 51 | if (i < 10) { 52 | cache[i].serviceName = serviceName; 53 | cache[i].conn = conn; 54 | } 55 | 56 | return conn; 57 | } 58 | 59 | IOReturn IOKit_call(const char* serviceName, 60 | uint32_t selector, 61 | const uint64_t *input, 62 | uint32_t inputCnt, 63 | const void *inputStruct, 64 | size_t inputStructCnt, 65 | uint64_t *output, 66 | uint32_t *outputCnt, 67 | void *outputStruct, 68 | size_t *outputStructCnt) 69 | { 70 | IOReturn ret; 71 | io_connect_t conn = IOKit_getConnect(serviceName); 72 | 73 | ret = IOConnectCallMethod(conn, 74 | selector, 75 | input, 76 | inputCnt, 77 | inputStruct, 78 | inputStructCnt, 79 | output, 80 | outputCnt, 81 | outputStruct, 82 | outputStructCnt); 83 | 84 | if (ret != kIOReturnSuccess) 85 | { 86 | fprintf(stderr, "IOConnectCallMethod on %s selector %d returned %x\n", serviceName, selector, ret); 87 | } 88 | 89 | return ret; 90 | } -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/IOKit.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | io_connect_t IOKit_getConnect(const char* serviceName); 4 | 5 | IOReturn IOKit_call(const char* serviceName, 6 | uint32_t selector, 7 | const uint64_t *input, 8 | uint32_t inputCnt, 9 | const void *inputStruct, 10 | size_t inputStructCnt, 11 | uint64_t *output, 12 | uint32_t *outputCnt, 13 | void *outputStruct, 14 | size_t *outputStructCnt); -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/Makefile: -------------------------------------------------------------------------------- 1 | SDKVER?=7.0 2 | SDKVER?=6.1 3 | SDKVER?=6.0 4 | SDKVER?=5.1 5 | SDKVER?=5.0 6 | SDKVER?=4.3 7 | SDKVER?=4.2 8 | ARCH?=armv7 9 | MINIOS=4.0 10 | SDK=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS$(SDKVER).sdk/ 11 | HGVERSION:= $(shell hg parents --template '{node|short}' || echo "unknown") 12 | CC=clang -arch $(ARCH) 13 | CFLAGS=-Wall -isysroot $(SDK) -DHGVERSION="\"${HGVERSION}\"" -O3 -I. 14 | CFLAGS+= -framework CoreFoundation -framework IOKit -framework Security 15 | CFLAGS+= -miphoneos-version-min=$(MINIOS) 16 | CODESIGN=codesign -s - --entitlements 17 | 18 | all: $(SDK) IOKit IOUSBDeviceControllerLib.h device_infos restored_external bruteforce ioflashstoragekit 19 | 20 | $(SDK): 21 | @echo "iOS SDK not found in $(SDK)" 22 | @echo "=> check SDKVER/SDK in Makefile" 23 | 24 | IOUSBDeviceControllerLib.h: 25 | curl -o IOUSBDeviceControllerLib.h http://www.opensource.apple.com/source/IOKitUser/IOKitUser-502/usb_device.subproj/IOUSBDeviceControllerLib.h?txt 26 | 27 | IOKit: 28 | ln -s /System/Library/Frameworks/IOKit.framework/Versions/Current/Headers IOKit 29 | 30 | device_infos: device_infos.c device_info.c IOAESAccelerator.c AppleEffaceableStorage.c AppleKeyStore.c bsdcrypto/pbkdf2.c bsdcrypto/sha1.c bsdcrypto/key_wrap.c bsdcrypto/rijndael.c util.c IOKit.c registry.c ioflash/ioflash.c kernel_patcher.c 31 | $(CC) $(CFLAGS) -o $@ $^ 32 | $(CODESIGN) tfp0.plist $@ 33 | 34 | restored_external: restored_external.c device_info.c remote_functions.c plist_server.c AppleKeyStore.c AppleEffaceableStorage.c IOKit.c IOAESAccelerator.c util.c registry.c AppleKeyStore_kdf.c bsdcrypto/pbkdf2.c bsdcrypto/sha1.c bsdcrypto/rijndael.c bsdcrypto/key_wrap.c ioflash/ioflash.c kernel_patcher.c 35 | $(CC) $(CFLAGS) -o $@ $^ 36 | $(CODESIGN) keystore_device.xml $@ 37 | 38 | bruteforce: systemkb_bruteforce.c AppleKeyStore.c AppleEffaceableStorage.c IOKit.c IOAESAccelerator.c util.c registry.c AppleKeyStore_kdf.c bsdcrypto/pbkdf2.c bsdcrypto/sha1.c bsdcrypto/rijndael.c bsdcrypto/key_wrap.c device_info.c ioflash/ioflash.c kernel_patcher.c 39 | $(CC) $(CFLAGS) -o $@ $^ 40 | $(CODESIGN) keystore_device.xml $@ 41 | 42 | ioflashstoragekit: ioflash/ioflash.c ioflash/ioflash_kernel.c ioflash/ioflashstoragekit.c util.c 43 | $(CC) $(CFLAGS) -o $@ $^ 44 | $(CODESIGN) tfp0.plist $@ 45 | 46 | kernel_patcher: kernel_patcher.c 47 | $(CC) $(CFLAGS) -o $@ $^ 48 | $(CODESIGN) tfp0.plist $@ 49 | 50 | shsh_dump: ioflash/ioflash.c ioflash/ioflash_kernel.c shsh_dump.c util.c 51 | $(CC) $(CFLAGS) -o $@ $^ 52 | $(CODESIGN) tfp0.plist $@ 53 | 54 | clean: 55 | rm -f bruteforce restored_external device_infos ioflashstoragekit shsh_dump 56 | 57 | rebuild: clean all 58 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/bsdcrypto/key_wrap.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: key_wrap.c,v 1.3 2011/01/11 15:42:05 deraadt Exp $ */ 2 | 3 | /*- 4 | * Copyright (c) 2008 Damien Bergamini 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | /* 20 | * This code implements the AES Key Wrap algorithm described in RFC 3394. 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | //haxs to compile on osx 27 | #include 28 | #define timingsafe_bcmp bcmp 29 | #define ovbcopy bcopy 30 | #define explicit_bzero bzero 31 | #define htobe64 CFSwapInt64BigToHost 32 | #include "rijndael.h" 33 | #include "key_wrap.h" 34 | 35 | 36 | static const u_int8_t IV[8] = 37 | { 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6 }; 38 | 39 | void 40 | aes_key_wrap_set_key(aes_key_wrap_ctx *ctx, const u_int8_t *K, size_t K_len) 41 | { 42 | rijndael_set_key(&ctx->ctx, K, K_len * NBBY); 43 | } 44 | 45 | void 46 | aes_key_wrap_set_key_wrap_only(aes_key_wrap_ctx *ctx, const u_int8_t *K, 47 | size_t K_len) 48 | { 49 | rijndael_set_key_enc_only(&ctx->ctx, K, K_len * NBBY); 50 | } 51 | 52 | void 53 | aes_key_wrap(aes_key_wrap_ctx *ctx, const u_int8_t *P, size_t n, u_int8_t *C) 54 | { 55 | u_int64_t B[2], t; 56 | u_int8_t *A, *R; 57 | size_t i; 58 | int j; 59 | 60 | ovbcopy(P, C + 8, n * 8); /* P and C may overlap */ 61 | A = C; /* A points to C[0] */ 62 | memcpy(A, IV, 8); /* A = IV, an initial value */ 63 | 64 | for (j = 0, t = 1; j <= 5; j++) { 65 | R = C + 8; 66 | for (i = 1; i <= n; i++, t++) { 67 | /* B = A | R[i] */ 68 | memcpy(&B[0], A, 8); 69 | memcpy(&B[1], R, 8); 70 | /* B = AES(K, B) */ 71 | rijndael_encrypt(&ctx->ctx, (caddr_t)B, (caddr_t)B); 72 | /* MSB(64, B) = MSB(64, B) ^ t */ 73 | B[0] ^= htobe64(t); 74 | /* A = MSB(64, B) */ 75 | memcpy(A, &B[0], 8); 76 | /* R[i] = LSB(64, B) */ 77 | memcpy(R, &B[1], 8); 78 | 79 | R += 8; 80 | } 81 | } 82 | explicit_bzero(B, sizeof B); 83 | } 84 | 85 | int 86 | aes_key_unwrap(aes_key_wrap_ctx *ctx, const u_int8_t *C, u_int8_t *P, size_t n) 87 | { 88 | u_int64_t B[2], t; 89 | u_int8_t A[8], *R; 90 | size_t i; 91 | int j; 92 | 93 | memcpy(A, C, 8); /* A = C[0] */ 94 | ovbcopy(C + 8, P, n * 8); /* P and C may overlap */ 95 | 96 | for (j = 5, t = 6 * n; j >= 0; j--) { 97 | R = P + (n - 1) * 8; 98 | for (i = n; i >= 1; i--, t--) { 99 | /* MSB(64, B) = A */ 100 | memcpy(&B[0], A, 8); 101 | /* MSB(64, B) = MSB(64, B) ^ t */ 102 | B[0] ^= htobe64(t); 103 | /* B = MSB(64, B) | R[i] */ 104 | memcpy(&B[1], R, 8); 105 | /* B = AES-1(K, B) */ 106 | rijndael_decrypt(&ctx->ctx, (caddr_t)B, (caddr_t)B); 107 | /* A = MSB(64, B) */ 108 | memcpy(A, &B[0], 8); 109 | /* R[i] = LSB(64, B) */ 110 | memcpy(R, &B[1], 8); 111 | 112 | R -= 8; 113 | } 114 | } 115 | explicit_bzero(B, sizeof B); 116 | 117 | /* check that A is an appropriate initial value */ 118 | return timingsafe_bcmp(A, IV, 8) != 0; 119 | } 120 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/bsdcrypto/key_wrap.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: key_wrap.h,v 1.1 2008/08/12 15:43:00 damien Exp $ */ 2 | 3 | /*- 4 | * Copyright (c) 2008 Damien Bergamini 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #ifndef _KEY_WRAP_H_ 20 | #define _KEY_WRAP_H_ 21 | 22 | typedef unsigned char u_int8_t; 23 | 24 | typedef struct _aes_key_wrap_ctx { 25 | rijndael_ctx ctx; 26 | } aes_key_wrap_ctx; 27 | 28 | #include 29 | 30 | __BEGIN_DECLS 31 | 32 | void aes_key_wrap_set_key(aes_key_wrap_ctx *, const u_int8_t *, size_t); 33 | void aes_key_wrap_set_key_wrap_only(aes_key_wrap_ctx *, const u_int8_t *, 34 | size_t); 35 | void aes_key_wrap(aes_key_wrap_ctx *, const u_int8_t *, size_t, u_int8_t *); 36 | int aes_key_unwrap(aes_key_wrap_ctx *, const u_int8_t *, u_int8_t *, 37 | size_t); 38 | __END_DECLS 39 | 40 | #endif /* _KEY_WRAP_H_ */ 41 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/bsdcrypto/pbkdf2.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: pbkdf2.h,v 1.1 2008/06/14 06:28:27 djm Exp $ */ 2 | 3 | /*- 4 | * Copyright (c) 2008 Damien Bergamini 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | /* 20 | * Password-Based Key Derivation Function 2 (PKCS #5 v2.0). 21 | * Code based on IEEE Std 802.11-2007, Annex H.4.2. 22 | */ 23 | int pkcs5_pbkdf2(const char *, size_t, const char *, size_t, 24 | u_int8_t *, size_t, u_int); 25 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/bsdcrypto/rijndael.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: rijndael.h,v 1.13 2008/06/09 07:49:45 djm Exp $ */ 2 | 3 | /** 4 | * rijndael-alg-fst.h 5 | * 6 | * @version 3.0 (December 2000) 7 | * 8 | * Optimised ANSI C code for the Rijndael cipher (now AES) 9 | * 10 | * @author Vincent Rijmen 11 | * @author Antoon Bosselaers 12 | * @author Paulo Barreto 13 | * 14 | * This code is hereby placed in the public domain. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS 17 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | #ifndef __RIJNDAEL_H 29 | #define __RIJNDAEL_H 30 | 31 | #define AES_MAXKEYBITS (256) 32 | #define AES_MAXKEYBYTES (AES_MAXKEYBITS/8) 33 | /* for 256-bit keys, fewer for less */ 34 | #define AES_MAXROUNDS 14 35 | 36 | typedef unsigned char u_char; 37 | typedef unsigned char u8; 38 | typedef unsigned short u16; 39 | typedef unsigned int u32; 40 | 41 | /* The structure for key information */ 42 | typedef struct { 43 | int enc_only; /* context contains only encrypt schedule */ 44 | int Nr; /* key-length-dependent number of rounds */ 45 | u32 ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */ 46 | u32 dk[4*(AES_MAXROUNDS + 1)]; /* decrypt key schedule */ 47 | } rijndael_ctx; 48 | 49 | int rijndael_set_key(rijndael_ctx *, const u_char *, int); 50 | int rijndael_set_key_enc_only(rijndael_ctx *, const u_char *, int); 51 | void rijndael_decrypt(rijndael_ctx *, const u_char *, u_char *); 52 | void rijndael_encrypt(rijndael_ctx *, const u_char *, u_char *); 53 | 54 | int rijndaelKeySetupEnc(unsigned int [], const unsigned char [], int); 55 | int rijndaelKeySetupDec(unsigned int [], const unsigned char [], int); 56 | void rijndaelEncrypt(const unsigned int [], int, const unsigned char [], 57 | unsigned char []); 58 | 59 | #endif /* __RIJNDAEL_H */ 60 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/bsdcrypto/sha1.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: sha1.c,v 1.9 2011/01/11 15:50:40 deraadt Exp $ */ 2 | 3 | /* 4 | * SHA-1 in C 5 | * By Steve Reid 6 | * 100% Public Domain 7 | * 8 | * Test Vectors (from FIPS PUB 180-1) 9 | * "abc" 10 | * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 11 | * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 12 | * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 13 | * A million repetitions of "a" 14 | * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 15 | */ 16 | 17 | /* #define LITTLE_ENDIAN * This should be #define'd already, if true. */ 18 | /* #define SHA1HANDSOFF * Copies data before messing with it. */ 19 | 20 | #define SHA1HANDSOFF 21 | 22 | #include 23 | #include 24 | 25 | #include "sha1.h" 26 | 27 | #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 28 | 29 | /* blk0() and blk() perform the initial expand. */ 30 | /* I got the idea of expanding during the round function from SSLeay */ 31 | #if BYTE_ORDER == LITTLE_ENDIAN 32 | #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ 33 | |(rol(block->l[i],8)&0x00FF00FF)) 34 | #else 35 | #define blk0(i) block->l[i] 36 | #endif 37 | #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ 38 | ^block->l[(i+2)&15]^block->l[i&15],1)) 39 | 40 | /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 41 | #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); 42 | #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); 43 | #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 44 | #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); 45 | #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 46 | 47 | /* Hash a single 512-bit block. This is the core of the algorithm. */ 48 | 49 | void 50 | SHA1Transform(u_int32_t state[5], const unsigned char buffer[SHA1_BLOCK_LENGTH]) 51 | { 52 | u_int32_t a, b, c, d, e; 53 | typedef union { 54 | unsigned char c[64]; 55 | unsigned int l[16]; 56 | } CHAR64LONG16; 57 | CHAR64LONG16* block; 58 | #ifdef SHA1HANDSOFF 59 | unsigned char workspace[SHA1_BLOCK_LENGTH]; 60 | 61 | block = (CHAR64LONG16 *)workspace; 62 | bcopy(buffer, block, SHA1_BLOCK_LENGTH); 63 | #else 64 | block = (CHAR64LONG16 *)buffer; 65 | #endif 66 | /* Copy context->state[] to working vars */ 67 | a = state[0]; 68 | b = state[1]; 69 | c = state[2]; 70 | d = state[3]; 71 | e = state[4]; 72 | 73 | /* 4 rounds of 20 operations each. Loop unrolled. */ 74 | R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); 75 | R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); 76 | R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); 77 | R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); 78 | R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); 79 | R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); 80 | R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); 81 | R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); 82 | R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); 83 | R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); 84 | R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); 85 | R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); 86 | R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); 87 | R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); 88 | R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); 89 | R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); 90 | R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); 91 | R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); 92 | R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); 93 | R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); 94 | 95 | /* Add the working vars back into context.state[] */ 96 | state[0] += a; 97 | state[1] += b; 98 | state[2] += c; 99 | state[3] += d; 100 | state[4] += e; 101 | /* Wipe variables */ 102 | a = b = c = d = e = 0; 103 | } 104 | 105 | 106 | /* SHA1Init - Initialize new context */ 107 | 108 | void 109 | SHA1Init(SHA1_CTX *context) 110 | { 111 | /* SHA1 initialization constants */ 112 | context->count = 0; 113 | context->state[0] = 0x67452301; 114 | context->state[1] = 0xEFCDAB89; 115 | context->state[2] = 0x98BADCFE; 116 | context->state[3] = 0x10325476; 117 | context->state[4] = 0xC3D2E1F0; 118 | } 119 | 120 | 121 | /* Run your data through this. */ 122 | 123 | void 124 | SHA1Update(SHA1_CTX *context, const unsigned char *data, unsigned int len) 125 | { 126 | unsigned int i; 127 | unsigned int j; 128 | 129 | j = (u_int32_t)((context->count >> 3) & 63); 130 | context->count += (len << 3); 131 | if ((j + len) > 63) { 132 | bcopy(data, &context->buffer[j], (i = 64 - j)); 133 | SHA1Transform(context->state, context->buffer); 134 | for ( ; i + 63 < len; i += 64) { 135 | SHA1Transform(context->state, &data[i]); 136 | } 137 | j = 0; 138 | } 139 | else i = 0; 140 | bcopy(&data[i], &context->buffer[j], len - i); 141 | } 142 | 143 | 144 | /* Add padding and return the message digest. */ 145 | 146 | void 147 | SHA1Final(unsigned char digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context) 148 | { 149 | unsigned int i; 150 | unsigned char finalcount[8]; 151 | 152 | for (i = 0; i < 8; i++) { 153 | finalcount[i] = (unsigned char)((context->count >> 154 | ((7 - (i & 7)) * 8)) & 255); /* Endian independent */ 155 | } 156 | SHA1Update(context, (unsigned char *)"\200", 1); 157 | while ((context->count & 504) != 448) { 158 | SHA1Update(context, (unsigned char *)"\0", 1); 159 | } 160 | SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ 161 | 162 | if (digest) 163 | for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { 164 | digest[i] = (unsigned char)((context->state[i >> 2] >> 165 | ((3 - (i & 3)) * 8)) & 255); 166 | } 167 | bzero(&finalcount, 8); 168 | #if 0 /* We want to use this for "keyfill" */ 169 | /* Wipe variables */ 170 | i = 0; 171 | bzero(context->buffer, 64); 172 | bzero(context->state, 20); 173 | bzero(context->count, 8); 174 | #ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */ 175 | SHA1Transform(context->state, context->buffer); 176 | #endif 177 | #endif 178 | } 179 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/bsdcrypto/sha1.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: sha1.h,v 1.5 2007/09/10 22:19:42 henric Exp $ */ 2 | 3 | /* 4 | * SHA-1 in C 5 | * By Steve Reid 6 | * 100% Public Domain 7 | */ 8 | 9 | #ifndef _SHA1_H_ 10 | #define _SHA1_H_ 11 | 12 | #define SHA1_BLOCK_LENGTH 64 13 | #define SHA1_DIGEST_LENGTH 20 14 | 15 | typedef struct { 16 | u_int32_t state[5]; 17 | u_int64_t count; 18 | unsigned char buffer[SHA1_BLOCK_LENGTH]; 19 | } SHA1_CTX; 20 | 21 | void SHA1Init(SHA1_CTX * context); 22 | void SHA1Transform(u_int32_t state[5], const unsigned char buffer[SHA1_BLOCK_LENGTH]); 23 | void SHA1Update(SHA1_CTX *context, const unsigned char *data, unsigned int len); 24 | void SHA1Final(unsigned char digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context); 25 | 26 | #endif /* _SHA1_H_ */ 27 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/device_info.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "IOAESAccelerator.h" 6 | #include "AppleEffaceableStorage.h" 7 | #include "bsdcrypto/rijndael.h" 8 | #include "bsdcrypto/key_wrap.h" 9 | #include "device_info.h" 10 | #include "registry.h" 11 | #include "util.h" 12 | #include "ioflash/ioflash.h" 13 | 14 | uint8_t lockers[960]={0}; 15 | uint8_t lwvm[80]={0}; 16 | 17 | CFDictionaryRef device_info(int socket, CFDictionaryRef request) 18 | { 19 | uint8_t dkey[40]={0}; 20 | uint8_t emf[36]={0}; 21 | size_t bootargs_len = 255; 22 | char bootargs[256]={0}; 23 | 24 | struct HFSInfos hfsinfos={0}; 25 | 26 | CFMutableDictionaryRef out = CFDictionaryCreateMutable(kCFAllocatorDefault, 27 | 0, 28 | &kCFTypeDictionaryKeyCallBacks, 29 | &kCFTypeDictionaryValueCallBacks); 30 | 31 | get_device_infos(out); 32 | 33 | CFMutableDictionaryRef nand = FSDGetInfo(0); 34 | if (nand != NULL) 35 | CFDictionaryAddValue(out, CFSTR("nand"), nand); 36 | 37 | getHFSInfos(&hfsinfos); 38 | 39 | uint8_t* key835 = IOAES_key835(); 40 | uint8_t* key89A = IOAES_key89A(); 41 | uint8_t* key89B = IOAES_key89B(); 42 | 43 | if (!AppleEffaceableStorage__getBytes(lockers, 960)) 44 | { 45 | CFDataRef lockersData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, lockers, 960, kCFAllocatorNull); 46 | CFDictionaryAddValue(out, CFSTR("lockers"), lockersData); 47 | CFRelease(lockersData); 48 | 49 | if (!AppleEffaceableStorage__getLockerFromBytes(LOCKER_DKEY, lockers, 960, dkey, 40)) 50 | { 51 | aes_key_wrap_ctx ctx; 52 | 53 | aes_key_wrap_set_key(&ctx, key835, 16); 54 | 55 | if(aes_key_unwrap(&ctx, dkey, dkey, 32/8)) 56 | printf("FAIL unwrapping DKey with key 0x835\n"); 57 | } 58 | if (!AppleEffaceableStorage__getLockerFromBytes(LOCKER_EMF, lockers, 960, emf, 36)) 59 | { 60 | doAES(&emf[4], &emf[4], 32, kIOAESAcceleratorCustomMask, key89B, NULL, kIOAESAcceleratorDecrypt, 128); 61 | } 62 | else if (!AppleEffaceableStorage__getLockerFromBytes(LOCKER_LWVM, lockers, 960, lwvm, 0x50)) 63 | { 64 | doAES(lwvm, lwvm, 0x50, kIOAESAcceleratorCustomMask, key89B, NULL, kIOAESAcceleratorDecrypt, 128); 65 | memcpy(&emf[4], &lwvm[32+16], 32); 66 | } 67 | } 68 | 69 | CFNumberRef n = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &hfsinfos.dataVolumeOffset); 70 | CFDictionaryAddValue(out, CFSTR("dataVolumeOffset"), n); 71 | CFRelease(n); 72 | addHexaString(out, CFSTR("dataVolumeUUID"), (uint8_t*) &hfsinfos.volumeUUID, 8); 73 | addHexaString(out, CFSTR("key835"), key835, 16); 74 | addHexaString(out, CFSTR("key89A"), key89A, 16); 75 | addHexaString(out, CFSTR("key89B"), key89B, 16); 76 | addHexaString(out, CFSTR("EMF"), &emf[4], 32); 77 | addHexaString(out, CFSTR("DKey"), dkey, 32); 78 | 79 | sysctlbyname("kern.bootargs", bootargs, &bootargs_len, NULL, 0); 80 | if (bootargs_len > 1) 81 | { 82 | CFStringRef bootargsString = CFStringCreateWithBytes(kCFAllocatorDefault, bootargs, bootargs_len - 1, kCFStringEncodingASCII, 0); 83 | CFDictionaryAddValue(out, CFSTR("kern.bootargs"), bootargsString); 84 | CFRelease(bootargsString); 85 | } 86 | 87 | CFDictionaryAddValue(out, CFSTR("ramdisk revision"), CFSTR(HGVERSION)); 88 | CFDictionaryAddValue(out, CFSTR("ramdisk compile time"), CFSTR(__DATE__ " " __TIME__ )); 89 | 90 | return out; 91 | } 92 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/device_info.h: -------------------------------------------------------------------------------- 1 | #ifndef HGVERSION 2 | #define HGVERSION "unknown" 3 | #endif 4 | 5 | CFDictionaryRef device_info(int socket, CFDictionaryRef request); 6 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/device_infos.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "device_info.h" 5 | #include "util.h" 6 | 7 | int main(int argc, char* argv[]) 8 | { 9 | CFMutableDictionaryRef out = device_info(-1, NULL); 10 | 11 | if (out == NULL) 12 | { 13 | fprintf(stderr, "device_info(-1, NULL) failed\n"); 14 | return -1; 15 | } 16 | 17 | if (argc > 1 ) 18 | { 19 | CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault, argv[1], kCFStringEncodingASCII); 20 | CFTypeRef value = CFDictionaryGetValue(out, key); 21 | if (value != NULL) 22 | { 23 | *stderr = *stdout;//HAX 24 | CFShow(value); 25 | } 26 | else 27 | fprintf(stderr, "key %s not found\n", argv[1]); 28 | CFRelease(key); 29 | CFRelease(out); 30 | return 0; 31 | } 32 | 33 | writePlistToStdout(out); 34 | /*CFStringRef plistFileName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@.plist"), CFDictionaryGetValue(out, CFSTR("dataVolumeUUID"))); 35 | 36 | CFStringRef printString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("Writing results to %@\n"), plistFileName); 37 | CFShow(printString); 38 | CFRelease(printString); 39 | 40 | saveResults(plistFileName, out); 41 | CFRelease(plistFileName);*/ 42 | CFRelease(out); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/dump_data_partition.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cat /dev/rdisk0s2s1 | netcat -l -p 1234 4 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/image.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int screenWidth, screenHeight; 7 | CGContextRef context = NULL; 8 | 9 | CGContextRef fb_open() { 10 | io_connect_t conn = NULL; 11 | int bytesPerRow; 12 | void *surfaceBuffer; 13 | void *frameBuffer; 14 | CGColorSpaceRef colorSpace; 15 | 16 | if (context != NULL) 17 | return context; 18 | 19 | io_service_t fb_service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleCLCD")); 20 | if (!fb_service) { 21 | fb_service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleM2CLCD")); 22 | if (!fb_service) { 23 | printf("Couldn't find framebuffer.\n"); 24 | return NULL; 25 | } 26 | } 27 | 28 | IOMobileFramebufferOpen(fb_service, mach_task_self(), 0, &conn); 29 | IOMobileFramebufferGetLayerDefaultSurface(conn, 0, &surfaceBuffer); 30 | 31 | screenHeight = CoreSurfaceBufferGetHeight(surfaceBuffer); 32 | screenWidth = CoreSurfaceBufferGetWidth(surfaceBuffer); 33 | bytesPerRow = CoreSurfaceBufferGetBytesPerRow(surfaceBuffer); 34 | 35 | CoreSurfaceBufferLock(surfaceBuffer, 3); 36 | frameBuffer = CoreSurfaceBufferGetBaseAddress(surfaceBuffer); 37 | CoreSurfaceBufferUnlock(surfaceBuffer); 38 | 39 | // create bitmap context 40 | colorSpace = CGColorSpaceCreateDeviceRGB(); 41 | context = CGBitmapContextCreate(frameBuffer, screenWidth, screenHeight, 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast); 42 | if(context == NULL) { 43 | printf("Couldn't create screen context!\n"); 44 | return NULL; 45 | } 46 | 47 | CGColorSpaceRelease(colorSpace); 48 | 49 | return context; 50 | } 51 | 52 | int drawImage(const char* pngFileName) 53 | { 54 | CGContextRef c = fb_open(); 55 | if (c == NULL) 56 | return -1; 57 | 58 | CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, pngFileName, strlen(pngFileName), 0); 59 | void* imageSource = CGImageSourceCreateWithURL(url, NULL); 60 | CFRelease(url); 61 | 62 | if (imageSource != NULL) 63 | { 64 | CGImageRef img = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL); 65 | if (img != NULL) 66 | { 67 | CGContextClearRect (c, CGRectMake(0, 0, screenWidth, screenHeight)); 68 | CGContextDrawImage(c, CGRectMake(0, 0, screenWidth, screenHeight), img); 69 | } 70 | } 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/image.h: -------------------------------------------------------------------------------- 1 | int drawImage(const char* pngFileName); 2 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/ioflash/ioflash.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define kIOFlashStorageOptionBootPageIO 0x100 4 | #define kIOFlashStorageOptionRawPageIO 0x002 5 | #define kIOFlashStorageOptionXXXX 0x004 6 | //0xC0 == kIOFlashStorageOptionUseAES | kIOFlashStorageOptionHomogenize 7 | 8 | #define kIOFlashControllerReadPage 0x1 9 | #define kIOFlashControllerWritePage 0x2 10 | #define kIOFlashControllerDisableKeepout 0xa 11 | 12 | 13 | struct kIOFlashControllerReadPageIn; 14 | struct kIOFlashControllerOut; 15 | 16 | //from ioflashstoragetool 17 | CFMutableDictionaryRef MakeOneStringProp(CFStringRef key, CFStringRef value); 18 | io_service_t _wait_for_io_service_matching_dict(CFDictionaryRef matching); 19 | int FSDConnect(const char* name); 20 | int FSDGetPropertyForKey(io_object_t obj, CFStringRef name, void* out, uint32_t outLen, CFMutableDictionaryRef dict); 21 | void findPartitionLocation(CFStringRef contentHint, CFMutableDictionaryRef dict);//findNvramLocation 22 | IOReturn FSDReadPageHelper(struct kIOFlashControllerReadPageIn* in, struct kIOFlashControllerOut* out); 23 | IOReturn FSDReadPageWithOptions(uint32_t ceNum, uint32_t pageNum, void* buffer, void* spareBuffer, uint32_t spareSize, uint32_t options, struct kIOFlashControllerOut* out); 24 | IOReturn FSDReadBootPage(uint32_t ceNum, uint32_t pageNum,uint32_t* buffer, struct kIOFlashControllerOut* out); 25 | 26 | CFMutableDictionaryRef FSDGetInfo(int); 27 | int IOFlashStorage_kernel_patch(); 28 | 29 | CFDictionaryRef nand_dump(int fd); 30 | int dump_nand_to_socket(int fd); 31 | int nand_proxy(int fd); 32 | 33 | struct kIOFlashControllerReadPageIn 34 | { 35 | uint32_t page; 36 | uint32_t ce; 37 | uint32_t options; 38 | void* buffer; 39 | uint32_t bufferSize; 40 | void* spare; 41 | uint32_t spareSize; 42 | };//sizeof = 0x1C 43 | 44 | //sizeof=0x8 45 | struct kIOFlashControllerOut 46 | { 47 | uint32_t ret1; 48 | uint32_t ret2; 49 | }; 50 | 51 | //sizeof=0x50 AppleIOPFMIDMACommand? 52 | struct IOFlashCommandStruct 53 | { 54 | uint32_t flags0; 55 | uint32_t flags1; 56 | uint32_t field8; 57 | uint32_t fieldC; 58 | uint32_t* page_ptr; 59 | void* bufferDesc;//IOMemoryDescriptor* 60 | uint32_t field18; 61 | uint32_t field1C; 62 | uint32_t field20; 63 | uint32_t* ce_ptr; 64 | void* spareVA; 65 | uint32_t spareSize; 66 | uint32_t field30; 67 | uint32_t field34; 68 | uint32_t field38; 69 | uint32_t errorCode; 70 | uint32_t field40; 71 | uint32_t field44; 72 | uint32_t field48; 73 | uint32_t field4C; 74 | }; 75 | 76 | typedef struct IOExternalMethodArguments 77 | { 78 | uint32_t version; 79 | 80 | uint32_t selector; 81 | 82 | mach_port_t asyncWakePort; 83 | io_user_reference_t * asyncReference; 84 | uint32_t asyncReferenceCount; 85 | 86 | const uint64_t * scalarInput; 87 | uint32_t scalarInputCount; 88 | 89 | const void * structureInput; 90 | uint32_t structureInputSize; 91 | 92 | //IOMemoryDescriptor * structureInputDescriptor; 93 | void * structureInputDescriptor; 94 | 95 | uint64_t * scalarOutput; 96 | uint32_t scalarOutputCount; 97 | 98 | void * structureOutput; 99 | uint32_t structureOutputSize; 100 | 101 | void * structureOutputDescriptor; 102 | uint32_t structureOutputDescriptorSize; 103 | 104 | uint32_t __reservedA; 105 | 106 | //OSObject ** structureVariableOutputData; 107 | void ** structureVariableOutputData; 108 | 109 | uint32_t __reserved[30]; 110 | } IOExternalMethodArguments; 111 | 112 | typedef struct proxy_read_cmd 113 | { 114 | uint32_t ce; 115 | uint32_t page; 116 | uint32_t spareSize; 117 | uint32_t options; 118 | } proxy_read_cmd; 119 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/ioflash/ioflashstoragekit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "ioflash.h" 5 | #include "../util.h" 6 | 7 | #define LISTEN_PORT 2000 8 | 9 | #define CMD_DUMP 0 10 | #define CMD_PROXY 1 11 | 12 | int main(int argc, char* argv[]) 13 | { 14 | int one=1; 15 | int cmd=0; 16 | 17 | if(!IOFlashStorage_kernel_patch()) 18 | return -1; 19 | 20 | CFMutableDictionaryRef dict = FSDGetInfo(1); 21 | if(dict == NULL) 22 | { 23 | fprintf(stderr, "FAILed to get NAND infos"); 24 | return -1; 25 | } 26 | 27 | check_special_pages(); 28 | 29 | int sl = create_listening_socket(LISTEN_PORT); 30 | if(sl == -1) 31 | { 32 | fprintf(stderr, "Error calling create_listening_socket\n"); 33 | return -1; 34 | } 35 | 36 | fprintf(stderr, "NAND dumper listening on port %d\n", LISTEN_PORT); 37 | 38 | while(1) 39 | { 40 | int s = accept(sl, NULL, NULL); 41 | setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof(int)); 42 | 43 | int r = read(s, (void*) &cmd, sizeof(int)); 44 | if(r == sizeof(int)) 45 | { 46 | if(cmd == CMD_DUMP) 47 | { 48 | nand_dump(s); 49 | } 50 | else if(cmd == CMD_PROXY) 51 | { 52 | nand_proxy(s); 53 | } 54 | } 55 | shutdown(s, SHUT_RDWR); 56 | close(s); 57 | } 58 | return 0; 59 | } -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/kernel_patcher.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | mach_port_t kernel_task=0; 9 | 10 | kern_return_t write_kernel(mach_port_t p, void* addr, uint32_t value) 11 | { 12 | pointer_t buf; 13 | unsigned int sz; 14 | 15 | kern_return_t r = vm_write(p, (vm_address_t)addr, (vm_address_t)&value, sizeof(value)); 16 | if (r) 17 | { 18 | fprintf(stderr, "vm_write into kernel_task failed\n"); 19 | } 20 | else 21 | { 22 | //fix cache issue 23 | vm_read(p, (vm_address_t) addr, sizeof(value), &buf, &sz); 24 | fprintf(stderr, "vm_write into kernel_task OK %x\n", *((uint32_t*) buf)); 25 | } 26 | return r; 27 | } 28 | 29 | int patch_IOAESAccelerator() 30 | { 31 | kern_return_t r = task_for_pid(mach_task_self(), 0, &kernel_task); 32 | 33 | if( r != 0) 34 | { 35 | fprintf(stderr, "task_for_pid returned %x : missing tfp0 kernel patch or wrong entitlements\n", r); 36 | return 0; 37 | } 38 | uint32_t i; 39 | pointer_t buf; 40 | unsigned int sz; 41 | 42 | vm_address_t addr = 0x80002000; 43 | 44 | while( addr < (0x80002000 + 0xA00000)) 45 | { 46 | vm_read(kernel_task, addr, 2048, &buf, &sz); 47 | if( buf == NULL || sz == 0) 48 | continue; 49 | uint8_t* p = (uint8_t*) buf; 50 | 51 | for(i=0; i < sz; i++) 52 | { 53 | //"IOAESAccelerator enable UID" : (h("67 D0 40 F6"), h("00 20 40 F6")), 54 | if (*((uint32_t*)&p[i]) == 0xF640d067) 55 | { 56 | fprintf(stderr, "Found IOAESAccelerator UID ptr at %x, patching kernel\n", (uint32_t) addr + i); 57 | write_kernel(kernel_task, (void*) (addr + i), (uint32_t) 0xF6402000); 58 | return 0; 59 | } 60 | } 61 | addr += 2048; 62 | } 63 | fprintf(stderr, "IOAESAccelerator Kernel patching failed\n"); 64 | return -1; 65 | } 66 | 67 | /* 68 | int main(int argc, char** argv) 69 | { 70 | return patch_IOAESAccelerator(); 71 | } 72 | */ -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/keystore_device.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.keystore.device 6 | 7 | get-task-allow 8 | 9 | run-unsigned-code 10 | 11 | task_for_pid-allow 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/plist_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "plist_server.h" 9 | #include "util.h" 10 | 11 | #define TCP_PORT 1999 12 | 13 | int send_progress_message(int socket, int progress, int total) 14 | { 15 | const void* keys[3] = {CFSTR("MessageType"), CFSTR("Progress"), CFSTR("Total")}; 16 | const void* values[3] = {CFSTR("Progress"), NULL, NULL}; 17 | 18 | CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &progress); 19 | CFNumberRef number2 = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &total); 20 | values[1] = number; 21 | values[2] = number2; 22 | CFDictionaryRef msg = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 23 | CFRelease(number); 24 | CFRelease(number2); 25 | int res = send_object(socket, msg); 26 | CFRelease(msg); 27 | return res; 28 | } 29 | 30 | int send_object(int socket, CFTypeRef obj) 31 | { 32 | uint32_t len = 0; 33 | int res = -1; 34 | 35 | if(obj == NULL) 36 | return res; 37 | 38 | CFDataRef outdata = CFPropertyListCreateData(kCFAllocatorDefault, obj, kCFPropertyListXMLFormat_v1_0, 0, NULL); 39 | if (outdata != NULL) 40 | { 41 | len = CFDataGetLength(outdata); 42 | write(socket, &len, 4); 43 | res = write(socket, CFDataGetBytePtr(outdata), CFDataGetLength(outdata)); 44 | CFRelease(outdata); 45 | } 46 | return res; 47 | } 48 | 49 | int handle_client(int socket, CFDictionaryRef handlers) 50 | { 51 | uint32_t len=0; 52 | uint32_t received,i; 53 | CFDataRef data; 54 | CFDictionaryRef plist; 55 | CFTypeRef out = NULL; 56 | uint8_t* buffer; 57 | CFTypeRef (*handler)(int, CFDictionaryRef dict) = NULL; 58 | 59 | while(1) 60 | { 61 | if(recv(socket, &len, 4, 0) != 4) 62 | break; 63 | //printf("len=%x\n", len); 64 | 65 | if (len > PLIST_MAX_SIZE) 66 | break; 67 | 68 | buffer = malloc(len); 69 | 70 | if(buffer == NULL) 71 | break; 72 | 73 | for(i=0; i < len; ) 74 | { 75 | received = recv(socket, &buffer[i], len - i, 0); 76 | if (received == -1) 77 | break; 78 | i += received; 79 | } 80 | 81 | data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, buffer, len, kCFAllocatorNull); 82 | 83 | if(data == NULL) 84 | { 85 | free(buffer); 86 | continue; 87 | } 88 | 89 | plist = (CFDictionaryRef) CFPropertyListCreateWithData (kCFAllocatorDefault, data, kCFPropertyListImmutable, NULL, NULL); 90 | 91 | if(plist == NULL || CFGetTypeID(plist) != CFDictionaryGetTypeID()) 92 | { 93 | CFRelease(data); 94 | free(buffer); 95 | send_object(socket, CFSTR("invalid XML plist dictionary")); 96 | continue; 97 | } 98 | 99 | if (CFDictionaryContainsKey(plist, CFSTR("Request"))) 100 | { 101 | CFStringRef request = CFDictionaryGetValue(plist, CFSTR("Request")); 102 | 103 | handler = CFDictionaryGetValue(handlers, request); 104 | 105 | if (handler != NULL) 106 | { 107 | out = handler(socket, plist); 108 | if (out == NULL) 109 | out = CFSTR("Request did not return any result"); 110 | } 111 | else 112 | { 113 | out = CFSTR("No handler defined for Request"); 114 | } 115 | } 116 | else 117 | { 118 | out = CFSTR("request dictionary needs to contain Request key"); 119 | } 120 | 121 | if(out == NULL) 122 | out = CFSTR("no response"); 123 | 124 | send_object(socket, out); 125 | CFRelease(out); 126 | 127 | CFRelease(plist); 128 | CFRelease(data); 129 | free(buffer); 130 | } 131 | send_object(socket, CFSTR("kthxbye")); 132 | return 0; 133 | } 134 | 135 | void serve_plist_rpc(int port, CFDictionaryRef handlers) 136 | { 137 | int quit = 0; 138 | int one=1; 139 | printf("plist_rpc: listening on port %d\n", port); 140 | int sl = create_listening_socket(port); 141 | 142 | while(!quit) 143 | { 144 | int s = accept(sl, NULL, NULL); 145 | setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof(int)); 146 | 147 | handle_client(s, handlers); 148 | shutdown(s, SHUT_RDWR); 149 | close(s); 150 | } 151 | close(sl); 152 | } 153 | 154 | CFStringRef testHandler(int s, CFDictionaryRef dict) 155 | { 156 | printf("lol\n"); 157 | return CFSTR("Hello, World!"); 158 | } 159 | 160 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/plist_server.h: -------------------------------------------------------------------------------- 1 | #define PLIST_MAX_SIZE 50*1024*1024 2 | 3 | int create_listening_socket(int port); 4 | int send_progress_message(int socket, int progress, int total); 5 | int send_object(int socket, CFTypeRef obj); 6 | void serve_plist_rpc(int port, CFDictionaryRef handlers); -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/registry.h: -------------------------------------------------------------------------------- 1 | void get_device_infos(CFMutableDictionaryRef out); -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/remote_functions.h: -------------------------------------------------------------------------------- 1 | 2 | CFDictionaryRef load_system_keybag(int socket, CFDictionaryRef dict); 3 | CFDictionaryRef bruteforce_system_keybag(int socket, CFDictionaryRef dict); 4 | CFDictionaryRef keybag_get_passcode_key(int socket, CFDictionaryRef dict); 5 | CFDictionaryRef get_escrow_record(int socket, CFDictionaryRef dict); 6 | CFDictionaryRef download_file(int socket, CFDictionaryRef dict); 7 | CFDictionaryRef remote_aes(int socket, CFDictionaryRef dict); 8 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/scripts/mount_partitions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -a /dev/disk0s1s2 ]; then # test for iOS 5 data partition 4 | mount_hfs /dev/disk0s1s1 /mnt1 2>/dev/null 5 | mount_hfs /dev/disk0s1s2 /mnt2 2>/dev/null 6 | elif [ -a /dev/disk0s2s1 ]; then # test for iOS 4 data partition 7 | mount_hfs /dev/disk0s1 /mnt1 2>/dev/null 8 | mount_hfs /dev/disk0s2s1 /mnt2 2>/dev/null 9 | elif [ -a /dev/disk0s2 ]; then 10 | mount_hfs /dev/disk0s1 /mnt1 2>/dev/null 11 | mount_hfs /dev/disk0s2 /mnt2 2>/dev/null 12 | else 13 | echo "Error mounting partitions. Please try it manually" 14 | fi -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/shsh_dump.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | //#include 4 | //#include 5 | #include 6 | #include 7 | #include 8 | #include "ioflash/ioflash.h" 9 | #include "util.h" 10 | 11 | struct IMG2 12 | { 13 | uint32_t magic; 14 | uint32_t block_size; 15 | uint32_t images_offset; 16 | uint32_t images_block; 17 | uint32_t images_length; 18 | uint8_t padding[0x1c]; 19 | uint32_t crc32; 20 | }; 21 | 22 | struct IMG3 23 | { 24 | uint32_t magic; 25 | uint32_t fullSize; 26 | uint32_t sizeNoPack; 27 | uint32_t sigCheckArea; 28 | uint32_t iden; 29 | }; 30 | 31 | struct IMG3_TLV 32 | { 33 | uint32_t tag; 34 | uint32_t total_length; 35 | uint32_t data_length; 36 | uint8_t payload[1]; 37 | }; 38 | 39 | void printIMG2(struct IMG2* s) 40 | { 41 | printf("magic= %x\n", s->magic); 42 | printf("block_size= %x\n", s->block_size); 43 | printf("images_offset= %x\n", s->images_offset); 44 | printf("images_block= %x\n", s->images_block); 45 | printf("images_length= %x\n", s->images_length); 46 | } 47 | void printIMG3(struct IMG3* s) 48 | { 49 | char iden[10]={0}; 50 | memcpy(iden, &s->iden, 4); 51 | printf("magic= %x\n", s->magic); 52 | printf("fullSize= %x\n", s->fullSize); 53 | printf("iden= %s\n", iden); 54 | } 55 | 56 | CFDataRef getIMG3Data(struct IMG3* img3) 57 | { 58 | CFDataRef data = NULL; 59 | uint8_t* p = (uint8_t*) img3; 60 | uint8_t* z = &p[20]; 61 | 62 | if(img3->magic != 'Img3') 63 | return NULL; 64 | 65 | while(z < &p[img3->fullSize]) 66 | { 67 | struct IMG3_TLV* item = (struct IMG3_TLV*) z; 68 | if( item->tag == 'DATA') 69 | { 70 | data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, item->payload, item->data_length, NULL); 71 | return data; 72 | } 73 | z += item->total_length; 74 | } 75 | return NULL; 76 | } 77 | 78 | 79 | extern uint32_t gPagesPerBlock; 80 | extern uint32_t gBytesPerPage ; 81 | extern uint32_t gBootloaderBytes ; 82 | 83 | int main(int argc, char* argv[]) 84 | { 85 | int one=1; 86 | int cmd=0; 87 | 88 | CFMutableDictionaryRef dict = FSDGetInfo(1); 89 | if (dict == NULL) 90 | { 91 | fprintf(stderr, "FAILed to get NAND infos"); 92 | return -1; 93 | } 94 | if(!IOFlashStorage_kernel_patch()) 95 | return -1; 96 | 97 | struct kIOFlashControllerOut out; 98 | uint32_t bootSize = gBootloaderBytes * gPagesPerBlock * 8; 99 | 100 | printf("Mallocing %x bytes for boot partition\n", bootSize); 101 | uint8_t* boot = malloc(bootSize); 102 | if( boot == NULL) 103 | { 104 | return -1; 105 | } 106 | 107 | uint8_t* buffer = malloc(gBytesPerPage); 108 | if( buffer == NULL) 109 | { 110 | return -1; 111 | } 112 | 113 | uint32_t block, page, off=0; 114 | 115 | for(block=8; block < 16; block++) 116 | { 117 | for(page=0; page < gPagesPerBlock; page++) 118 | { 119 | if(FSDReadBootPage(0, block*gPagesPerBlock + page, buffer, &out)) 120 | { 121 | //printf("FSDReadBootPage error %x\n", block*gPagesPerBlock + page); 122 | //return -1; 123 | } 124 | memcpy(&boot[off], buffer, gBootloaderBytes); 125 | off += gBootloaderBytes; 126 | } 127 | } 128 | 129 | printIMG2((struct IMG2*) boot); 130 | struct IMG2* img2 = (struct IMG2*) boot; 131 | 132 | if( img2->magic != 0x494d4732) 133 | { 134 | printf("Bag IMG2 magic : %x\n", img2->magic); 135 | return -1; 136 | } 137 | uint32_t start = img2->block_size * img2->images_block; 138 | 139 | uint32_t end = start + img2->block_size * img2->images_length; 140 | 141 | if( end < start) 142 | { 143 | return -1; 144 | } 145 | printf("start %x end %x\n", start, end); 146 | uint8_t* p = &boot[start]; 147 | 148 | CFMutableDictionaryRef resultsDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 149 | 150 | if(dict == NULL) 151 | { 152 | return -1; 153 | } 154 | 155 | while(p < &boot[end]) 156 | { 157 | struct IMG3* img3 = (struct IMG3*) p; 158 | if(img3->magic != 'Img3') 159 | break; 160 | printIMG3(img3); 161 | 162 | if(img3->iden == 'SCAB') 163 | { 164 | CFDataRef data = getIMG3Data(img3); 165 | if(data) 166 | { 167 | CFDictionaryAddValue(resultsDict, CFSTR("APTicket"), data); 168 | writePlistToStdout(resultsDict); 169 | CFRelease(data); 170 | } 171 | } 172 | p += img3->fullSize; 173 | 174 | } 175 | return 0; 176 | } -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/tfp0.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | get-task-allow 6 | 7 | run-unsigned-code 8 | 9 | task_for_pid-allow 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/util.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "util.h" 12 | 13 | void printBytesToHex(const uint8_t* buffer, size_t bytes) 14 | { 15 | while(bytes > 0) { 16 | printf("%02x", *buffer); 17 | buffer++; 18 | bytes--; 19 | } 20 | } 21 | 22 | void printHexString(const char* description, const uint8_t* buffer, size_t bytes) 23 | { 24 | printf("%s : ", description); 25 | printBytesToHex(buffer, bytes); 26 | printf("\n"); 27 | } 28 | 29 | int write_file(const char* filename, uint8_t* data, size_t len) 30 | { 31 | int fd = open(filename, O_CREAT | O_RDWR); 32 | if (fd < 0) 33 | return -1; 34 | if (write(fd, data, len) != len) 35 | return -1; 36 | close(fd); 37 | return 0; 38 | } 39 | 40 | void writePlistToStdout(CFDictionaryRef out) 41 | { 42 | CFDataRef d = CFPropertyListCreateData(kCFAllocatorDefault, out, kCFPropertyListXMLFormat_v1_0, 0, NULL); 43 | if (d == NULL) 44 | return; 45 | write(1, CFDataGetBytePtr(d), CFDataGetLength(d)); 46 | } 47 | 48 | int mountDataPartition(const char* mountpoint) 49 | { 50 | char* diskname = "/dev/disk0s2s1"; 51 | int err; 52 | printf("Trying to mount data partition\n"); 53 | err = mount("hfs","/mnt2", MNT_RDONLY | MNT_NOATIME | MNT_NODEV | MNT_LOCAL, &diskname); 54 | if (!err) 55 | return 0; 56 | 57 | diskname = "/dev/disk0s1s2"; 58 | err = mount("hfs","/mnt2", MNT_RDONLY | MNT_NOATIME | MNT_NODEV | MNT_LOCAL, &diskname); 59 | if (!err) 60 | return 0; 61 | diskname = "/dev/disk0s2"; 62 | err = mount("hfs","/mnt2", MNT_RDONLY | MNT_NOATIME | MNT_NODEV | MNT_LOCAL, &diskname); 63 | 64 | return err; 65 | } 66 | 67 | 68 | int getHFSInfos(struct HFSInfos *infos) 69 | { 70 | char buf[8192] = {0}; 71 | struct HFSPlusVolumeHeader* header; 72 | unsigned int i; 73 | 74 | int fd = open("/dev/rdisk0s2", O_RDONLY); 75 | if (fd < 0 ) 76 | fd = open("/dev/rdisk0s1s2", O_RDONLY); //ios5 lwvm 77 | if (fd < 0 ) 78 | return fd; 79 | lseek(fd, 0, SEEK_SET); 80 | 81 | if (read(fd, buf, 8192) != 8192) 82 | return -1; 83 | close(fd); 84 | 85 | header = (struct HFSPlusVolumeHeader*) &buf[0x400]; 86 | 87 | uint32_t blockSize = CFSwapInt32BigToHost(header->blockSize); 88 | 89 | infos->volumeUUID = header->volumeUUID; 90 | infos->blockSize = blockSize; 91 | 92 | if (blockSize != 0x1000 && blockSize != 0x2000) 93 | { 94 | fprintf(stderr, "getHFSInfos: Unknown block size %x\n", blockSize); 95 | } 96 | else 97 | { 98 | fd = open("/dev/rdisk0", O_RDONLY); 99 | if (fd < 0 ) 100 | return fd; 101 | 102 | if (read(fd, buf, 8192) != 8192) 103 | return -1; 104 | 105 | if (!memcmp(buf, LwVMType, 16)) 106 | { 107 | LwVM* lwvm = (LwVM*) buf; 108 | 109 | if (lwvm->chunks[0] != 0xF000) 110 | { 111 | fprintf(stderr, "getHFSInfos: lwvm->chunks[0] != 0xF000\n"); 112 | return -1; 113 | } 114 | 115 | for(i=0; i < 0x400; i++) 116 | { 117 | if(lwvm->chunks[i] == 0x1000) //partition 1 block 0 118 | { 119 | break; 120 | } 121 | } 122 | uint32_t LwVM_rangeShiftValue = 32 - __builtin_clz((lwvm->mediaSize - 1) >> 10); 123 | 124 | infos->dataVolumeOffset = (i << LwVM_rangeShiftValue) / blockSize; 125 | } 126 | else 127 | { 128 | lseek(fd, 2*blockSize, SEEK_SET); 129 | 130 | if (read(fd, buf, 8192) != 8192) 131 | return -1; 132 | close(fd); 133 | 134 | infos->dataVolumeOffset = ((unsigned int*)buf)[0xA0/4]; 135 | } 136 | } 137 | return 0; 138 | } 139 | 140 | CFMutableStringRef CreateHexaCFString(uint8_t* buffer, size_t len) 141 | { 142 | int i; 143 | 144 | CFMutableStringRef s = CFStringCreateMutable(kCFAllocatorDefault, len*2); 145 | 146 | for(i=0; i < len; i++) 147 | { 148 | CFStringAppendFormat(s, NULL, CFSTR("%02x"), buffer[i]); 149 | } 150 | return s; 151 | } 152 | 153 | void addHexaString(CFMutableDictionaryRef out, CFStringRef key, uint8_t* buffer, size_t len) 154 | { 155 | CFMutableStringRef s = CreateHexaCFString(buffer, len); 156 | CFDictionaryAddValue(out, key, s); 157 | CFRelease(s); 158 | } 159 | 160 | void saveResults(CFStringRef filename, CFMutableDictionaryRef out) 161 | { 162 | CFURLRef fileURL = CFURLCreateWithFileSystemPath( NULL, filename, kCFURLPOSIXPathStyle, FALSE); 163 | CFWriteStreamRef stream = CFWriteStreamCreateWithFile( NULL, fileURL); 164 | CFWriteStreamOpen(stream); 165 | CFPropertyListWriteToStream(out, stream, kCFPropertyListXMLFormat_v1_0, NULL); 166 | CFWriteStreamClose(stream); 167 | 168 | CFRelease(stream); 169 | CFRelease(fileURL); 170 | } 171 | 172 | int create_listening_socket(int port) 173 | { 174 | struct sockaddr_in listen_addr; 175 | int s, one = 1; 176 | 177 | memset(&listen_addr, 0, sizeof(struct sockaddr)); 178 | listen_addr.sin_family = AF_INET; 179 | listen_addr.sin_port = htons(port); 180 | listen_addr.sin_addr.s_addr = INADDR_ANY; 181 | 182 | s = socket(AF_INET, SOCK_STREAM, 0); 183 | 184 | setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); 185 | 186 | if (bind(s, (struct sockaddr *)&listen_addr, sizeof(struct sockaddr)) < 0) 187 | { 188 | perror("bind"); 189 | return -1; 190 | } 191 | listen(s, 10); 192 | 193 | return s; 194 | } 195 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/ramdisk_tools/util.h: -------------------------------------------------------------------------------- 1 | struct HFSInfos { 2 | uint64_t volumeUUID; 3 | uint32_t blockSize; 4 | uint32_t dataVolumeOffset; 5 | }; 6 | 7 | struct HFSPlusVolumeHeader { 8 | uint16_t signature; 9 | uint16_t version; 10 | uint32_t attributes; 11 | uint32_t lastMountedVersion; 12 | uint32_t journalInfoBlock; 13 | 14 | uint32_t createDate; 15 | uint32_t modifyDate; 16 | uint32_t backupDate; 17 | uint32_t checkedDate; 18 | 19 | uint32_t fileCount; 20 | uint32_t folderCount; 21 | 22 | uint32_t blockSize; 23 | uint32_t totalBlocks; 24 | uint32_t freeBlocks; 25 | 26 | uint32_t nextAllocation; 27 | uint32_t rsrcClumpSize; 28 | uint32_t dataClumpSize; 29 | uint32_t nextCatalogID; 30 | 31 | uint32_t writeCount; 32 | uint64_t encodingsBitmap; 33 | 34 | uint32_t finderInfo[6]; 35 | uint64_t volumeUUID; 36 | /* 37 | HFSPlusForkData allocationFile; 38 | HFSPlusForkData extentsFile; 39 | HFSPlusForkData catalogFile; 40 | HFSPlusForkData attributesFile; 41 | HFSPlusForkData startupFile;*/ 42 | } __attribute__((packed)); 43 | 44 | //https://github.com/iDroid-Project/openiBoot/blob/master/openiboot/includes/bdev.h 45 | typedef struct _LwVMPartitionRecord { 46 | uint64_t type[2]; 47 | uint64_t guid[2]; 48 | uint64_t begin; 49 | uint64_t end; 50 | uint64_t attribute; // 0 == unencrypted; 0x1000000000000 == encrypted 51 | char partitionName[0x48]; 52 | } __attribute__ ((packed)) LwVMPartitionRecord; 53 | 54 | typedef struct _LwVM { 55 | uint64_t type[2]; 56 | uint64_t guid[2]; 57 | uint64_t mediaSize; 58 | uint32_t numPartitions; 59 | uint32_t crc32; 60 | uint8_t unkn[464]; 61 | LwVMPartitionRecord partitions[12]; 62 | uint16_t chunks[1024]; // chunks[0] should be 0xF000 63 | } __attribute__ ((packed)) LwVM; 64 | 65 | static const char LwVMType[] = { 0x6A, 0x90, 0x88, 0xCF, 0x8A, 0xFD, 0x63, 0x0A, 0xE3, 0x51, 0xE2, 0x48, 0x87, 0xE0, 0xB9, 0x8B }; 66 | 67 | int getHFSInfos(struct HFSInfos *infos); 68 | 69 | CFMutableStringRef CreateHexaCFString(uint8_t* buffer, size_t len); 70 | 71 | void printBytesToHex(const uint8_t* buffer, size_t bytes); 72 | void printHexString(const char* description, const uint8_t* buffer, size_t bytes); 73 | int write_file(const char* filename, uint8_t* data, size_t len); 74 | 75 | void addHexaString(CFMutableDictionaryRef out, CFStringRef key, uint8_t* buffer, size_t len); 76 | void saveResults(CFStringRef filename, CFMutableDictionaryRef out); 77 | void writePlistToStdout(CFDictionaryRef out); 78 | 79 | int mountDataPartition(const char* mountpoint); 80 | 81 | int create_listening_socket(int port); -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/tcprelay.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | python usbmuxd-python-client/tcprelay.py -t 22:2222 1999:1999 4 | 5 | -------------------------------------------------------------------------------- /vendor/iphone-dataprotection/usbmuxd-python-client/tcprelay.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # tcprelay.py - TCP connection relay for usbmuxd 5 | # 6 | # Copyright (C) 2009 Hector Martin "marcan" 7 | # 8 | # This program is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 2 or version 3. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | import usbmux 22 | import SocketServer 23 | import select 24 | from optparse import OptionParser 25 | import sys 26 | import threading 27 | 28 | class SocketRelay(object): 29 | def __init__(self, a, b, maxbuf=65535): 30 | self.a = a 31 | self.b = b 32 | self.atob = "" 33 | self.btoa = "" 34 | self.maxbuf = maxbuf 35 | def handle(self): 36 | while True: 37 | rlist = [] 38 | wlist = [] 39 | xlist = [self.a, self.b] 40 | if self.atob: 41 | wlist.append(self.b) 42 | if self.btoa: 43 | wlist.append(self.a) 44 | if len(self.atob) < self.maxbuf: 45 | rlist.append(self.a) 46 | if len(self.btoa) < self.maxbuf: 47 | rlist.append(self.b) 48 | rlo, wlo, xlo = select.select(rlist, wlist, xlist) 49 | if xlo: 50 | return 51 | if self.a in wlo: 52 | n = self.a.send(self.btoa) 53 | self.btoa = self.btoa[n:] 54 | if self.b in wlo: 55 | n = self.b.send(self.atob) 56 | self.atob = self.atob[n:] 57 | if self.a in rlo: 58 | s = self.a.recv(self.maxbuf - len(self.atob)) 59 | if not s: 60 | return 61 | self.atob += s 62 | if self.b in rlo: 63 | s = self.b.recv(self.maxbuf - len(self.btoa)) 64 | if not s: 65 | return 66 | self.btoa += s 67 | #print "Relay iter: %8d atob, %8d btoa, lists: %r %r %r"%(len(self.atob), len(self.btoa), rlo, wlo, xlo) 68 | 69 | class TCPRelay(SocketServer.BaseRequestHandler): 70 | def handle(self): 71 | print "Incoming connection to %d"%self.server.server_address[1] 72 | mux = usbmux.USBMux(options.sockpath) 73 | print "Waiting for devices..." 74 | if not mux.devices: 75 | mux.process(1.0) 76 | if not mux.devices: 77 | print "No device found" 78 | self.request.close() 79 | return 80 | dev = mux.devices[0] 81 | print "Connecting to device %s"%str(dev) 82 | dsock = mux.connect(dev, self.server.rport) 83 | lsock = self.request 84 | print "Connection established, relaying data" 85 | try: 86 | fwd = SocketRelay(dsock, lsock, self.server.bufsize * 1024) 87 | fwd.handle() 88 | finally: 89 | dsock.close() 90 | lsock.close() 91 | print "Connection closed" 92 | 93 | class TCPServer(SocketServer.TCPServer): 94 | allow_reuse_address = True 95 | 96 | class ThreadedTCPServer(SocketServer.ThreadingMixIn, TCPServer): 97 | pass 98 | 99 | HOST = "localhost" 100 | 101 | parser = OptionParser(usage="usage: %prog [OPTIONS] RemotePort[:LocalPort] [RemotePort[:LocalPort]]...") 102 | parser.add_option("-t", "--threaded", dest='threaded', action='store_true', default=False, help="use threading to handle multiple connections at once") 103 | parser.add_option("-b", "--bufsize", dest='bufsize', action='store', metavar='KILOBYTES', type='int', default=128, help="specify buffer size for socket forwarding") 104 | parser.add_option("-s", "--socket", dest='sockpath', action='store', metavar='PATH', type='str', default=None, help="specify the path of the usbmuxd socket") 105 | 106 | options, args = parser.parse_args() 107 | 108 | serverclass = TCPServer 109 | if options.threaded: 110 | serverclass = ThreadedTCPServer 111 | 112 | if len(args) == 0: 113 | parser.print_help() 114 | sys.exit(1) 115 | 116 | ports = [] 117 | 118 | for arg in args: 119 | try: 120 | if ':' in arg: 121 | rport, lport = arg.split(":") 122 | rport = int(rport) 123 | lport = int(lport) 124 | ports.append((rport, lport)) 125 | else: 126 | ports.append((int(arg), int(arg))) 127 | except: 128 | parser.print_help() 129 | sys.exit(1) 130 | 131 | servers=[] 132 | 133 | for rport, lport in ports: 134 | print "Forwarding local port %d to remote port %d"%(lport, rport) 135 | server = serverclass((HOST, lport), TCPRelay) 136 | server.rport = rport 137 | server.bufsize = options.bufsize 138 | servers.append(server) 139 | 140 | alive = True 141 | 142 | while alive: 143 | try: 144 | rl, wl, xl = select.select(servers, [], []) 145 | for server in rl: 146 | server.handle_request() 147 | except: 148 | alive = False 149 | -------------------------------------------------------------------------------- /vendor/vfdecrypt/Makefile: -------------------------------------------------------------------------------- 1 | linux: 2 | gcc -o vfdecrypt vfdecrypt.c -lcrypto 3 | mac: 4 | gcc -o vfdecrypt vfdecrypt.c -lcrypto -DMAC_OSX 5 | install: 6 | cp ./vfdecrypt /usr/local/bin 7 | ldconfig 8 | uninstall: 9 | rm -rf /usr/local/bin/vfdecrypt 10 | clean: 11 | rm -rf ./vfdecrypt 12 | -------------------------------------------------------------------------------- /vendor/vfdecrypt/README: -------------------------------------------------------------------------------- 1 | This is a cross platform dmg decryption tool. Maintained by quasarboi, but credit goes to its original owner. 2 | 3 | To build on Linux, run "make linux"; 4 | To build on Mac, run "make mac"; 5 | To install, run "sudo make install"; 6 | To run, run "vfdecrypt"; 7 | To clean, run "make clean"; 8 | To uninstall, run "sudo make uninstall". 9 | 10 | Usage: vfdecrypt -i in-file [-p password] [-k key] -o out-file 11 | 12 | NOTICE: The -i and -o flags are extremely important, as without them, the program will never terminate unless forced to. 13 | NOTICE: ONLY the -k -i and -o flags have been tested. 14 | 15 | Depends: 16 | libssl0.9.8 17 | 18 | Example: 19 | Decrypting iOS 4 in your home directory. 20 | Once the program is compiled and installed, run: 21 | 22 | "vfdecrypt -i name_of_root_filesystem.dmg -k ec6eb0268c4e9f8ab9d003f601e8f4b36f4fc4311c61e5ebed07ce718424ffee7e7d924d -o decrypted.dmg" --------------------------------------------------------------------------------