Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port MASTG test 0087 (by @guardsquare) #3056

Merged
merged 9 commits into from
Nov 26, 2024
2 changes: 1 addition & 1 deletion Document/0x06i-Testing-Code-Quality-and-Build-Settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Detecting the presence of [binary protection mechanisms](0x04h-Testing-Code-Qual
Although Xcode enables all binary security features by default, it may be relevant to verify this for old applications or to check for compiler flag misconfigurations. The following features are applicable:

- [**PIE (Position Independent Executable)**](0x04h-Testing-Code-Quality.md#position-independent-code):
- PIE applies to executable binaries (Mach-O type `MH_EXECUTE`).
- PIE applies to executable binaries (Mach-O type `MH_EXECUTE`) [source](https://web.archive.org/web/20230328221404/https://opensource.apple.com/source/cctools/cctools-921/include/mach-o/loader.h.auto.html).
- However it's not applicable for libraries (Mach-O type `MH_DYLIB`).
- [**Memory management**](0x04h-Testing-Code-Quality.md#memory-management):
- Both pure Objective-C, Swift and hybrid binaries should have ARC (Automatic Reference Counting) enabled.
Expand Down
2 changes: 1 addition & 1 deletion techniques/android/MASTG-TECH-0115.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Obtaining Compiler Provided Security Features
title: Obtaining Compiler-Provided Security Features
platform: android
---

Expand Down
80 changes: 57 additions & 23 deletions techniques/ios/MASTG-TECH-0082.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,63 @@
---
title: Get Loaded Native Libraries
title: Get Shared Libraries
platform: ios
---

## Using Objection

You can use the `list_frameworks` command in @MASTG-TOOL-0038 to list all the application's bundles that represent Frameworks.
To effectively identify and analyze shared libraries within an iOS application, it's important to distinguish between the app's bundled libraries and the system libraries provided by iOS. This distinction helps focus on the components that are unique to the app, thereby reducing noise during security assessments.

- **System Libraries**: Part of the iOS SDK, located in directories such as `/System/Library/Frameworks` or `/usr/lib`. These libraries are standard for all iOS applications and generally don't require detailed analysis unless there is a specific reason.
- **App-Bundled Libraries**: Included in the app bundle, often found in the `Frameworks` directory (`YourApp.app/Frameworks`). They include both first-party (custom) and third-party libraries that the developer intentionally incorporated into the app. They are the primary focus for security assessments. However, note that some **system libraries** may be also bundled with the app to ensure compatibility with specific versions of the iOS SDK so you'd need to filter them out.

Note that we're not considering static libraries, which, unlike dynamic libraries that are loaded at runtime, become part of the app's binary, resulting in a single executable file.

**Strategy**: Use one of the methods below, or a combination of them, to identify shared libraries, and then filter out system libraries to focus on those that are bundled with the app.

## Inspecting the Application Binary

Navigate to the `Frameworks` directory within the application bundle to find the shared libraries. The shared libraries are usually in the form of `.framework` or `.dylib` files.

```bash
ls -1 Frameworks
App.framework
Flutter.framework
libswiftCore.dylib
libswiftCoreAudio.dylib
...
```

## @MASTG-TOOL-0060

You can use the `otool -L` command to list the shared libraries.

```bash
otool -L MASTestApp
MASTestApp:
/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 2503.1.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1345.120.2)
/System/Library/Frameworks/CryptoKit.framework/CryptoKit (compatibility version 1.0.0, current version 1.0.0)
...
```

## @MASTG-TOOL-0073

In radare2, you can list the linked libraries using the `il` command.

```bash
r2 MASTestApp
[0x100006e9c]> il
[Linked libraries]
/System/Library/Frameworks/Foundation.framework/Foundation
/usr/lib/libobjc.A.dylib
/usr/lib/libSystem.B.dylib
/System/Library/Frameworks/CryptoKit.framework/CryptoKit
...
```

## @MASTG-TOOL-0074

You can use Objection's command `list_frameworks` to list all the app's bundles that represent Frameworks.

```bash
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios bundles list_frameworks
Expand All @@ -17,9 +69,9 @@ RealmSwift org.cocoapods.RealmSwift 4.1.1 ...A-v2.ap
...
```

## Using Frida
## @MASTG-TOOL-0039

In Frida REPL process related information can be obtained using the `Process` command. Within the `Process` command the function `enumerateModules` lists the libraries loaded into the process memory.
The `Process.enumerateModules()` function in Frida's REPL allows enumeration of modules loaded into memory during runtime.

```bash
[iPhone::com.iOweApp]-> Process.enumerateModules()
Expand All @@ -45,21 +97,3 @@ In Frida REPL process related information can be obtained using the `Process` co

...
```

Similarly, information related to various threads can be obtained.

```bash
Process.enumerateThreads()
[
{
"context": {
...
},
"id": 1287,
"state": "waiting"
},

...
```

The `Process` command exposes multiple functions which can be explored as per needs. Some useful functions are `findModuleByAddress`, `findModuleByName` and `enumerateRanges` besides others.
64 changes: 64 additions & 0 deletions techniques/ios/MASTG-TECH-0118.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: Obtaining Compiler-Provided Security Features
platform: ios
---

The iOS compiler provides several [security features that can be enabled during compilation](../../../Document/0x06i-Testing-Code-Quality-and-Build-Settings.md/#binary-protection-mechanisms). These features help protect the application from common vulnerabilities like buffer overflows and memory leaks. This technique provides guidance on how to check if these features are enabled in the compiled binary.

## @MASTG-TOOL-0073

In radare2, the presence of these compiler-provided security features can be checked by using the `i` and `is` commands.

**Check for PIC and Canaries:** Using the `i` command, you can check if the binary has Position Independent Code (PIC) enabled (`pic`) and if it has stack canaries (`canary`).

```sh
r2 MASTestApp
[0x100007408]> i~canary,pic
canary true
pic true
```

The output shows that the binary has stack canaries and PIE enabled.

**Check for ARC:** Using the `is` command, you can list the symbols in the binary and check for symbols that indicate the usage of Automatic Reference Counting (ARC). Common ARC symbols include:

- `objc_autorelease`
- `objc_retainAutorelease`
- `objc_release`
- `objc_retain`
- `objc_retainAutoreleasedReturnValue`
- `swift_release`
- `swift_retain`

An iOS binary does not need to have all of these symbols to be considered ARC-enabled, but the presence of some of them indicates that ARC is used.

```sh
[0x100007408]> is~release,retain
80 0x0000790c 0x10000790c LOCAL FUNC 0 imp.objc_release_x20
81 0x00007918 0x100007918 LOCAL FUNC 0 imp.objc_release_x24
82 0x00007924 0x100007924 LOCAL FUNC 0 imp.objc_release_x25
83 0x00007930 0x100007930 LOCAL FUNC 0 imp.objc_release_x27
84 0x0000793c 0x10000793c LOCAL FUNC 0 imp.objc_release_x8
85 0x00007948 0x100007948 LOCAL FUNC 0 imp.objc_retainAutoreleasedReturnValue
86 0x00007954 0x100007954 LOCAL FUNC 0 imp.objc_retain_x23
101 0x00007a08 0x100007a08 LOCAL FUNC 0 imp.swift_release
102 0x00007a14 0x100007a14 LOCAL FUNC 0 imp.swift_retain
```

The output shows that the binary contains symbols indicating the usage of ARC.

## @MASTG-TOOL-0074

Objection has a command `ios info binary` which can be used to get information about the binary, including whether stack canaries and PIE are enabled.

```sh
com.yourcompany.PPClient on (iPhone: 13.2.3) [usb] # ios info binary
Name Type Encrypted PIE ARC Canary Stack Exec RootSafe
-------------------- ------- ----------- ----- ----- -------- ------------ ----------
PayPal execute True True True True False False
CardinalMobile dylib False False True True False False
FraudForce dylib False False True True False False
...
```

The output shows `PIE`, `ARC` and `Canary` with a value of `True` or `False`.
32 changes: 32 additions & 0 deletions tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: Position Independent Code (PIC) not Enabled
platform: ios
id: MASTG-TEST-0x87-1
type: [static]
weakness: MASWE-0116
---

## Overview

[PIE (Position Independent Executables)](../../../Document/0x04h-Testing-Code-Quality.md/#position-independent-code) are designed to enhance security by allowing executables to be loaded at random memory addresses, mitigating certain types of attacks.

In the context Mach-O file format of iOS applications:

- PIE is applicable to executables with the `MH_EXECUTE` file type, which essentially means the main app binary (e.g. `YourApp.app/YourApp`).
- Shared libraries with the `MH_DYLIB` file type (dylibs and frameworks) are inherently position-independent and do not utilize the `MH_PIE` flag.

This test case checks if the main executable is compiled with PIE.

## Steps

1. Extract the application and identify the main binary (@MASTG-TECH-0054).
2. Identify all shared libraries (@MASTG-TECH-0082).
3. Run @MASTG-TECH-0118 on the main binary and grep for "pic" or the corresponding keyword used by the selected tool.

## Observation

The output should list if PIC is enabled or disabled.

## Evaluation

The test case fails if PIC is disabled.
37 changes: 37 additions & 0 deletions tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: Stack Canaries not enabled
platform: ios
id: MASTG-TEST-0x87-2
type: [static]
weakness: MASWE-0116
---

## Overview

This test case checks if the main binary or any libraries of the app are compiled without stack canaries and therefore lack [stack smashing protection](../../../Document/0x06i-Testing-Code-Quality-and-Build-Settings.md/#binary-protection-mechanisms), a common mitigation technique against buffer overflow attacks.

This test applies to all binaries and libraries:

- It is especially important for non-memory safe languages like Objective-C or C/C++.
- For pure Swift apps, checking for stack canaries can be usually skipped, as Swift is considered a memory safe by design and conventional parsing techniques cannot detect stack canaries in Swift binaries (see the "canary – exceptions" section of this [blog post](https://sensepost.com/blog/2021/on-ios-binary-protections/)).

To differentiate between Objective-C and Swift binaries, you can inspect the imports and linked libraries. Detecting Objective-C binaries is straightforward, but detecting pure Swift binaries is more challenging because depending on the Swift version and compiler settings, the binary may still contain Objective-C symbols or libraries. See the "identifying objc vs swift" section of this [blog post](https://sensepost.com/blog/2021/on-ios-binary-protections/) for more details.

## Steps

1. Extract the application and identify the main binary (@MASTG-TECH-0054).
2. Identify all shared libraries (@MASTG-TECH-0082).
3. Run @MASTG-TECH-0118 on the main binary and each shared library.
4. If the output contains the symbol `__stack_chk_fail` it indicates stack canaries are enabled.

## Observation

The output should contain a list of symbols of the main binary and each shared library.

## Evaluation

The test case fails any binary or library is not purely Swift but does not contain methods indicating stack canaries like `objc_autorelease` or `objc_retainAutorelease`.

**Note:** Checking for the `__stack_chk_fail` symbol only indicates that stack smashing protection is enabled somewhere in the app. While stack canaries are typically enabled or disabled for the entire binary, there may be corner cases where only parts of the application are protected. For example, if the app developer statically links a library with stack smashing protection enabled, but disables it for the entire application.

If you want to be sure that specific security-critical methods are sufficiently protected, you need to reverse-engineer each of them and manually check for stack smashing protection.
35 changes: 35 additions & 0 deletions tests-beta/ios/MASVS-CODE/MASTG-TEST-0x87-3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: Automatic Reference Counting (ARC) not enabled
platform: ios
id: MASTG-TEST-0x87-3
type: [static]
weakness: MASWE-0116
---

## Overview

This test case checks if [ARC (Automatic Reference Counting)](../../../Document/0x04h-Testing-Code-Quality.md/#automatic-reference-counting) is enabled in iOS apps. ARC is a compiler feature in Objective-C and Swift that automates memory management, reducing the likelihood of memory leaks and other related issues. Enabling ARC is crucial for maintaining the security and stability of iOS applications.

- **Objective-C Code:** ARC can be enabled by compiling with the `-fobjc-arc` flag in Clang.
- **Swift Code:** ARC is enabled by default.
- **C/C++ Code:** ARC is not applicable, as it pertains specifically to Objective-C and Swift.

When ARC is enabled, binaries will include symbols such as `objc_autorelease` or `objc_retainAutorelease`.

## Steps

1. Extract the application and identify the main binary (@MASTG-TECH-0054).
2. Identify all shared libraries (@MASTG-TECH-0082).
3. Run @MASTG-TECH-0118 on the main binary and each shared library looking for ARC symbols like `objc_autorelease` or `objc_retainAutorelease`.

## Observation

The output should contain a list of symbols of the main binary and each shared library.

## Evaluation

The test fails if any binary or library containing Objective-C or Swift code is missing ARC-related symbols. The presence of symbols such as `_objc_msgSend` (Objective-C) or `_swift_allocObject` (Swift) without corresponding ARC symbols indicates that ARC may not be enabled.

**Note:** Checking for these symbols only indicates that ARC is enabled somewhere in the app. While ARC is typically enabled or disabled for the entire binary, there can be corner cases where only parts of the application or libraries are protected. For example, if the app developer statically links a library that has ARC enabled, but disables it for the entire application.

If you want to be sure that specific security-critical methods are adequately protected, you need to reverse-engineer each of them and manually check for ARC, or request the source code from the developer.
3 changes: 3 additions & 0 deletions tests/ios/MASVS-CODE/MASTG-TEST-0087.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ title: Make Sure That Free Security Features Are Activated
masvs_v1_levels:
- L1
- L2
status: deprecated
covered_by: [MASTG-TEST-0228, MASTG-TEST-0229, MASTG-TEST-0230]
deprecation_note: New version available in MASTG V2
---

## Overview
Expand Down