1 of 51

Reverse Engineering and Securing iOS Apps

Luke Reichold

2 of 51

  1. Network / Transport Security
  2. Static Analysis
  3. Dynamic Analysis
  4. Storing Data at Rest

Vulnerability Analysis - Techniques

3 of 51

  • Become more conscious of how design decisions impact overall application security�
  • Minimize attack surface

Goals

4 of 51

  • Intro to using Charles HTTP(S) proxy

  • No source code or jailbreak required!

  • Demonstration
  1. Network Analysis using Charles Proxy

5 of 51

Analyzing other apps:

  • Understand how other apps structure API's and transfer data
  • Insight into how they solved a similar problem
  • See what data the apps you use collect on you

Network Analysis - Benefits

6 of 51

Recognize that ANY user with MITM can...

  • Freely re-write network requests / responses
  • View non-public web API endpoints
  • Observe sensitive strings / tokens

Network Analysis - Benefits

7 of 51

8 of 51

  • Certificate Pinning
  • Server should validate all requests from the app
  • Follow secure session management practices
  • Use App Transport Security

Transport Security - Best Practices

9 of 51

What is it?

2. Static Analysis

10 of 51

What is it?

Inspect code / binary to seek out coding flaws, back doors, and vulnerabilities without execution.

2. Static Analysis

11 of 51

  • Application logs
  • API tokens / secrets in strings or Plists
  • URL's of non-public API endpoints
  • All linked frameworks
  • Private functions, ivars, classes

2. Static Analysis - Targets

12 of 51

2. Static Analysis - Attack Vectors

  • strings
  • Class dumps
  • Disassemblers / decompilers (Hopper)

13 of 51

Xcode Demo

2. Static Analysis

14 of 51

  • String obfuscation

2. Static Analysis - Defense Techniques

15 of 51

  • Store as hex?�

unsigned char myApiKey[] = {0xDE, 0xAD, 0xBE, 0xEF }

String Obfuscation

16 of 51

  • XOR the key against some value determined at runtime�obfuscated_key = actual_key ^ NSStringFromClass([LRAppDelegate class])

  • Store only this obfuscated key in code

String Obfuscation - Better Technique

17 of 51

  • String obfuscation
  • Never hard code or otherwise trivially store passwords, session tokens, etc.

2. Static Analysis - Defense Techniques

18 of 51

  • String obfuscation
  • Never hard code or otherwise trivially store passwords, session tokens, etc.
  • Anything that must truly remain private should not reside on the mobile device

2. Static Analysis - Defense Techniques

19 of 51

  • AUTOMATED static analysis tools
    • Clang static analyzer
    • Thread sanitizer
    • Address Sanitizer
    • Facebook’s Infer

2. Static Analysis - Defense Techniques

Built into Xcode!

20 of 51

  • Jailbroken devices

3. Runtime Analysis - Attack Vectors

21 of 51

  • Jailbroken devices
  • Attached debuggers

3. Runtime Analysis - Attack Vectors

22 of 51

  • Jailbroken devices
  • Attached debuggers
  • Unvalidated user input

3. Runtime Analysis - Attack Vectors

23 of 51

  • Check for apps like /Applications/Cydia.app

Implementing Jailbreak Detection

24 of 51

  • Check for apps like /Applications/Cydia.app
  • Attempt to modify files outside its sandbox

Implementing Jailbreak Detection

25 of 51

  • Check for apps like /Applications/Cydia.app
  • Attempt to modify files outside its sandbox
  • Call system API’s like fork() or system()

Implementing Jailbreak Detection

26 of 51

  • Cycript (can emulate without jailbreak)
  • Modify ivars, swizzle methods at runtime
  • Run any method arbitrarily
  • Inject malicious dynamic libraries

Runtime Debugging

27 of 51

  • Add checks in main.m to kill app if LLDB or GDB detected

Runtime Debugging - Defenses

