Practical iOS Applications Hacking WP
Practical iOS Applications Hacking WP
3 Accepted Papers
3.1
3.1.1
@GoToHack Mathieu Renard GoToHack is a Senior Penetration tester, working for a French company (SOGETI-ESEC) where is leading the penetration test team. His research areas focus in Web Application Security, Embedded Systems, Hardware hacking and recently Mobile device Security. Since last year, he has focused is work (security assessments) and his research on professional iOS applications and their supporting architecture where data security is paramount. twitter: @GoToHack 3.1.2 Practical iOS Apps hacking
This talk demonstrates how professional applications like, Mobile Device Management (MDM) Client, Condential contents manager (Sandbox), professional media players and other applications handling sensitive data are attacked and sometimes easily breached. This talk is designed to demonstrate many of the techniques attackers use to manipulate iOS applications in order to extract condential data from the device. In this talk, the audience will see examples of the worst practices we are dealing with every day when pentesting iOS applications and learn how to mitigate the risks and avoid common mistakes that leave applications exposed. Attendees will gain a basic understanding of how these attacks are executed, and many examples and demonstrations of how to code more securely in ways that wont leave applications exposed to such attacks. This talk will focus especially on the following features: Secure Data Storage Secure Password Storage Secure communication Jailbreak detection Defensive tricks Talk and paper can be downloaded from http://grehack.org
14 / 61
GreHack
Mathieu RENARD
Sogeti ESEC / GotoHack.org Paris, FRANCE mathieu.renard[-AT-]gotohack.org
This paper demonstrates how professional applications like, Mobile Device Management (MDM) Client, Confidential contents manager (Sandbox), professional media players and other applications handling sensitive data are attacked and sometimes easily breached. Readers will gain a basic understanding of how these attacks are executed, and many examples of how to code more securely in ways that will not leave applications exposed to such attacks.
that can allow retrieving confidential information stored by miss implemented iOS application. 1) Using afc protocol to retrieve data stored on the device Apple File Communication Protocol (AFC) is a serial port protocol that uses a framework called MobileDevice that is installed by default with iTunes. Since 2010 this protocol is implemented in the libimobiledevice[8] open-sources project. The protocol uses the USB Port and cable when it is connected to the computer and is responsible for things such as copying music and photos and installing firmware upgrades. AFC Clients like iTunes are allowed access to a jailed or limited area of the device memory. Actually, AFC clients can only access to certain files, namely those located in the Media and User installed applications folders. In other words, using AFC client a user/attacker can download the application resources and data. Including the default preferences file where sometimes credentials are stored. The only requirement is the device has to be unlocked. But this is definitively not a problem because an evil maid cans backdoor any iDevice Dock Station.
I. INTRODUCTION Gone are the days when employees only used a companyissued phone for work related matters. Today, employees bring personal smart phones and tablets to the office and often have access to sensitive company information on these devices. This paper is the result of one-year pentesting iOS application and is designed to demonstrate many of the techniques attackers use to manipulate iOS applications in order to extract confidential data from the device. Then, Jailbreak detection features are analyzed before discussing the results of tests launched on professional applications like, Mobile Device Management (MDM) Client, Confidential contents manager (Sandbox), professional media players and other applications handling sensitive data. Finally the author proposes mitigation techniques to implement in order to avoid common mistakes that leave applications exposed.
II. ATTACKING IOS APPLICATIONS Most of the time attacking iOS application is synonym to jailbreak an iDevice, decrypt the application and reverse the binaries. Before developing these items there is some interesting points to linger on, especially on regular devices. A. What attackers can do without jailbreaking the device Without having access to the file system it is impossible de decrypt and reverse iOS applications installed from Apple App Store. Nevertheless, this section present attacks vectors
15 / 61
GreHack
Application & Item type WiFi Password IMAP/POP/SMTP accounts Exchange Accounts VPN LDAP/CalDAV/CardDAV Accounts iTunes backup password Device Certificate & private Key
Using the iphonedataprotection[1] tools developed by Jean-Baptiste Bdrune and Jean Sigwald of Sogeti ESEC, it is possible to extract all data stored in the keychain. Nonetheless, only data stored without the ThisDeviceOnly protection class can be extracted without requiring any jailbreak. Notice: Extracting data stored with the ThisDeviceOnly protection class require to previously extracting the 0x835 key the attack is detailed in the next section. 3) Monitoring communication Monitoring communication can highlights lack of encryption allowing unsecured credential gathering. Starting iOS 5, apple added a remote virtual interface (RVI) facility that allows capturing traces from an iOS device. On Mac OSX the virtual interface can be enabled with the rvictl command.
Since the sync option is defined on the computer side, no user interaction except unlocking the device is required. This implementation allows malicious dock station to initiate backups without user authorization. Performing such attack an attacker may retrieve personal and confidential data like copies of SMS, Call Logs, application data, default preferences and data stored in the keychain. Keychain class keys define whether a keychain item can be migrated to other device or not. List of protection classes available for the keychain items are shown in the table bellow.
TABLE II. Protection class kSecAttrAccessibleWhenUnlocked KEYCHAIN CLASS KEYS Description Keychain item is accessible only after the device is unlocked Keychain item is accessible only after the first unlock of the device to till reboot Keychain item is accessible even the device is locked Keychain item is accessible only after the device is unlocked and the item cannot be migrated between devices Keychain item is accessible after the first unlock of the device and the item cannot be migrated Keychain item is accessible even the device is locked and the item cannot be migrated
$ rvictl -s 454b673c547582234decef5ef3abce6765506af45 Starting device 454b673c547582234decef5ef3abce6765506af45 [SUCCEEDED] $ # network interface, rvi0, added by the previous command. $ ifconfig -l lo0 gif0 stf0 en0 en1 p2p0 fw0 ppp0 utun0 rvi0 $ sudo tcpdump -i rvi0 -n listening on rvi0, link-type RAW (Raw IP), capture size 65535 bytes
kSecAttrAccessibleAfterFirstUnlock kSecAttrAccessibleAlways
kSecAttrAccessibleWhenUnlocked ThisDeviceOnly
On other system this can be done using the com.apple.pcapd service through the usbmux[8] deamon. 4) Attacking secure communications to servers Almost every application handling sensitive data will connect back to some server component. Developers are, thus, faced with the challenge of having to protect sensitive data in transit as it traverses the Internet and sometimes even insecure wireless media. This can be done using encryption but must be implemented correctly.
kSecAttrAccessibleAfterFirstUnlock ThisDeviceOnly
kSecAttrAccessibleAlways ThisDeviceOnly
16 / 61
GreHack
2) Retrieving the 0x835 Key Browsing the keychain content on a jailbroken is not really difficult. On the opposite, extracting all data including data stored within the ThisDeviceOnly protection class form a backup require extracting the 0x835 key. The 0x835 key is generated by encrypting 01010101010101010101010101010101 with the UIDkey (Hardware key). Hardware keys can only be accessed from kernel. Therefore, IOAESAccelerator kernel service has to be patched in order to allow keys access from user land. The iPhoneDataProtection framework embeds tools allowing patching the kernel and retrieving the 0x835 key.
17 / 61
GreHack
18 / 61
GreHack
4) Where to start ? To start the analysis in the right way we have to locate the main class. The UIApplicationDelegate protocol declares methods that are implemented by the delegate of a UIApplication object. These methods provide information about key events in an applications execution such as when it finished launching, when it is about to be terminated, when memory is low, and when important changes occur. Finding one of the following methods: ApplicationDidFinishLaunching, ApplicationDidFinishLaunchingWithOptions, Application* is a good way to find out which view is launched first. Regarding the views initialization, The UIViewController class provides specific methods that are called when specific events occur. When trying to follow the execution patch the main event to focus our intention is viewDidLoad that is called after views initialization. 5) Where to look ? The list of points to focus on when reversing iOS Application is related to the features of the application to be analyzed. Here is a list of object that may have an interest regarding security matters.
TABLE IV. INTERESTING OBJECTS, CLASSES & METHODS Objects / Classes / Methods NSURL* CFSocket* ksecAttr*, SecKeychain* NSFileManager* CCCrypt*
Use case URL Handling Socket Handling Keychain Files Handling Crypto
D. Dynamic analysis There are many different approaches to dynamic analysis. In this section we will focus on the MobileSubstrate[6] framework.
static int (*old_system)(char *) = NULL; int st_system(char * cmd){ if (!cmd){ return nil; } return old_system(cmd); } __attribute__((constructor)) static void initialize() { MSHookFunction(system, st_system,&old_system); }
19 / 61
GreHack
+ (BOOL)doFstabSize { struct stat sb; stat("/etc/fstab", &sb); long long size = sb.st_size; if (size == 80){ return NO; return YES; }
CCCrypt(CCOperation op, CCAlgorithm alg, CCOptions options, const void *key, size_t keyLength, const void *iv, const void *dataIn, size_t dataInLength, void *dataOut, size_t dataOutAvailable, size_t *dataOutMoved);
This test can easily be bypassed by hooking the stat system call within a mobile substrate extension. C. Checking for shell By default no shell is available on regular device but it comes with the public jailbreak. This is why this test aims to detect if a shell is available on the device by calling system(0). If the value of command is NULL, system() returns nonzero if the shell is available, and zero if not.
III. JAILBREAK DETECTION FEATURES [THE TRUTH] Jailbreak detection features are implanted in order to detect when an end user has compromised their device, or to detect whether an intruder has compromised a stolen device. For example, all MDM application embeds jailbreak detection features. The following sections present common and uncommon jailbreak detection features highlighted during one year studying iOS application security. A. Checking for jailbreak files This is the most common check performed on the application we analyzed. Usually applications are checking for files like: /Applications/Cydia.app, /bin/apt,/usr/sbin/sshd
This test can easily be bypassed with a mobile substrate extension (See Figure 7).
20 / 61
GreHack
+ (BOOL)doSignerIdentity { NSBundle *bundle = [NSBundle mainBundle]; NSDictionary *info = [bundle infoDictionary]; if ([info objectForKey: @"SignerIdentity"] != nil){ NSLog(@"App have has been hacked"); return YES; } return NO; }
This test is designed to overcome automated processes at best, and will probably only defeating most tutorial-followers. An attacker can hexedit the binary file and as such, could edit the string @"SignerIdentity" to read @"siNGerIDentitY" or something else which would return nil, and thus pass. This test can also by bypassed by hooking objectForKey and return nil. E. Less commons Jailbreak checks Less commons jailbreak checks are using system calls: Fork(): Documented in some books and blog posts: If the process can fork, the device is jailbroken. Except this check producing a lot of logs in the console, and most important does not work because the jailbreak does not patch this part of the sandbox. See the iPhone Wiki [12] for details about jailbreak patchs. Open(): Trying to open a file in write mode in a not writable path outside the sandbox: if no error the device is not jailbroken. Like other jailbreak detection functions presented in this section system calls can easily being hooked in order to hide the jailbreak. F. Conclusion: Jailbreak detection = Fail by design! Despite this test are interesting and probably stops most of the script kiddies, tutorial follower and automating tools, skillful attackers can bypass them. The thing is that Apple does not provide any API to launch action either before or after the installation. As a result attackers are able to decrypt and analyze applications before they could launch their jailbreak detection tests. Moreover after jailbreak the attackers have root access to the device, which means to control everything on the device as the opposite of iOS application. Nevertheless, when well implemented, jailbreak detection features can discourage most of script kiddies and tutorial followers.
B. Authentication Bypass Here the password defined by the user is stored on the file system in an encrypted database. The problem is that the application has to decrypt the database before the user being authenticated in order to check the password validity. Since the database is decrypted before the user was authenticated it is possible for an attacker, having an access to an unlocked jailbroken device to retrieve the password in the memory. C. Unsecure data storage This example was highlighted during the analysis of a sandbox like application. According to the documentation the application is using "high grade encryption to secure the document. iExplorer is an iPhone browser or iPad file explorer that runs on Mac & PC. iExplorer lets users browse the files and folders on their iDevice as if it were a normal USB flash drive or pen drive (this application does not require any jailbreak). Using this tool it is possible to download all the application resources and data. The analysis of the data highlights the lack of encryption. In this case, when the vendor says "high grade encryption you must read: All data are stored on the iPhone encrypted file system that provides high-grade encryption.
21 / 61
GreHack
Base64Key = (int)objc_msgSend( *classRef_NSString_Ptr, *selRef_stringWithFormat_Ptr, CFSTR("HiddenTreasures")); NSData = &classRef_NSData; Key = objc_msgSend(&OBJC_CLASS___NSData, "dataFromBase64String:", Base64Key); BundlePath = objc_msgSend(&OBJC_CLASS__NSBundle, "mainBundle"); cpngPath = (int)objc_msgSend(BundlePath, "pathForResource:ofType:" filename, CFSTR("cpng"), 1063452672); Data = *NSData; cpngFileContent = (int)objc_msgSend(Data, dataWithContentsOfFile:", cpngPath); decyptedContent = (int)objc_msgSend( &OBJC_CLASS___FBEncryptorAES, "decryptData:key:iv:", cpngFileContent, Key, 0);
This allows an attacker to develop its own movie player to read the videos files extracted/dumped from the Ipad.
V. DEFENDING IOS APPLICATION In matter of security the iOS system is not perfect. Even if Apple increases the security level of its mobile operating system, for each new release comes a new jailbreak. Jailbreaking is a process that allows users to gain the root access to the command line, decrypt, analyze and crack iOS application. In this section we will present some defensives tricks, which can be use to the aim to slow down skilful attackers, discourage script kiddies and defeat automatic tools. A. Anti-analysis part 1 It is possible to add an anti-debugging feature by sending a non-standard ptrace value named PT_DENY_ATTACH. Setting this value allows a process that is not currently being traced to deny future traces by its parent. All others arguments are ignored. An attempt by the parent to trace a process, which has set this flag, will result in a segmentation violation in the parent.
Here the Key/Password: Hiddentreasures is Base64 decoded before being used as a key for the AES decryption algorithm. Moreover the IV used by the AES crypto function is fixed to 0. With this information an attacker can easily be reimplement the algorithm and decrypt the data. F. Playing DRM video with MPMoviePlayerControler This application was using the apple MPMoviePlayerControler API to play encrypted content stored on the device. In other words the application was localy streaming the files. The MPMoviePlayerControler is a part of Apple APIs. Apple developers documentation says: A movie player (of type MPMoviePlayerController) manages the playback of a movie from a file or a network stream.
22 / 61
GreHack
#import <dlfcn.h> #import <sys/types.h> #define PT_DENY_ATTACH 31 typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data); void disable_gdb() { void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW); ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace"); ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0); dlclose(handle); }
#include <unistd.h> #include <sys/types.h> #include <sys/sysctl.h> #include <string.h> #define P_TRACED 0x00000800 static int checkGDB() __attribute__((always_inline));
It is useful for defeating most tutorial-followers but this is no guarantee that your application cannot be debugged, and in fact there are ways around this. An attacker, can set a breakpoint within the application prior to issuing a run from within a debugger, and specify that the debugger run any commands he wants when ptrace starts and before the application can shut down. Here is an example of a GDB PT_DENY_ATTACH system call: script to bypass
int checkGDB() { size_t size = sizeof(struct kinfo_proc); struct kinfo_proc info; memset(&info, 0, sizeof(struct kinfo_proc)); int ret, name[4]; name[0] = CTL_KERN; name[1] = KERN_PROC; name[2] = KERN_PROC_PID; name[3] = getpid(); if (ret = (sysctl(name, 4, &info, &size, NULL, 0))) return ret; return (info.kp_proc.p_flag & P_TRACED) ? 1 : 0; }
It is useful for defeating most tutorial-followers but this is no guarantee that your application cannot be debugged, and in fact there are ways around this. Nevertheless, since the ptrace function is built inside the kernel, the user space interface only performs syscall 26 (ptrace). If the anti-debugging function is inlined like the example bellow the PT_DENY_ATTACH will be installed and there is no way .
This technique will only allow the application to detect when gdb, or another debugger, is attached to the process, but will not detect when malicious code is injected, or when other tools that do not trace are attached to the process. Implementing this in your code will only force an attacker to either avoid using a debugger (which will further complicate things for him), or to locate and patch the debugging checks. Moreover a skillful attacker could also patch out the invocation of sysctl itself. This is why simples sanity checks should be done to ensure that sysctl can return other data, and to ensure that the call does not fail. This will help further complicate the attack and require the attacker to properly populate the kinfo_proc structure with valid information. C. Preventing Hooking Hooking allowing attackers to alter or augment the behaviour of applications. By implementing the following defensives measures allowing ensuring that called function are the ones implemented in the application. 1) Validating Address Space Any time malicious code is injected into an application, it is loaded into the application address space. Validating the address space for critical methods used by the application force the attacker to find ways to inject his code into the existing address space.
Anyway a dedicated and skillful attacker can patch the kernel/application. B. Anti-analysis 2 When an application is being debugged, the kernel sets the P_TRACED flag for the process signifying that the process is being traced. Applications can monitor the state of this flag. If
23 / 61
GreHack
/* Pathname of shared object that contains address */ void *dli_fbase; /* Shared object Address */ const char *dli_sname; /* Name of nearest symbol with address lower than addr */ void *dli_saddr; /* Exact address of symbol named in dli_sname */ } Dl_info;
static int isPasswordValid(char * pwd) __attribute__((always_inline)); int isPasswordValid(char * pwd) { //Function body }
By providing the structure with the function pointer of a classs method implementation, its origins can be verified.
In addition of this attribute the following two compilations flags should be enabled: -finline-functions -Winline D. Others binary protection iOS Applications are not exempt of overflow vulnerabilities this is why the following mitigating technics should be implemented in every application. 1) Stack smashing protection It is possible to activate stack-mashing protection at compilation time. This can be achieved by specifying the fstack-protector-all compiler flag. When an application is compiled with this protection, a known value called canary is placed on the stack before the local variables to protect the saved base pointer, saved instruction pointer and function arguments. The value of the canary is verified upon the function return to see if it has been overwritten. One can identify the presence of stack canaries examining the symbol table of the binary, if stacksmashing protection is compiled in to the application, two undefined symbols will be present: ___stack_chk_fail ___stack_chk_guard 2) Automatic Reference Counting Automatic Reference Counting (ARC) was introduced in iOS SDK version 5.0 to move the responsibility of memory management from the developer to the compiler. Consequently, ARC also offers some security benefits as it reduces the likelihood of developers introducing memory corruption (specifically object use after-free and double free) vulnerabilities in to applications. ARC can be enabled in an application within XCode by setting the compiler option ObjectiveC Automatic Reference Counting to yes. This option is automatically check statring XCode 4.3.
static int checkAddressSpace __attribute__((always_inline)); int checkAddressSpace(NString MyCriticalClass , NSString MyCriticalMethod){ Dl_info info; IMP imp = class_getMethodImplementation( objc_getClass(MyCriticalClass), sel_registerName(MyCriticalMethod)); if (dladdr(imp, &info)){ /* Do some additional tests: Pathname of shared object */ return 1; } else { NSLog("Error: cannot find %@ symbol", MyCriticalMethod); return 0; } }
2) Inlining iOS offers a way to override functions in a shared library with DYLD_INSERT_LIBRARIES environment variable (which is similar to LD_PRELOAD on Linux). On a jailbroken device the MobileSubstrate framework simplify this task and allows developers to easily load libraries at application launch. Inline functions are functions in which the compiler expands a function body to be inserted within the code every time it is called. In other words, there is no longer a function: the code gets pasted into the machine code whenever it is called. Turning the critical functions into inline ones will cause it to be repeated throughout the
24 / 61
GreHack
VI. CONCLUSION Regarding security most of iOS applications are not mature! Developers should apply the following recommendation in order to mitigate the risks. Do not relay only on iOS security, Do not store credential using standardUserDefaults method. Encrypt your data even when stored in the keychain, Do not store crypto keys on the device, Check your code, classes, functions, methods integrity, Detect the jailbreak, Properly implement cryptography in applications (simple implementation are the most secure), Remove all debug information from the final release, Minimize use of Objective-C for critical functions & security features. Users and companies should not blindly thrust iOS application vendors when talking about security. REFERENCES
[1] iPhoneDataProtection - Jean-Baptiste Bdrune and Jean Sigwald, [2] Crakulous - Angel, http://hackulo.us [3] Dumpdecrypted Stefan Esser i0n1c, https://github.com/stefanesser/dumpdecrypted [4] Absinthe - Chronic-Dev Team and iPhone Dev Teams (Jailbreak Dream Team), http://greenpois0n.com [5] iOS SSL Kill Switch iSECPartners, https://github.com/iSECPartners [6] MobileSubstrate, Cydia Sauric, http://iphonedevwiki.net/index.php/MobileSubstrate, http://cydia.saurik.com/ [7] iExplorer - Macroplatant, http://www.macroplant.com/iexplorer/ [8] libimobiledevice & usbmuxd - Nikias, http://www.libimobiledevice.org/ [9] Gutmann method, http://en.wikipedia.org/wiki/Gutmann_method
25 / 61
GreHack
FURTHER READING
[31] Hacking and Securing iOS Applications: Jonathan Zdziarski [32] iOS Hacker's Handbook : Charlie Miller , Dion Blazakis , Dino Dai Zovi , Stefan Esser , Vincenzo Iozzo , Ralf-Phillip Weinmann [33] iOS kernel exploitation IOKit edition: http://reverse.put.as/wpcontent/uploads/2011/06/SyScanTaipei2011_StefanEsser_iOS_ Kernel_Exploitation_IOKit_Edition.pdf [34] iOS 5 an exploitation night mare http://antid0te.com/CSW2012_StefanEsser_iOS5_An_Exploitation_ Nightmare_FINAL.pdf [35] Evolution of iPhone Baseband and unlocks: http://conference.hitb.org/hitbsecconf2012ams/materials/D1T2 MuscleNerd Evolution of iPhone Baseband and Unlocks.pdf
26 / 61
GreHack