Who am I?
Ilja van Sprundel IOActive netric blogs.23.nu/ilja
common security issues seen in 3rd party iOS applications possible fix or mitigation of them document how to exploit them in some cases
Introduction
Mobile app market exploded over the last 2 years lots of demand for security reviews of iPhone and iPad apps over the last year or so Very little has been published Ive done a number of them in the last 10 months notes of what Ive learned so far
Application environment
native applications iOS, port of MacOSX to arm cpu obj-c (strict c superset) obj-c classes take care of most low
level handling (memory allocations, ....)
Transport security
fair amount of iOS apps need to do
secure transactions
online banking, online trading, ... They will use SSL use of https:// urls passed to
NSURLRequest / NSURLConnection
Transport security
Transport security
TLS_RSA_WITH_DES_CBC_SHA TLS_RSA_EXPORT_WITH_RC40_MD5 TLS_RSA_EXPORT_WITH_DES40_CBC_
SHA
TLS_DHE_RSA_WITH_DES_CBC_SHA TLS_DHE_RSA_EXPORT_WITH_DES40_
CBC_SHA
Transport security
on by default no (documented) way to turn it off this is (kinda) documented:
from apples Secure Coding Guide (2010-02-12), page 29
Transport security
SSL apis on iOS arent granular
enough
cant fix it, but you can mitigate it include an ssl library and use that one
(e.g. CyaSSL and MatrixSSL are build for embedded use)
Transport security
Transport security
NSMutableDictionary *settings = [[NSMutableDictionary alloc] init];[settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsExpiredCertificates];[settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsExpiredRoots];[settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsAnyRoot];[settings setObject:[NSNumber numberWithBool:NO] forKey:(NSString *)kCFStreamSSLValidatesCertificateChain];CFReadStreamSe tProperty((CFReadStreamRef)inputStream, kCFStreamPropertySSLSettings, (CFDictionaryRef)settings);CFWriteStreamSetProperty((CFWr iteStreamRef)outputStream, kCFStreamPropertySSLSettings, (CFDictionaryRef)settings);
Transport security
Luckily none of that is on by default! takes quite some work to screw this up
for a developer
application:openURL:sourceApplication:
annotation
UIWebView
can be used to build gui (mostly in weblike environments)
UIWebView
Vulnerable to attack (if used as a gui) if attacker can inject unescaped data will lead to Cross site scripting
UIWebView
by default there is no bridge from UIWebViews javascript to actual obj-c most iOS apps developers that use UIWebView (for guis) would like there to be one url handler, only valid for that specific UIWebView shouldStartLoadingWithRequest: method
UIWebView
that url handler can do anything you
want it to do
UIWebView
UIWebView
if used simply as a browser can do a lot more than render html and
interact with a webapplications
UIWebView
Excel (xls)
keynote (.key.zip) (and also zip files) numbers (.numbers.zip) Pages (.pages.zip) pdf (.pdf) powerpoint (.ppt) word (.doc) rtf (.rtf) / rtf dictionary (.rtfd.zip) keynote 09 (.key) numbers 09 (.numbers) pages 09 (.pages)
UIWebView
Very long list enormously difficult file formats to parse
apple apis, but they are in proc ! on by default no way to turn this off
UIWebView
does a number of other things: e.g. try to detect phone numbers and
turns them into tell:// urls
UIWebView
mitigation: render out of proc give url to safari instead of rendering in
UIWebView
UIImage
Wide attack surface very similar to
UIWebViews
UIImage
tiff jpeg
png
bmp ico cur xbm gif
UIImage
not to mention some extensions that
work with various image file formats:
UIImage
Huge attack surface there is no property to specify which
UIImage
2 possible workaround UIImage allows using CGImageRef use more low-level Core Graphics
library to specifically load jpg or png
UIImage
or you could just look at the first couple of bytes of the image file each graphics format is trivial to detect based on some magic bytes in the begining for example:
jpg signature: 4A 46 49 46
GIF signature: 47 49 46 38 39 61 or 47 49 46 38 37 61 BMP: first 2 bytes: BM
addValue:forHTTPHeaderField setValue:forHTTPHeaderField
seems most iOS apps are riddled with it most iOS apps developers dont seem
to know this is a problem
NSLog() [NSString stringWithFormat:] [NSString initWithFormat:] [NSMutableString appendFormat:] [NSAlert informativeTextWithFormat:] [NSPredicate predicateWithFormat:]
[NSException format:]
NSRunAlertPanel
printf
snprintf
fprintf ...
Exploiting bugs
binary protocol handling is sort of the exception no good obj-c classes for that developers have to fall back to old c-style binary protocol parsing.
Directory traversal
iOS has similar file apis as MacOSX same types of desktop/server os file
issues
NSFileManager
Directory traversal
classic dir traversal:
NSString *file = [[NSString alloc] initWithFormat: @"%@/%@", NSTemporaryDirectory(), attackerControlledString]; NSFileManager *m = [NSFileManager defaultManager]; [m createFileAtPath:text contents:nsd attributes:nil];
Directory traversal
Poison NULL byte
NSString *file = [[NSString alloc] initWithFormat: @"%@/%@.ext", NSTemporaryDirectory(), attackerControlledString]; NSFileManager *m = [NSFileManager defaultManager]; [m createFileAtPath:text contents:nsd attributes:nil];
../../../../blahblah\0
This works, because NSStrings dont use 0bytes to terminate a string, but the iOS kernel does.
NSXMLParser
it handles DTDs by default billion laughs no way to turn it off doesnt resolve external entities by
default
can be turned on
NSXMLParser
Theres kindof a hairy workaround. 6 callbacks can be defined, that will be
called if a DTD is encountered.
foundElementDeclarationWithName
foundAttributeDeclarationWithName foundInternalEntityDeclarationWithName foundExternalEntityDeclarationWithName foundNotationDeclarationWithName foundUnparsedEntityDeclarationWithName
NSXMLParser
- (void) parser:(NSXMLParser*)parser foundExternalEntityDeclarationWithName:(NSString*)entityName { [self abort:@"DTD"]; } - (void) parser:(NSXMLParser*)parser foundAttributeDeclarationWithName:(NSString*)attributeName ... { [self abort:@"DTD"]; } - (void) parser:(NSXMLParser*)parser foundElementDeclarationWithName:(NSString*)elementName model:(NSString*)model { [self abort:@"DTD"]; } (void) parser:(NSXMLParser*)parser foundInternalEntityDeclarationWithName:(NSString*)name value:(NSString*)value { [self abort:@"DTD"]; } - (void) parser:(NSXMLParser*)parser foundUnparsedEntityDeclarationWithName:(NSString*)name ... { [self abort:@"DTD"]; } - (void) parser:(NSXMLParser*)parser foundNotationDeclarationWithName:(NSString*)name publicID:(NSString*)publicID ... { [self abort:@"DTD"]; }
NSXMLParser
This works, but its hairy and error
prone
Questions ?