Our new workshop about mobile application testing, held for the 1st time at the Troopers conference 2013, is coming closer. So I would like to take the opportunity and post an appetizer for those who are still undetermined if they should attend the workshop ;-).
While the topic of mobile application testing is a wide field that may contain reverse engineering, secure storage analysis, vulnerability research, network traffic analysis and so forth, in the end of the day you have to answer one question: Can I trust this application and run it on my enterprise devices? So first you have to define some criteria, which kind of behavior and characteristics of an application you regard as trustworthy (or not). Let us peek at malware … besides harming your devices and data, malware is typically:
- obfuscated and/or encrypted
- contains anti-debugging features
- contains anti-reverse engineering features
This makes the analysis process a difficult task and comparing these characteristics especially to ordinary iOS applications from the AppStore, at least one is also true for these apps: Those are encrypted and are only decrypted at runtime on your Apple gadget ;-).
But luckily we don’t have to decrypt the app for a quick look at their functionality, because the mach-o header of the app (mach-o is the executable file format of iOS apps) is not encrypted at all and can be analyzed with some command line tools that are part of the Xcode development environment. The nm
command shows us the symbol table of the mach-o binary and we will focus on the so called TEXT segment that contains the executable code of the application. Let’s take a look at an example, a browser application from the AppStore:
$ nm -m BrowserPadOrg|grep TEXT
00008eac (__TEXT,__stub_helper) non-external (was a private external) stub helpers
000062fc (__TEXT,__text) non-external [Thumb] +[NSURLRequest(SSL) allowsAnyHTTPSCertificateForHost:]
00005e30 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView atitle]
00005e24 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView bookmarkView]
00005ee0 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView dealloc]
00005f08 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView didReceiveMemoryWarning]
00005e14 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView numberOfSectionsInTableView:]
00005f30 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView saveBookmark]
00006048 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView setAtitle:]
00006070 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView setBookmarkView:]
00006020 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView setUrl:]
00005e10 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView shouldAutorotateToInterfaceOrientation:]
00006098 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView tableView:cellForRowAtIndexPath:]
00005e1c (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView tableView:didSelectRowAtIndexPath:]
00005e18 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView tableView:numberOfRowsInSection:]
00005e3c (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView url]
00005e48 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView viewDidLoad]
00005e20 (__TEXT,__text) non-external [Thumb] -[BookmarkDetailView viewDidUnload]
000057f8 (__TEXT,__text) non-external [Thumb] -[BookmarkView addBookmark]
00005654 (__TEXT,__text) non-external [Thumb] -[BookmarkView bookmarkTitle]
00005648 (__TEXT,__text) non-external [Thumb] -[BookmarkView browser]
00005724 (__TEXT,__text) non-external [Thumb] -[BookmarkView cancelEditBookmark]
00005b68 (__TEXT,__text) non-external [Thumb] -[BookmarkView dealloc]
00005b90 (__TEXT,__text) non-external [Thumb] -[BookmarkView didReceiveMemoryWarning]
00005688 (__TEXT,__text) non-external [Thumb] -[BookmarkView editBookmark]
00005644 (__TEXT,__text) non-external [Thumb] -[BookmarkView numberOfSectionsInTableView:]
0000597c (__TEXT,__text) non-external [Thumb] -[BookmarkView saveBookmark:url:]
00005b1c (__TEXT,__text) non-external [Thumb] -[BookmarkView saveBookmarkFile]
00005dc0 (__TEXT,__text) non-external [Thumb] -[BookmarkView setBookmarkTitle:]
00005de8 (__TEXT,__text) non-external [Thumb] -[BookmarkView setBrowser:]
00005d98 (__TEXT,__text) non-external [Thumb] -[BookmarkView setUrl:]
00005640 (__TEXT,__text) non-external [Thumb] -[BookmarkView shouldAutorotateToInterfaceOrientation:]
00005a14 (__TEXT,__text) non-external [Thumb] -[BookmarkView tableView:cellForRowAtIndexPath:]
00005900 (__TEXT,__text) non-external [Thumb] -[BookmarkView tableView:commitEditingStyle:forRowAtIndexPath:]
00005890 (__TEXT,__text) non-external [Thumb] -[BookmarkView tableView:didSelectRowAtIndexPath:]
00005b00 (__TEXT,__text) non-external [Thumb] -[BookmarkView tableView:numberOfRowsInSection:]
00005660 (__TEXT,__text) non-external [Thumb] -[BookmarkView url]
00005bb8 (__TEXT,__text) non-external [Thumb] -[BookmarkView viewDidLoad]
0000566c (__TEXT,__text) non-external [Thumb] -[BookmarkView viewDidUnload]
00002148 (__TEXT,__text) non-external [Thumb] -[BrowserPadAppDelegate application:didFinishLaunchingWithOptions:]
000021f8 (__TEXT,__text) non-external [Thumb] -[BrowserPadAppDelegate dealloc]
00002270 (__TEXT,__text) non-external [Thumb] -[BrowserPadAppDelegate setViewController:]
00002248 (__TEXT,__text) non-external [Thumb] -[BrowserPadAppDelegate setWindow:]
00002130 (__TEXT,__text) non-external [Thumb] -[BrowserPadAppDelegate viewController]
0000213c (__TEXT,__text) non-external [Thumb] -[BrowserPadAppDelegate window]
00002a54 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController alertView:clickedButtonAtIndex:]
000022cc (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController alertViewCancel:]
00002dcc (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController backButtonPress:]
00002408 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController bookmarkButtonPress:]
00002550 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController cancelButtonPress:]
000028d4 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController connection:canAuthenticateAgainstProtectionSpace:]
000027ec (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController connection:didFailWithError:]
00002904 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController connection:didReceiveAuthenticationChallenge:]
00002a00 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController connection:didReceiveData:]
00002a10 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController connection:didReceiveResponse:]
000029f0 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController connectionDidFinishLoading:]
00003214 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController dealloc]
00002298 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController degreesToRadians:]
000041a4 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController didDoubleTap]
0000323c (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController didReceiveMemoryWarning]
00003608 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController externalButtonPress:]
000022dc (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController fileURL]
00002d50 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController forwardButtonPress:]
00002590 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController goButtonPress:]
000033c8 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController handleScreenCapture:]
000022e8 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController hideToolbarDidStop:finished:context:]
00002f00 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController initializeDefaults]
000045dc (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController initializeExternalScreen]
00004c9c (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController initializeUserInterface]
000034d0 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController laserViewRemoved]
000025a4 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController loadURL:]
000043d8 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController loadURL]
00003ff0 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController pointerButtonPress:]
000022bc (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController popoverControllerDidDismissPopover:]
000032f8 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController rotateButtonPress:]
0000232c (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController scrollViewDidEndScrollingAnimation:]
00002314 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController scrollViewDidEndZooming:withView:atScale:]
000025f4 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController scrollViewDidScroll:]
000022d0 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController scrollViewDidZoom:]
000033a0 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController setFileURL:]
00002e2c (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController shouldAutorotateToInterfaceOrientation:]
00003d50 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController showAuthAlert]
000023a8 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController textField:shouldChangeCharactersInRange:replacementString:]
00002720 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController textFieldDidBeginEditing:]
000022d8 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController textFieldDidEndEditing:]
00003264 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController viewDidLoad]
000022d4 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController viewDidUnload]
00003124 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController viewForZoomingInScrollView:]
00002b74 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController webView:didFailLoadWithError:]
00002bec (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController webView:shouldStartLoadWithRequest:navigationType:]
00002b88 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController webViewDidFinishLoad:]
00002b24 (__TEXT,__text) non-external [Thumb] -[BrowserPadViewController webViewDidStartLoad:]
0000637c (__TEXT,__text) non-external [Thumb] -[MyWebView browserViewController]
00006388 (__TEXT,__text) non-external [Thumb] -[MyWebView dealloc]
000063f8 (__TEXT,__text) non-external [Thumb] -[MyWebView hitTest:withEvent:]
000063b0 (__TEXT,__text) non-external [Thumb] -[MyWebView initWithFrame:]
00006574 (__TEXT,__text) non-external [Thumb] -[MyWebView setBrowserViewController:]
0000659c (__TEXT,__text) non-external [Thumb] -[MyWebView setTouchDelegate:]
00006370 (__TEXT,__text) non-external [Thumb] -[MyWebView touchDelegate]
0000651c (__TEXT,__text) non-external [Thumb] -[MyWebView touchesBegan:withEvent:]
000064a4 (__TEXT,__text) non-external [Thumb] -[MyWebView touchesEnded:withEvent:]
000064e0 (__TEXT,__text) non-external [Thumb] -[MyWebView touchesMoved:withEvent:]
00005188 (__TEXT,__text) non-external [Thumb] -[PointerView browserViewController]
000051a0 (__TEXT,__text) non-external [Thumb] -[PointerView dealloc]
00005194 (__TEXT,__text) non-external [Thumb] -[PointerView externalView]
00005220 (__TEXT,__text) non-external [Thumb] -[PointerView initWithFrame:]
0000534c (__TEXT,__text) non-external [Thumb] -[PointerView setBrowserViewController:]
00005324 (__TEXT,__text) non-external [Thumb] -[PointerView setExternalView:]
00005204 (__TEXT,__text) non-external [Thumb] -[PointerView toggleLaser:]
00005488 (__TEXT,__text) non-external [Thumb] -[PointerView touchesBegan:withEvent:]
000051c8 (__TEXT,__text) non-external [Thumb] -[PointerView touchesEnded:withEvent:]
00005374 (__TEXT,__text) non-external [Thumb] -[PointerView touchesMoved:withEvent:]
00006300 (__TEXT,__text) non-external [Thumb] -[RenderView dealloc]
00006328 (__TEXT,__text) non-external [Thumb] -[RenderView initWithFrame:]
000020e4 (__TEXT,__text) non-external [Thumb] _main
000020b8 (__TEXT,__text) external start
These are the functions of the browser application and we already get a good idea about what this app is doing, right? But what about a developer that uses an obfuscation feature called stripping, that is part of the Xcode environment? The command strip
removes any resolved symbol from the binary, just run strip <binary_name>
and let’s see what happens to our example application when running the nm
command:
$ nm -m BrowserPadStripped|grep TEXT
$
No information from the TEXT segment anymore 🙁 and no easy guess about the implemented functionality. To find out more about the application we have to reverse engineer the application in detail now, which means decrypting it on an iOS device and analyzing the ARM based disassembly. But comparing this to malware, we already got an impression about the trustworthiness of this app:
Criteria | Malware | iOS App |
---|---|---|
obfuscated/enrypted | X | X |
Anti-Debugging | X | |
Anti-RE | X | X |
So I will let it up to you to decide, if you want to trust my example app from this post ;-). Or if this single criterion is sufficient to decide at all…
See you at Troopers and have a nice day :-).
Michael