28 of 51

  • Add checks in main.m to kill app if LLDB or GDB attached
  • Integrity checks on embedded frameworks (dladdr)

Runtime Debugging - Defenses

29 of 51

  • Add checks in main.m to kill app if LLDB or GDB attached
  • Runtime integrity checks on embedded frameworks (dladdr)
  • Use static libraries instead of dylibs

Runtime Debugging - Defenses

30 of 51

  • Buffer overflows
  • String formatting vulnerabilities
  • URL schemes

Unvalidated User Input

31 of 51

Buffer overflows:

  • Avoid low-level C string functions

Unvalidated User Input

32 of 51

String formatting:

  • Don't accept format strings from a user
  • Don't format strings more than once

Unvalidated User Input

33 of 51

// BAD

NSLog(self.userInputTextField);

[mString appendFormat:[NSString stringWithFormat:@"value: ", _myField.text]];

String Formatting

34 of 51

URL Schemes:

  • Arguments might redirect call to other dir. or URL

myapp://use_template?template=/../../../../../../some/other/file

Unvalidated User Input

35 of 51

URL Schemes:

  • Provide UI confirmation for critical or destructive actions

Unvalidated User Input

36 of 51

  • Jailbreak detection
  • Debugging detection
  • Input validation and fuzzing
  • Declaring sensitive functions inline

3. Runtime Manipulation - Mitigation

37 of 51

  • Effective at duplicating sensitive code (enabling paid features, jailbreak checks, etc)
  • The actual code is pasted into the calling function each time the function call is made.
  • Make it much more difficult for an attacker to simply find the one "exit" call and overwrite it

Inlining Functions

38 of 51

Inlining Functions

39 of 51

Inlining Functions

#define isJailbroken() asdfghz()

static inline bool asdfghz() _attribute__((always_inline)) {

...

}

40 of 51

  • Assume user's device will become lost or stolen

4. Storing Data at Rest

41 of 51

  • Assume user's device will become lost or stolen
  • iOS Data Protection

4. Storing Data at Rest

42 of 51

  • Assume user's device will become lost or stolen
  • iOS Data Protection
  • Keychain

4. Storing Data at Rest

43 of 51

  • Assume user's device will become lost or stolen
  • iOS Data Protection
  • Keychain
  • Use system API’s: Security.framework

4. Storing Data at Rest

44 of 51

  • Assume user's device will become lost or stolen
  • iOS Data Protection
  • Keychain
  • Use system API’s: Security.framework
  • Ask: "Do I actually need to store this on device?"

4. Storing Data at Rest

45 of 51

  • Assume user's device will become lost or stolen
  • iOS Data Protection
  • Keychain
  • Use system API’s: Security.framework
  • Ask: "Do I actually need to store this on device?"
  • Consider storing sensitive data only in-memory

4. Storing Data at Rest

46 of 51

  • Validate all authenticated network requests

Big Ideas

47 of 51

  • Validate all authenticated network requests
  • Assume your app binary will be decrypted and analyzed

Big Ideas

48 of 51

  • Validate all authenticated network requests
  • Assume your app binary will be decrypted and analyzed
  • Validate user input

Big Ideas

49 of 51

  • Validate all authenticated network requests
  • Assume your app binary will be decrypted and analyzed
  • Validate user input
  • Sensitive data: avoid storing on disk, or at least encrypt

Big Ideas

50 of 51

  • Validate all authenticated network requests
  • Assume your app binary will be decrypted and analyzed
  • Validate user input
  • Sensitive data: avoid storing on disk, or at least encrypt
  • Implement jailbreak detection if possible

Big Ideas

51 of 51

  • Validate all authenticated network requests
  • Assume your app binary will be decrypted and analyzed
  • Validate user input
  • Sensitive data: avoid storing on disk, or at least encrypt
  • Implement jailbreak detection if possible
  • Design for the “angry path”

Big Ideas