mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 04:33:28 +00:00
GitBook: [master] 467 pages and 2 assets modified
This commit is contained in:
parent
d2d0b1333e
commit
e15860f1d3
7 changed files with 618 additions and 250 deletions
BIN
.gitbook/assets/image (505).png
Normal file
BIN
.gitbook/assets/image (505).png
Normal file
Binary file not shown.
After Width: | Height: | Size: 493 KiB |
BIN
.gitbook/assets/image (506).png
Normal file
BIN
.gitbook/assets/image (506).png
Normal file
Binary file not shown.
After Width: | Height: | Size: 125 KiB |
13
SUMMARY.md
13
SUMMARY.md
|
@ -507,11 +507,14 @@
|
|||
* [Online Platforms with API](online-platforms-with-api.md)
|
||||
* [Stealing Sensitive Information Disclosure from a Web](stealing-sensitive-information-disclosure-from-a-web.md)
|
||||
* [iOS Pentesting](ios-pentesting/README.md)
|
||||
* [iOS Pentesting Checklist](ios-pentesting/ios-pentesting-checklist.md)
|
||||
* [Extracting Entitlements From Compiled Application](ios-pentesting/extracting-entitlements-from-compiled-application.md)
|
||||
* [iOS Basics](ios-pentesting/ios-basics.md)
|
||||
* [Frida Configuration in iOS](ios-pentesting/frida-configuration-in-ios.md)
|
||||
* [iOS Testing Environment](ios-pentesting/ios-testing-environment.md)
|
||||
* [Basic iOS Testing Operations](ios-pentesting/basic-ios-testing-operations.md)
|
||||
* [Burp Suite Configuration for iOS](ios-pentesting/burp-configuration-for-ios.md)
|
||||
* [Extracting Entitlements From Compiled Application](ios-pentesting/extracting-entitlements-from-compiled-application.md)
|
||||
* [Frida Configuration in iOS](ios-pentesting/frida-configuration-in-ios.md)
|
||||
* [iOS App Extensions](ios-pentesting/ios-app-extensions.md)
|
||||
* [iOS Basics](ios-pentesting/ios-basics.md)
|
||||
* [iOS Hooking With Objection](ios-pentesting/ios-hooking-with-objection.md)
|
||||
* [iOS Pentesting Checklist](ios-pentesting/ios-pentesting-checklist.md)
|
||||
* [iOS Testing Environment](ios-pentesting/ios-testing-environment.md)
|
||||
* [iOS UIActivity Sharing](ios-pentesting/ios-uiactivity-sharing.md)
|
||||
|
||||
|
|
|
@ -44,240 +44,11 @@ $ frida-ps -Uai
|
|||
- iGoat-Swift OWASP.iGoat-Swift
|
||||
```
|
||||
|
||||
### Basic Enumeration of the app
|
||||
### Basic Enumeration & Hooking
|
||||
|
||||
For this section the tool [**Objection**](https://github.com/sensepost/objection) is going to be used.
|
||||
Start by getting an objection's session executing something like `objection -d --gadget "iGoat-Swift" explore` or `objection -d --gadget "OWASP.iGoat-Swift" explore`
|
||||
Learn how to **enumerate the components of the application** and how to easily **hook methods and classes** with objection:
|
||||
|
||||
* `env`: Find the paths where the application is stored inside the device
|
||||
|
||||
```bash
|
||||
env
|
||||
|
||||
Name Path
|
||||
----------------- -----------------------------------------------------------------------------------------------
|
||||
BundlePath /private/var/containers/Bundle/Application/179A6E8B-E7A8-476E-BBE3-B9300F546068/iGoat-Swift.app
|
||||
CachesDirectory /var/mobile/Containers/Data/Application/A079DF84-726C-4AEA-A194-805B97B3684A/Library/Caches
|
||||
DocumentDirectory /var/mobile/Containers/Data/Application/A079DF84-726C-4AEA-A194-805B97B3684A/Documents
|
||||
LibraryDirectory /var/mobile/Containers/Data/Application/A079DF84-726C-4AEA-A194-805B97B3684A/Library
|
||||
```
|
||||
|
||||
* `ios bundled list_bundles`: List bundles of the application
|
||||
|
||||
```bash
|
||||
ios bundles list_bundles
|
||||
Executable Bundle Version Path
|
||||
------------ -------------------- --------- -------------------------------------------
|
||||
iGoat-Swift OWASP.iGoat-Swift 1.0 ...8-476E-BBE3-B9300F546068/iGoat-Swift.app
|
||||
AGXMetalA9 com.apple.AGXMetalA9 172.18.4 ...tem/Library/Extensions/AGXMetalA9.bundle
|
||||
```
|
||||
|
||||
* `ios bundle list_frameworks`: List external frameworks used by the application
|
||||
|
||||
```bash
|
||||
ios bundles list_frameworks
|
||||
Executable Bundle Version Path
|
||||
------------------------------ -------------------------------------------- ---------- -------------------------------------------
|
||||
ReactCommon org.cocoapods.ReactCommon 0.61.5 ...tle.app/Frameworks/ReactCommon.framework
|
||||
...vateFrameworks/CoreDuetContext.framework
|
||||
FBReactNativeSpec org.cocoapods.FBReactNativeSpec 0.61.5 ...p/Frameworks/FBReactNativeSpec.framework
|
||||
...ystem/Library/Frameworks/IOKit.framework
|
||||
RCTAnimation org.cocoapods.RCTAnimation 0.61.5 ...le.app/Frameworks/RCTAnimation.framework
|
||||
jsinspector org.cocoapods.jsinspector 0.61.5 ...tle.app/Frameworks/jsinspector.framework
|
||||
DoubleConversion org.cocoapods.DoubleConversion 1.1.6 ...pp/Frameworks/DoubleConversion.framework
|
||||
react_native_config org.cocoapods.react-native-config 0.12.0 ...Frameworks/react_native_config.framework
|
||||
react_native_netinfo org.cocoapods.react-native-netinfo 4.4.0 ...rameworks/react_native_netinfo.framework
|
||||
PureLayout org.cocoapods.PureLayout 3.1.5 ...ttle.app/Frameworks/PureLayout.framework
|
||||
GoogleUtilities org.cocoapods.GoogleUtilities 6.6.0 ...app/Frameworks/GoogleUtilities.framework
|
||||
RCTNetwork org.cocoapods.RCTNetwork 0.61.5 ...ttle.app/Frameworks/RCTNetwork.framework
|
||||
RCTActionSheet org.cocoapods.RCTActionSheet 0.61.5 ....app/Frameworks/RCTActionSheet.framework
|
||||
react_native_image_editor org.cocoapods.react-native-image-editor 2.1.0 ...orks/react_native_image_editor.framework
|
||||
CoreModules org.cocoapods.CoreModules 0.61.5 ...tle.app/Frameworks/CoreModules.framework
|
||||
RCTVibration org.cocoapods.RCTVibration 0.61.5 ...le.app/Frameworks/RCTVibration.framework
|
||||
RNGestureHandler org.cocoapods.RNGestureHandler 1.6.1 ...pp/Frameworks/RNGestureHandler.framework
|
||||
RNCClipboard org.cocoapods.RNCClipboard 1.5.1 ...le.app/Frameworks/RNCClipboard.framework
|
||||
react_native_image_picker org.cocoapods.react-native-image-picker 2.3.4 ...orks/react_native_image_picker.framework
|
||||
[..]
|
||||
```
|
||||
|
||||
* `memory list modules`: List loaded modules in memory
|
||||
|
||||
```bash
|
||||
memory list modules
|
||||
Name Base Size Path
|
||||
----------------------------------- ----------- ------------------- ------------------------------------------------------------------------------
|
||||
iGoat-Swift 0x104ffc000 2326528 (2.2 MiB) /private/var/containers/Bundle/Application/179A6E8B-E7A8-476E-BBE3-B9300F54...
|
||||
SubstrateBootstrap.dylib 0x105354000 16384 (16.0 KiB) /usr/lib/substrate/SubstrateBootstrap.dylib
|
||||
SystemConfiguration 0x1aa842000 495616 (484.0 KiB) /System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguratio...
|
||||
libc++.1.dylib 0x1bdcfd000 368640 (360.0 KiB) /usr/lib/libc++.1.dylib
|
||||
libz.1.dylib 0x1efd3c000 73728 (72.0 KiB) /usr/lib/libz.1.dylib
|
||||
libsqlite3.dylib 0x1c267f000 1585152 (1.5 MiB) /usr/lib/libsqlite3.dylib
|
||||
Foundation 0x1ab550000 2732032 (2.6 MiB) /System/Library/Frameworks/Foundation.framework/Foundation
|
||||
libobjc.A.dylib 0x1bdc64000 233472 (228.0 KiB) /usr/lib/libobjc.A.dylib
|
||||
[...]
|
||||
```
|
||||
|
||||
* `memory list exports <module_name>`: Exports of a loaded module
|
||||
|
||||
```bash
|
||||
memory list exports iGoat-Swift
|
||||
Type Name Address
|
||||
-------- -------------------------------------------------------------------------------------------------------------------------------------- -----------
|
||||
variable _mh_execute_header 0x104ffc000
|
||||
function _mdictof 0x10516cb88
|
||||
function _ZN9couchbase6differ10BaseDifferD2Ev 0x10516486c
|
||||
function _ZN9couchbase6differ10BaseDifferD1Ev 0x1051648f4
|
||||
function _ZN9couchbase6differ10BaseDifferD0Ev 0x1051648f8
|
||||
function _ZN9couchbase6differ10BaseDiffer5setupEmm 0x10516490c
|
||||
function _ZN9couchbase6differ10BaseDiffer11allocStripeEmm 0x105164a20
|
||||
function _ZN9couchbase6differ10BaseDiffer7computeEmmj 0x105164ad8
|
||||
function _ZN9couchbase6differ10BaseDiffer7changesEv 0x105164de4
|
||||
function _ZN9couchbase6differ10BaseDiffer9addChangeENS0_6ChangeE 0x105164fa8
|
||||
function _ZN9couchbase6differlsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS0_6ChangeE 0x1051651d8
|
||||
function _ZN9couchbase6differlsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS1_6vectorINS0_6ChangeENS1_9allocatorIS8_EEEE 0x105165280
|
||||
variable _ZTSN9couchbase6differ10BaseDifferE 0x1051d94f0
|
||||
variable _ZTVN9couchbase6differ10BaseDifferE 0x10523c0a0
|
||||
variable _ZTIN9couchbase6differ10BaseDifferE 0x10523c0f8
|
||||
[..]
|
||||
```
|
||||
|
||||
* `ios hooking list classes`: List classes of the app
|
||||
|
||||
```bash
|
||||
ios hooking list classes
|
||||
|
||||
AAAbsintheContext
|
||||
AAAbsintheSigner
|
||||
AAAbsintheSignerContextCache
|
||||
AAAcceptedTermsController
|
||||
AAAccount
|
||||
AAAccountManagementUIResponse
|
||||
AAAccountManager
|
||||
AAAddEmailUIRequest
|
||||
AAAppleIDSettingsRequest
|
||||
AAAppleTVRequest
|
||||
AAAttestationSigner
|
||||
[...]
|
||||
```
|
||||
|
||||
* `ios hooking list class_methods`: List methods of a specific class
|
||||
|
||||
```bash
|
||||
ios hooking list class_methods iGoat_Swift.RCreditInfo
|
||||
- cvv
|
||||
- setCvv:
|
||||
- setName:
|
||||
- .cxx_destruct
|
||||
- name
|
||||
- cardNumber
|
||||
- init
|
||||
- initWithValue:
|
||||
- setCardNumber:
|
||||
```
|
||||
|
||||
* `ios hooking search classes <search_term>`: Search a class that contains a string
|
||||
|
||||
```bash
|
||||
ios hooking search classes iGoat
|
||||
iGoat_Swift.CoreDataHelper
|
||||
iGoat_Swift.RCreditInfo
|
||||
iGoat_Swift.SideContainmentSegue
|
||||
iGoat_Swift.CenterContainmentSegue
|
||||
iGoat_Swift.KeyStorageServerSideVC
|
||||
iGoat_Swift.HintVC
|
||||
iGoat_Swift.BinaryCookiesExerciseVC
|
||||
iGoat_Swift.ExerciseDemoVC
|
||||
iGoat_Swift.PlistStorageExerciseViewController
|
||||
iGoat_Swift.CouchBaseExerciseVC
|
||||
iGoat_Swift.MemoryManagementVC
|
||||
[...]
|
||||
```
|
||||
|
||||
* `ios hooking search methods <search_term>`: Search a method that contains a string
|
||||
|
||||
```bash
|
||||
ios hooking search methods cvv
|
||||
[AMSFinanceVerifyPurchaseResponse + _dialogRequestForCVVFromPayload:verifyType:]
|
||||
[AMSFinanceVerifyPurchaseResponse - _handleCVVDialogResult:shouldReattempt:]
|
||||
[AMSFinanceVerifyPurchaseResponse - _runCVVRequestForCode:error:]
|
||||
[iGoat_Swift.RCreditInfo - cvv]
|
||||
[iGoat_Swift.RCreditInfo - setCvv:]
|
||||
[iGoat_Swift.RealmExerciseVC - creditCVVTextField]
|
||||
[iGoat_Swift.RealmExerciseVC - setCreditCVVTextField:]
|
||||
[iGoat_Swift.DeviceLogsExerciseVC - cvvTextField]
|
||||
[iGoat_Swift.DeviceLogsExerciseVC - setCvvTextField:]
|
||||
[iGoat_Swift.CloudMisconfigurationExerciseVC - cvvTxtField]
|
||||
[iGoat_Swift.CloudMisconfigurationExerciseVC - setCvvTxtField:]
|
||||
```
|
||||
|
||||
### Basic Hooking
|
||||
|
||||
Now that you have **enumerated the classes and modules** used by the application you may have found some **interesting class and method names**.
|
||||
|
||||
* `ios hooking watch class <class_name>`: Hook all the methods of a class, dump all the initial parameters and returns
|
||||
|
||||
```bash
|
||||
ios hooking watch class iGoat_Swift.PlistStorageExerciseViewController
|
||||
```
|
||||
|
||||
* `ios hooking watch method "-[<class_name> <method_name>]" --dump-args --dump-return --dump-backtrace`: Hook an specific method of a class dumping the parameters, backtraces and returns of the method each time it's called
|
||||
|
||||
```bash
|
||||
ios hooking watch method "-[iGoat_Swift.BinaryCookiesExerciseVC verifyItemPressed]" --dump-args --dump-backtrace --dump-return
|
||||
```
|
||||
|
||||
* `ios hooking set return_value "-[<class_name> <method_name>]" false`: This will make the selected method return the indicated boolean
|
||||
|
||||
```bash
|
||||
ios hooking set return_value "-[iGoat_Swift.BinaryCookiesExerciseVC verifyItemPressed]" false
|
||||
```
|
||||
|
||||
* `ios hooking generate simple <class_name>`:
|
||||
|
||||
```bash
|
||||
ios hooking generate simple iGoat_Swift.RCreditInfo
|
||||
|
||||
var target = ObjC.classes.iGoat_Swift.RCreditInfo;
|
||||
|
||||
Interceptor.attach(target['+ sharedSchema'].implementation, {
|
||||
onEnter: function (args) {
|
||||
console.log('Entering + sharedSchema!');
|
||||
},
|
||||
onLeave: function (retval) {
|
||||
console.log('Leaving + sharedSchema');
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Interceptor.attach(target['+ className'].implementation, {
|
||||
onEnter: function (args) {
|
||||
console.log('Entering + className!');
|
||||
},
|
||||
onLeave: function (retval) {
|
||||
console.log('Leaving + className');
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Interceptor.attach(target['- cvv'].implementation, {
|
||||
onEnter: function (args) {
|
||||
console.log('Entering - cvv!');
|
||||
},
|
||||
onLeave: function (retval) {
|
||||
console.log('Leaving - cvv');
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Interceptor.attach(target['- setCvv:'].implementation, {
|
||||
onEnter: function (args) {
|
||||
console.log('Entering - setCvv:!');
|
||||
},
|
||||
onLeave: function (retval) {
|
||||
console.log('Leaving - setCvv:');
|
||||
},
|
||||
});
|
||||
```
|
||||
{% page-ref page="ios-hooking-with-objection.md" %}
|
||||
|
||||
### IPA Structure
|
||||
|
||||
|
@ -837,19 +608,6 @@ Jun 7 13:42:14 iPhone touch[9708] <Notice>: MS:Notice: Injecting: (null) [touch
|
|||
...
|
||||
```
|
||||
|
||||
## Clipboard
|
||||
|
||||
Some applications may save sensitive information inside the clipboard, which is dangerous because then a different application may sniff the clipboard and steal the data.
|
||||
|
||||
Fortunately, apps signed by the same certificate can create **private** **UIPasteboards**. This way, unlike the global Pasteboard, only **selected** **applications** can share and view the content of the **private** **pasteboard**.
|
||||
|
||||
Then, it's important to **check that sensitive information isn't being saved inside the global pasteboard**.
|
||||
It's also important to check that an **application isn't using the global pasteboard data to perform actions**, as malicious application could tamper this data.
|
||||
|
||||
An **application can also prevent its users to copy sensitive data to the clipboard** \(which is recommended\).
|
||||
|
||||
You can **monitor** the **pasteboard** **while you navigate** through the application with **objection's** `ios pasteboard monitor`
|
||||
|
||||
## Backups
|
||||
|
||||
iOS includes auto-backup features that create copies of the data stored on the device. You can **make iOS backups** from your host computer by using iTunes \(till macOS Catalina\) or Finder \(from macOS Catalina onwards\), or via the iCloud backup feature. In both cases, the backup includes nearly all data stored on the iOS device except highly sensitive data such as Apple Pay information and Touch ID settings.
|
||||
|
@ -943,6 +701,28 @@ Usage: /[!bf] [arg] Search stuff (see 'e??search' for options)
|
|||
|
||||
By using [**r2frida**](https://github.com/nowsecure/r2frida) you can analyze and inspect the app's memory while running and without needing to dump it. For example, you may run the previous search commands from r2frida and search the memory for a string, hexadecimal values, etc. When doing so, remember to prepend the search command \(and any other r2frida specific commands\) with a backslash `\` after starting the session with `r2 frida://usb//<name_of_your_app>`.
|
||||
|
||||
## Broken Cryptography
|
||||
|
||||
### Poor Key Management Processes
|
||||
|
||||
Some developers save sensitive data in the local storage and encrypt it with a key hardcoded/predictable in the code. This shouldn't be done as some reversing could allow attackers to extract the confidential information.
|
||||
|
||||
### Use of Insecure and/or Deprecated Algorithms
|
||||
|
||||
Developers shouldn't use **deprecated algorithms** to perform authorisation **checks**, **store** or **send** data. Some of these algorithms are: RC4, MD4, MD5, SHA1... If **hashes** are used to store passwords for example, hashes brute-force **resistant** should be used with salt.
|
||||
|
||||
### Check
|
||||
|
||||
The main checks to perform if to find if you can find **hardcoded** passwords/secrets in the code, or if those are **predictable**, and if the code is using some king of **weak** **cryptography** algorithms.
|
||||
|
||||
It's interesting to know that you can **monitor** some **crypto** **libraries** automatically using **objection** with:
|
||||
|
||||
```swift
|
||||
ios monitor crypt
|
||||
```
|
||||
|
||||
For **more information** about iOS cryptographic APIs and libraries access [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography)
|
||||
|
||||
## Local Authentication
|
||||
|
||||
The tester should be aware that **local authentication should always be enforced at a remote endpoint** or based on a cryptographic primitive. Attackers can easily bypass local authentication if no data returns from the authentication process.
|
||||
|
@ -1395,6 +1175,89 @@ func application(_ application: UIApplication,
|
|||
}
|
||||
```
|
||||
|
||||
### UIActivity Sharing
|
||||
|
||||
{% page-ref page="ios-uiactivity-sharing.md" %}
|
||||
|
||||
### UIPasteboard
|
||||
|
||||
The [`UIPasteboard`](https://developer.apple.com/documentation/uikit/uipasteboard) enables sharing data within an app, and from an app to other apps. There are two kinds of pasteboards:
|
||||
|
||||
* **systemwide general pasteboard**: for sharing data with **any app**. Persistent by default across device restarts and app uninstalls \(since iOS 10\).
|
||||
* **custom / named pasteboards**: for sharing data **with another app** \(having the same team ID as the app to share from\) or with the **app itself** \(they are only available in the process that creates them\). Non-persistent by default \(since iOS 10\), that is, they exist only until the owning \(creating\) app quits.
|
||||
|
||||
Some security considerations:
|
||||
|
||||
* Users **cannot grant or deny permission** for apps to read the **pasteboard**.
|
||||
* Since iOS 9, apps [cannot access the pasteboard while in background](https://forums.developer.apple.com/thread/13760), this mitigates background pasteboard monitoring.
|
||||
* [Apple warns about persistent named pasteboards](https://developer.apple.com/documentation/uikit/uipasteboard?language=objc) and **discourages their use**. Instead, shared containers should be used.
|
||||
* Starting in iOS 10 there is a new Handoff feature called **Universal Clipboard** that is enabled by default. It allows the **general pasteboard contents to automatically transfer between devices**. This feature can be disabled if the developer chooses to do so and it is also possible to set an expiration time and date for copied data.
|
||||
|
||||
Then, it's important to **check that sensitive information isn't being saved inside the global pasteboard**.
|
||||
It's also important to check that an **application isn't using the global pasteboard data to perform actions**, as malicious application could tamper this data.
|
||||
|
||||
An **application can also prevent its users to copy sensitive data to the clipboard** \(which is recommended\).
|
||||
|
||||
#### Static Analysis
|
||||
|
||||
The **systemwide general pasteboard** can be obtained by using [`generalPasteboard`](https://developer.apple.com/documentation/uikit/uipasteboard/1622106-generalpasteboard?language=objc), search the source code or the compiled binary for this method. Using the systemwide general pasteboard should be avoided when dealing with sensitive data.
|
||||
|
||||
**Custom pasteboards** can be created with [`pasteboardWithName:create:`](https://developer.apple.com/documentation/uikit/uipasteboard/1622074-pasteboardwithname?language=objc) or [`pasteboardWithUniqueName`](https://developer.apple.com/documentation/uikit/uipasteboard/1622087-pasteboardwithuniquename?language=objc). Verify if custom pasteboards are set to be persistent as this is deprecated since iOS 10. A shared container should be used instead.
|
||||
|
||||
#### Dynamic analysis
|
||||
|
||||
Hook or trace the following:
|
||||
|
||||
* `generalPasteboard` for the system-wide general pasteboard.
|
||||
* `pasteboardWithName:create:` and `pasteboardWithUniqueName` for custom pasteboards.
|
||||
|
||||
You can also Hook or trace the deprecated [`setPersistent:`](https://developer.apple.com/documentation/uikit/uipasteboard/1622096-setpersistent?language=objc) method and verify if it's being called.
|
||||
|
||||
When **monitoring** the **pasteboards**, there is several **details** that may be dynamically **retrieved**:
|
||||
|
||||
* Obtain **pasteboard name** by hooking `pasteboardWithName:create:` and inspecting its input parameters or `pasteboardWithUniqueName` and inspecting its return value.
|
||||
* Get the **first available pasteboard item**: e.g. for strings use `string` method. Or use any of the other methods for the [standard data types](https://developer.apple.com/documentation/uikit/uipasteboard?language=objc#1654275).
|
||||
* Get the **number of items** with `numberOfItems`.
|
||||
* Check for **existence of standard data types** with the [convenience methods](https://developer.apple.com/documentation/uikit/uipasteboard?language=objc#2107142), e.g. `hasImages`, `hasStrings`, `hasURLs` \(starting in iOS 10\).
|
||||
* Check for **other data types** \(typically UTIs\) with [`containsPasteboardTypes:inItemSet:`](https://developer.apple.com/documentation/uikit/uipasteboard/1622100-containspasteboardtypes?language=objc). You may inspect for more concrete data types like, for example an picture as public.png and public.tiff \([UTIs](http://web.archive.org/web/20190616231857/https://developer.apple.com/documentation/mobilecoreservices/uttype)\) or for custom data such as com.mycompany.myapp.mytype. Remember that, in this case, only those apps that _declare knowledge_ of the type are able to understand the data written to the pasteboard. Retrieve them using [`itemSetWithPasteboardTypes:`](https://developer.apple.com/documentation/uikit/uipasteboard/1622071-itemsetwithpasteboardtypes?language=objc) and setting the corresponding UTIs.
|
||||
* Check for excluded or expiring items by hooking `setItems:options:` and inspecting its options for `UIPasteboardOptionLocalOnly` or `UIPasteboardOptionExpirationDate`.
|
||||
|
||||
If only looking for strings you may want to use **objection's** command `ios pasteboard monitor`:
|
||||
|
||||
> Hooks into the iOS UIPasteboard class and polls the generalPasteboard every 5 seconds for data. If new data is found, different from the previous poll, that data will be dumped to screen.
|
||||
|
||||
You may also build your own pasteboard monitor that monitors specific information as seen above.
|
||||
|
||||
For example, this script \(inspired from the script behind [objection's pasteboard monitor](https://github.com/sensepost/objection/blob/b39ee53b5ba2e9a271797d2f3931d79c46dccfdb/agent/src/ios/pasteboard.ts)\) reads the pasteboard items every 5 seconds, if there's something new it will print it:
|
||||
|
||||
```javascript
|
||||
const UIPasteboard = ObjC.classes.UIPasteboard;
|
||||
const Pasteboard = UIPasteboard.generalPasteboard();
|
||||
var items = "";
|
||||
var count = Pasteboard.changeCount().toString();
|
||||
|
||||
setInterval(function () {
|
||||
const currentCount = Pasteboard.changeCount().toString();
|
||||
const currentItems = Pasteboard.items().toString();
|
||||
|
||||
if (currentCount === count) { return; }
|
||||
|
||||
items = currentItems;
|
||||
count = currentCount;
|
||||
|
||||
console.log('[* Pasteboard changed] count: ' + count +
|
||||
' hasStrings: ' + Pasteboard.hasStrings().toString() +
|
||||
' hasURLs: ' + Pasteboard.hasURLs().toString() +
|
||||
' hasImages: ' + Pasteboard.hasImages().toString());
|
||||
console.log(items);
|
||||
|
||||
}, 1000 * 5);
|
||||
```
|
||||
|
||||
### App Extensions
|
||||
|
||||
{% page-ref page="ios-app-extensions.md" %}
|
||||
|
||||
## Network Communication
|
||||
|
||||
It's important to check that no communication is occurring **without encryption** and also that the application is correctly **validating the TLS certificate** of the server.
|
||||
|
|
175
ios-pentesting/ios-app-extensions.md
Normal file
175
ios-pentesting/ios-app-extensions.md
Normal file
|
@ -0,0 +1,175 @@
|
|||
# iOS App Extensions
|
||||
|
||||
**Content copied form** [**https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction\#app-extensions**](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#app-extensions)\*\*\*\*
|
||||
|
||||
App extensions let apps offer custom functionality and content to users while they’re interacting with other apps or the system. Some notable ones are:
|
||||
|
||||
* **Custom Keyboard**: replaces the iOS system keyboard with a custom keyboard for use in all apps.
|
||||
* **Share**: post to a sharing website or share content with others.
|
||||
* **Today**: also called **widgets**, they offer content or perform quick tasks in the Today view of Notification Center.
|
||||
|
||||
For example, the user selects text in the _host app_, clicks on the "Share" button and selects one "app" or action from the list. This triggers the _app extension_ of the _containing app_. The app extension displays its view within the context of the host app and uses the items provided by the host app, the selected text in this case, to perform a specific task \(post it on a social network, for example\). See this picture from the [Apple App Extension Programming Guide](https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionOverview.html#//apple_ref/doc/uid/TP40014214-CH2-SW13) which pretty good summarizes this:
|
||||
|
||||
![](https://gblobscdn.gitbook.com/assets%2F-LH00RC4WVf3-6Ou4e0l%2F-Lf1APQHyCHdAvoJSvc_%2F-Lf1AQx9khfTwUwYuMti%2Fapp_extensions_communication.png?alt=media)
|
||||
|
||||
### **Security Considerations**
|
||||
|
||||
From the security point of view it is important to note that:
|
||||
|
||||
* An **app extension does never communicate directly with its containing app** \(typically, it isn’t even running while the contained app extension is running\).
|
||||
* An **app extension** and the **host app** **communicate** via **inter-process** communication.
|
||||
* An **app extension’s** containing app and the **host app don’t communicate** at all.
|
||||
* A **Today** **widget** \(and no other app extension type\) can ask the system to open its containing app by calling the `openURL:completionHandler:` method of the `NSExtensionContext` class.
|
||||
* Any **app extension** and its **containing app** can **access shared data in a privately** defined shared container.
|
||||
* App extensions **cannot access some APIs**, for example, HealthKit.
|
||||
* They **cannot receive data using AirDrop** but do can send data.
|
||||
* **No long-running background tasks** are allowed but uploads or downloads can be initiated.
|
||||
* App extensions **cannot access the camera or microphone on an iOS device** \(except for iMessage app extensions\).
|
||||
|
||||
### Static analysis
|
||||
|
||||
#### **Verifying if the App Contains App Extensions**
|
||||
|
||||
If you have the original source code you can search for all occurrences of `NSExtensionPointIdentifier` with Xcode \(cmd+shift+f\) or take a look into "Build Phases / Embed App extensions":
|
||||
|
||||
![](../.gitbook/assets/image%20%28505%29.png)
|
||||
|
||||
There you can find the names of all embedded app extensions followed by `.appex`, now you can navigate to the individual app extensions in the project.
|
||||
|
||||
If not having the original source code:
|
||||
|
||||
Grep for `NSExtensionPointIdentifier` among all files inside the app bundle \(IPA or installed app\):
|
||||
|
||||
```bash
|
||||
$ grep -nr NSExtensionPointIdentifier Payload/Telegram\ X.app/
|
||||
Binary file Payload/Telegram X.app//PlugIns/SiriIntents.appex/Info.plist matches
|
||||
Binary file Payload/Telegram X.app//PlugIns/Share.appex/Info.plist matches
|
||||
Binary file Payload/Telegram X.app//PlugIns/NotificationContent.appex/Info.plist matches
|
||||
Binary file Payload/Telegram X.app//PlugIns/Widget.appex/Info.plist matches
|
||||
Binary file Payload/Telegram X.app//Watch/Watch.app/PlugIns/Watch Extension.appex/Info.plist matches
|
||||
```
|
||||
|
||||
You can also access per SSH, find the app bundle and list all inside PlugIns \(they are placed there by default\) or do it with objection:
|
||||
|
||||
```bash
|
||||
ph.telegra.Telegraph on (iPhone: 11.1.2) [usb] # cd PlugIns
|
||||
/var/containers/Bundle/Application/15E6A58F-1CA7-44A4-A9E0-6CA85B65FA35/
|
||||
Telegram X.app/PlugIns
|
||||
|
||||
ph.telegra.Telegraph on (iPhone: 11.1.2) [usb] # ls
|
||||
NSFileType Perms NSFileProtection Read Write Name
|
||||
------------ ------- ------------------ ------ ------- -------------------------
|
||||
Directory 493 None True False NotificationContent.appex
|
||||
Directory 493 None True False Widget.appex
|
||||
Directory 493 None True False Share.appex
|
||||
Directory 493 None True False SiriIntents.appex
|
||||
```
|
||||
|
||||
We can see now the same four app extensions that we saw in Xcode before.
|
||||
|
||||
#### **Determining the Supported Data Types**
|
||||
|
||||
This is important for data being shared with host apps \(e.g. via Share or Action Extensions\). When the user selects some data type in a host app and it matches the data types define here, the host app will offer the extension. It is worth noticing the difference between this and data sharing via `UIActivity` where we had to define the document types, also using UTIs. An app does not need to have an extension for that. It is possible to share data using only `UIActivity`.
|
||||
|
||||
Inspect the app extension's `Info.plist` file and search for `NSExtensionActivationRule`. That key specifies the data being supported as well as e.g. maximum of items supported. For example:
|
||||
|
||||
```markup
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationRule</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
||||
<integer>10</integer>
|
||||
<key>NSExtensionActivationSupportsMovieWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
```
|
||||
|
||||
Only the data types present here and not having `0` as `MaxCount` will be supported. However, more complex filtering is possible by using a so-called predicate string that will evaluate the UTIs given. Please refer to the [Apple App Extension Programming Guide](https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW8) for more detailed information about this.
|
||||
|
||||
**Checking Data Sharing with the Containing App**
|
||||
|
||||
Remember that app extensions and their containing apps do not have direct access to each other’s containers. However, data sharing can be enabled. This is done via ["App Groups"](https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW19) and the [`NSUserDefaults`](https://developer.apple.com/documentation/foundation/nsuserdefaults) API. See this figure from [Apple App Extension Programming Guide](https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW11):
|
||||
|
||||
As also mentioned in the guide, the app must set up a shared container if the app extension uses the `NSURLSession` class to perform a background upload or download, so that both the extension and its containing app can access the transferred data.
|
||||
|
||||
**Verifying if the App Restricts the Use of App Extensions**
|
||||
|
||||
It is possible to reject a specific type of app extension by using the following method:
|
||||
|
||||
* [`application:shouldAllowExtensionPointIdentifier:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623122-application?language=objc)
|
||||
|
||||
However, it is currently only possible for "custom keyboard" app extensions \(and should be verified when testing apps handling sensitive data via the keyboard like e.g. banking apps\).
|
||||
|
||||
### Dynamic Analysis
|
||||
|
||||
For the dynamic analysis we can do the following to gain knowledge without having the source code:
|
||||
|
||||
* Inspecting the items being shared
|
||||
* Identifying the app extensions involved
|
||||
|
||||
**Inspecting the Items Being Shared**
|
||||
|
||||
For this we should hook `NSExtensionContext - inputItems` in the data originating app.
|
||||
|
||||
Following the previous example of Telegram we will now use the "Share" button on a text file \(that was received from a chat\) to create a note in the Notes app with it:
|
||||
|
||||
![](../.gitbook/assets/image%20%28506%29.png)
|
||||
|
||||
If we run a trace, we'd see the following output:
|
||||
|
||||
```bash
|
||||
(0x1c06bb420) NSExtensionContext - inputItems
|
||||
0x18284355c Foundation!-[NSExtension _itemProviderForPayload:extensionContext:]
|
||||
0x1828447a4 Foundation!-[NSExtension _loadItemForPayload:contextIdentifier:completionHandler:]
|
||||
0x182973224 Foundation!__NSXPCCONNECTION_IS_CALLING_OUT_TO_EXPORTED_OBJECT_S3__
|
||||
0x182971968 Foundation!-[NSXPCConnection _decodeAndInvokeMessageWithEvent:flags:]
|
||||
0x182748830 Foundation!message_handler
|
||||
0x181ac27d0 libxpc.dylib!_xpc_connection_call_event_handler
|
||||
0x181ac0168 libxpc.dylib!_xpc_connection_mach_event
|
||||
...
|
||||
RET: (
|
||||
"<NSExtensionItem: 0x1c420a540> - userInfo:
|
||||
{
|
||||
NSExtensionItemAttachmentsKey = (
|
||||
"<NSItemProvider: 0x1c46b30e0> {types = (\n \"public.plain-text\",\n \"public.file-url\"\n)}"
|
||||
);
|
||||
}"
|
||||
)
|
||||
```
|
||||
|
||||
Here we can observe that:
|
||||
|
||||
* This occurred under-the-hood via XPC, concretely it is implemented via a `NSXPCConnection` that uses the `libxpc.dylib` Framework.
|
||||
* The UTIs included in the `NSItemProvider` are `public.plain-text` and `public.file-url`, the latter being included in `NSExtensionActivationRule` from the [`Info.plist` of the "Share Extension" of Telegram](https://github.com/TelegramMessenger/Telegram-iOS/blob/master/Telegram/Share/Info.plist).
|
||||
|
||||
**Identifying the App Extensions Involved**
|
||||
|
||||
You can also find out which app extension is taking care of your the requests and responses by hooking `NSExtension - _plugIn`:
|
||||
|
||||
We run the same example again:
|
||||
|
||||
```bash
|
||||
(0x1c0370200) NSExtension - _plugIn
|
||||
RET: <PKPlugin: 0x1163637f0 ph.telegra.Telegraph.Share(5.3) 5B6DE177-F09B-47DA-90CD-34D73121C785
|
||||
1(2) /private/var/containers/Bundle/Application/15E6A58F-1CA7-44A4-A9E0-6CA85B65FA35
|
||||
/Telegram X.app/PlugIns/Share.appex>
|
||||
|
||||
(0x1c0372300) -[NSExtension _plugIn]
|
||||
RET: <PKPlugin: 0x10bff7910 com.apple.mobilenotes.SharingExtension(1.5) 73E4F137-5184-4459-A70A-83
|
||||
F90A1414DC 1(2) /private/var/containers/Bundle/Application/5E267B56-F104-41D0-835B-F1DAB9AE076D
|
||||
/MobileNotes.app/PlugIns/com.apple.mobilenotes.SharingExtension.appex>
|
||||
```
|
||||
|
||||
As you can see there are two app extensions involved:
|
||||
|
||||
* `Share.appex` is sending the text file \(`public.plain-text` and `public.file-url`\).
|
||||
* `com.apple.mobilenotes.SharingExtension.appex` which is receiving and will process the text file.
|
||||
|
||||
If you want to learn more about what's happening under-the-hood in terms of XPC, we recommend to take a look at the internal calls from "libxpc.dylib". For example you can use [`frida-trace`](https://www.frida.re/docs/frida-trace/) and then dig deeper into the methods that you find more interesting by extending the automatically generated stubs.
|
||||
|
||||
###
|
||||
|
258
ios-pentesting/ios-hooking-with-objection.md
Normal file
258
ios-pentesting/ios-hooking-with-objection.md
Normal file
|
@ -0,0 +1,258 @@
|
|||
# iOS Hooking With Objection
|
||||
|
||||
For this section the tool [**Objection**](https://github.com/sensepost/objection) is going to be used.
|
||||
Start by getting an objection's session executing something like:
|
||||
|
||||
```bash
|
||||
objection -d --gadget "iGoat-Swift" explore
|
||||
objection -d --gadget "OWASP.iGoat-Swift" explore
|
||||
```
|
||||
|
||||
## Basic Enumeration of the app
|
||||
|
||||
### Local App Paths
|
||||
|
||||
* `env`: Find the paths where the application is stored inside the device
|
||||
|
||||
```bash
|
||||
env
|
||||
|
||||
Name Path
|
||||
----------------- -----------------------------------------------------------------------------------------------
|
||||
BundlePath /private/var/containers/Bundle/Application/179A6E8B-E7A8-476E-BBE3-B9300F546068/iGoat-Swift.app
|
||||
CachesDirectory /var/mobile/Containers/Data/Application/A079DF84-726C-4AEA-A194-805B97B3684A/Library/Caches
|
||||
DocumentDirectory /var/mobile/Containers/Data/Application/A079DF84-726C-4AEA-A194-805B97B3684A/Documents
|
||||
LibraryDirectory /var/mobile/Containers/Data/Application/A079DF84-726C-4AEA-A194-805B97B3684A/Library
|
||||
```
|
||||
|
||||
### List Bundles, frameworks and libraries
|
||||
|
||||
* `ios bundles list_bundles`: List bundles of the application
|
||||
|
||||
```bash
|
||||
ios bundles list_bundles
|
||||
Executable Bundle Version Path
|
||||
------------ -------------------- --------- -------------------------------------------
|
||||
iGoat-Swift OWASP.iGoat-Swift 1.0 ...8-476E-BBE3-B9300F546068/iGoat-Swift.app
|
||||
AGXMetalA9 com.apple.AGXMetalA9 172.18.4 ...tem/Library/Extensions/AGXMetalA9.bundle
|
||||
```
|
||||
|
||||
* `ios bundles list_frameworks`: List external frameworks used by the application
|
||||
|
||||
```bash
|
||||
ios bundles list_frameworks
|
||||
Executable Bundle Version Path
|
||||
------------------------------ -------------------------------------------- ---------- -------------------------------------------
|
||||
ReactCommon org.cocoapods.ReactCommon 0.61.5 ...tle.app/Frameworks/ReactCommon.framework
|
||||
...vateFrameworks/CoreDuetContext.framework
|
||||
FBReactNativeSpec org.cocoapods.FBReactNativeSpec 0.61.5 ...p/Frameworks/FBReactNativeSpec.framework
|
||||
...ystem/Library/Frameworks/IOKit.framework
|
||||
RCTAnimation org.cocoapods.RCTAnimation 0.61.5 ...le.app/Frameworks/RCTAnimation.framework
|
||||
jsinspector org.cocoapods.jsinspector 0.61.5 ...tle.app/Frameworks/jsinspector.framework
|
||||
DoubleConversion org.cocoapods.DoubleConversion 1.1.6 ...pp/Frameworks/DoubleConversion.framework
|
||||
react_native_config org.cocoapods.react-native-config 0.12.0 ...Frameworks/react_native_config.framework
|
||||
react_native_netinfo org.cocoapods.react-native-netinfo 4.4.0 ...rameworks/react_native_netinfo.framework
|
||||
PureLayout org.cocoapods.PureLayout 3.1.5 ...ttle.app/Frameworks/PureLayout.framework
|
||||
GoogleUtilities org.cocoapods.GoogleUtilities 6.6.0 ...app/Frameworks/GoogleUtilities.framework
|
||||
RCTNetwork org.cocoapods.RCTNetwork 0.61.5 ...ttle.app/Frameworks/RCTNetwork.framework
|
||||
RCTActionSheet org.cocoapods.RCTActionSheet 0.61.5 ....app/Frameworks/RCTActionSheet.framework
|
||||
react_native_image_editor org.cocoapods.react-native-image-editor 2.1.0 ...orks/react_native_image_editor.framework
|
||||
CoreModules org.cocoapods.CoreModules 0.61.5 ...tle.app/Frameworks/CoreModules.framework
|
||||
RCTVibration org.cocoapods.RCTVibration 0.61.5 ...le.app/Frameworks/RCTVibration.framework
|
||||
RNGestureHandler org.cocoapods.RNGestureHandler 1.6.1 ...pp/Frameworks/RNGestureHandler.framework
|
||||
RNCClipboard org.cocoapods.RNCClipboard 1.5.1 ...le.app/Frameworks/RNCClipboard.framework
|
||||
react_native_image_picker org.cocoapods.react-native-image-picker 2.3.4 ...orks/react_native_image_picker.framework
|
||||
[..]
|
||||
```
|
||||
|
||||
* `memory list modules`: List loaded modules in memory
|
||||
|
||||
```bash
|
||||
memory list modules
|
||||
Name Base Size Path
|
||||
----------------------------------- ----------- ------------------- ------------------------------------------------------------------------------
|
||||
iGoat-Swift 0x104ffc000 2326528 (2.2 MiB) /private/var/containers/Bundle/Application/179A6E8B-E7A8-476E-BBE3-B9300F54...
|
||||
SubstrateBootstrap.dylib 0x105354000 16384 (16.0 KiB) /usr/lib/substrate/SubstrateBootstrap.dylib
|
||||
SystemConfiguration 0x1aa842000 495616 (484.0 KiB) /System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguratio...
|
||||
libc++.1.dylib 0x1bdcfd000 368640 (360.0 KiB) /usr/lib/libc++.1.dylib
|
||||
libz.1.dylib 0x1efd3c000 73728 (72.0 KiB) /usr/lib/libz.1.dylib
|
||||
libsqlite3.dylib 0x1c267f000 1585152 (1.5 MiB) /usr/lib/libsqlite3.dylib
|
||||
Foundation 0x1ab550000 2732032 (2.6 MiB) /System/Library/Frameworks/Foundation.framework/Foundation
|
||||
libobjc.A.dylib 0x1bdc64000 233472 (228.0 KiB) /usr/lib/libobjc.A.dylib
|
||||
[...]
|
||||
```
|
||||
|
||||
* `memory list exports <module_name>`: Exports of a loaded module
|
||||
|
||||
```bash
|
||||
memory list exports iGoat-Swift
|
||||
Type Name Address
|
||||
-------- -------------------------------------------------------------------------------------------------------------------------------------- -----------
|
||||
variable _mh_execute_header 0x104ffc000
|
||||
function _mdictof 0x10516cb88
|
||||
function _ZN9couchbase6differ10BaseDifferD2Ev 0x10516486c
|
||||
function _ZN9couchbase6differ10BaseDifferD1Ev 0x1051648f4
|
||||
function _ZN9couchbase6differ10BaseDifferD0Ev 0x1051648f8
|
||||
function _ZN9couchbase6differ10BaseDiffer5setupEmm 0x10516490c
|
||||
function _ZN9couchbase6differ10BaseDiffer11allocStripeEmm 0x105164a20
|
||||
function _ZN9couchbase6differ10BaseDiffer7computeEmmj 0x105164ad8
|
||||
function _ZN9couchbase6differ10BaseDiffer7changesEv 0x105164de4
|
||||
function _ZN9couchbase6differ10BaseDiffer9addChangeENS0_6ChangeE 0x105164fa8
|
||||
function _ZN9couchbase6differlsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS0_6ChangeE 0x1051651d8
|
||||
function _ZN9couchbase6differlsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS1_6vectorINS0_6ChangeENS1_9allocatorIS8_EEEE 0x105165280
|
||||
variable _ZTSN9couchbase6differ10BaseDifferE 0x1051d94f0
|
||||
variable _ZTVN9couchbase6differ10BaseDifferE 0x10523c0a0
|
||||
variable _ZTIN9couchbase6differ10BaseDifferE 0x10523c0f8
|
||||
[..]
|
||||
```
|
||||
|
||||
### List classes of an APP
|
||||
|
||||
* `ios hooking list classes`: List classes of the app
|
||||
|
||||
```bash
|
||||
ios hooking list classes
|
||||
|
||||
AAAbsintheContext
|
||||
AAAbsintheSigner
|
||||
AAAbsintheSignerContextCache
|
||||
AAAcceptedTermsController
|
||||
AAAccount
|
||||
AAAccountManagementUIResponse
|
||||
AAAccountManager
|
||||
AAAddEmailUIRequest
|
||||
AAAppleIDSettingsRequest
|
||||
AAAppleTVRequest
|
||||
AAAttestationSigner
|
||||
[...]
|
||||
```
|
||||
|
||||
* `ios hooking search classes <search_term>`: Search a class that contains a string. You can **search some uniq term that is related to the main app package** name to find the main classes of the app like in the example:
|
||||
|
||||
```bash
|
||||
ios hooking search classes iGoat
|
||||
iGoat_Swift.CoreDataHelper
|
||||
iGoat_Swift.RCreditInfo
|
||||
iGoat_Swift.SideContainmentSegue
|
||||
iGoat_Swift.CenterContainmentSegue
|
||||
iGoat_Swift.KeyStorageServerSideVC
|
||||
iGoat_Swift.HintVC
|
||||
iGoat_Swift.BinaryCookiesExerciseVC
|
||||
iGoat_Swift.ExerciseDemoVC
|
||||
iGoat_Swift.PlistStorageExerciseViewController
|
||||
iGoat_Swift.CouchBaseExerciseVC
|
||||
iGoat_Swift.MemoryManagementVC
|
||||
[...]
|
||||
```
|
||||
|
||||
### List class methods
|
||||
|
||||
* `ios hooking list class_methods`: List methods of a specific class
|
||||
|
||||
```bash
|
||||
ios hooking list class_methods iGoat_Swift.RCreditInfo
|
||||
- cvv
|
||||
- setCvv:
|
||||
- setName:
|
||||
- .cxx_destruct
|
||||
- name
|
||||
- cardNumber
|
||||
- init
|
||||
- initWithValue:
|
||||
- setCardNumber:
|
||||
```
|
||||
|
||||
* `ios hooking search methods <search_term>`: Search a method that contains a string
|
||||
|
||||
```bash
|
||||
ios hooking search methods cvv
|
||||
[AMSFinanceVerifyPurchaseResponse + _dialogRequestForCVVFromPayload:verifyType:]
|
||||
[AMSFinanceVerifyPurchaseResponse - _handleCVVDialogResult:shouldReattempt:]
|
||||
[AMSFinanceVerifyPurchaseResponse - _runCVVRequestForCode:error:]
|
||||
[iGoat_Swift.RCreditInfo - cvv]
|
||||
[iGoat_Swift.RCreditInfo - setCvv:]
|
||||
[iGoat_Swift.RealmExerciseVC - creditCVVTextField]
|
||||
[iGoat_Swift.RealmExerciseVC - setCreditCVVTextField:]
|
||||
[iGoat_Swift.DeviceLogsExerciseVC - cvvTextField]
|
||||
[iGoat_Swift.DeviceLogsExerciseVC - setCvvTextField:]
|
||||
[iGoat_Swift.CloudMisconfigurationExerciseVC - cvvTxtField]
|
||||
[iGoat_Swift.CloudMisconfigurationExerciseVC - setCvvTxtField:]
|
||||
```
|
||||
|
||||
## Basic Hooking
|
||||
|
||||
Now that you have **enumerated the classes and modules** used by the application you may have found some **interesting class and method names**.
|
||||
|
||||
### Hook all methods of a class
|
||||
|
||||
* `ios hooking watch class <class_name>`: Hook all the methods of a class, dump all the initial parameters and returns
|
||||
|
||||
```bash
|
||||
ios hooking watch class iGoat_Swift.PlistStorageExerciseViewController
|
||||
```
|
||||
|
||||
### Hook a single method
|
||||
|
||||
* `ios hooking watch method "-[<class_name> <method_name>]" --dump-args --dump-return --dump-backtrace`: Hook an specific method of a class dumping the parameters, backtraces and returns of the method each time it's called
|
||||
|
||||
```bash
|
||||
ios hooking watch method "-[iGoat_Swift.BinaryCookiesExerciseVC verifyItemPressed]" --dump-args --dump-backtrace --dump-return
|
||||
```
|
||||
|
||||
### Change Boolean Return
|
||||
|
||||
* `ios hooking set return_value "-[<class_name> <method_name>]" false`: This will make the selected method return the indicated boolean
|
||||
|
||||
```bash
|
||||
ios hooking set return_value "-[iGoat_Swift.BinaryCookiesExerciseVC verifyItemPressed]" false
|
||||
```
|
||||
|
||||
### Generate hooking template
|
||||
|
||||
* `ios hooking generate simple <class_name>`:
|
||||
|
||||
```bash
|
||||
ios hooking generate simple iGoat_Swift.RCreditInfo
|
||||
|
||||
var target = ObjC.classes.iGoat_Swift.RCreditInfo;
|
||||
|
||||
Interceptor.attach(target['+ sharedSchema'].implementation, {
|
||||
onEnter: function (args) {
|
||||
console.log('Entering + sharedSchema!');
|
||||
},
|
||||
onLeave: function (retval) {
|
||||
console.log('Leaving + sharedSchema');
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Interceptor.attach(target['+ className'].implementation, {
|
||||
onEnter: function (args) {
|
||||
console.log('Entering + className!');
|
||||
},
|
||||
onLeave: function (retval) {
|
||||
console.log('Leaving + className');
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Interceptor.attach(target['- cvv'].implementation, {
|
||||
onEnter: function (args) {
|
||||
console.log('Entering - cvv!');
|
||||
},
|
||||
onLeave: function (retval) {
|
||||
console.log('Leaving - cvv');
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Interceptor.attach(target['- setCvv:'].implementation, {
|
||||
onEnter: function (args) {
|
||||
console.log('Entering - setCvv:!');
|
||||
},
|
||||
onLeave: function (retval) {
|
||||
console.log('Leaving - setCvv:');
|
||||
},
|
||||
});
|
||||
```
|
||||
|
69
ios-pentesting/ios-uiactivity-sharing.md
Normal file
69
ios-pentesting/ios-uiactivity-sharing.md
Normal file
|
@ -0,0 +1,69 @@
|
|||
# iOS UIActivity Sharing
|
||||
|
||||
## UIActivity Sharing
|
||||
|
||||
Starting on iOS 6 it is possible for third-party apps to **share data \(items\)** via specific mechanisms [like AirDrop, for example](https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple_ref/doc/uid/TP40007072-CH6-SW3). From a user perspective, this feature is the well-known system-wide _share activity sheet_ that appears after clicking on the "Share" button.
|
||||
|
||||
A full list of the available built-in sharing mechanisms can be found in [UIActivity.ActivityType](https://developer.apple.com/documentation/uikit/uiactivity/activitytype). If not considered appropriate for the app, the d**evelopers have the possibility to exclude some of these sharing mechanisms**.
|
||||
|
||||
### **Sending Items**
|
||||
|
||||
When testing `UIActivity` Sharing you should pay special attention to:
|
||||
|
||||
* the data \(items\) being shared,
|
||||
* the custom activities,
|
||||
* the excluded activity types.
|
||||
|
||||
Data sharing via `UIActivity` works by creating a `UIActivityViewController` and passing it the desired items \(URLs, text, a picture\) on [`init(activityItems:applicationActivities:)`](https://developer.apple.com/documentation/uikit/uiactivityviewcontroller/1622019-init).
|
||||
|
||||
If having the source code, you should take a look at the `UIActivityViewController`:
|
||||
|
||||
* Inspect the activities passed to the `init(activityItems:applicationActivities:)` method.
|
||||
* Check if it defines custom activities \(also being passed to the previous method\).
|
||||
* Verify the `excludedActivityTypes`, if any.
|
||||
|
||||
If you only have the compiled/installed app, try searching for the previous method and property, for example:
|
||||
|
||||
```bash
|
||||
$ rabin2 -zq Telegram\ X.app/Telegram\ X | grep -i activityItems
|
||||
0x1000df034 45 44 initWithActivityItems:applicationActivities:
|
||||
```
|
||||
|
||||
### **Receiving Items**
|
||||
|
||||
When receiving items, you should check:
|
||||
|
||||
* if the app **declares** _**custom document types**_ ****by looking into **Exported/Imported UTIs** \("Info" tab of the Xcode project\). The list of all system declared UTIs \(Uniform Type Identifiers\) can be found in the [archived Apple Developer Documentation](https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html#//apple_ref/doc/uid/TP40009259).
|
||||
* if the app specifies any _**document types that it can open**_ by looking into **Document Types** \("Info" tab of the Xcode project\). If present, they consist of name and one or more UTIs that represent the data type \(e.g. "public.png" for PNG files\). iOS uses this to determine if the app is eligible to open a given document \(specifying Exported/Imported UTIs is not enough\).
|
||||
* if the app properly _**verifies the received data**_ by looking into the implementation of [`application:openURL:options:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application?language=objc) \(or its deprecated version [`UIApplicationDelegate application:openURL:sourceApplication:annotation:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623073-application?language=objc)\) in the app delegate.
|
||||
|
||||
If not having the source code you can still take a look into the `Info.plist` file and search for:
|
||||
|
||||
* `UTExportedTypeDeclarations`/`UTImportedTypeDeclarations` if the app declares exported/imported _custom document types_.
|
||||
* `CFBundleDocumentTypes` to see if the app specifies any _document types that it can open_.
|
||||
|
||||
A very complete explanation about the use of these keys can be found [on Stackoverflow](https://stackoverflow.com/questions/21937978/what-are-utimportedtypedeclarations-and-utexportedtypedeclarations-used-for-on-i) but here you have a summary:
|
||||
|
||||
* `UTExportedTypeDeclarations`: Use them to define **your own UTIs** that your app wants to teach the system it is installed on. An **UTI describes a piece of data** \(_not necessarily data located inside a file!_\) and requires at least an **identifier** \(`com.example.MyCoolDataType`\). Additionally it may have a **name** \(`My Cool Data Type`\), one or more file name **extensions** \(`.myCoolDataType`\), one or more **MIME** **types** \(`x-application/my-cool-data-type`\), one or more **pasteboard** **types** \(used when transferring data of that kind using copy&paste\), and one or more **legacy OS type**. Usually you also want UTIs to conform to existing UTIs \(E.g. when you say your UTI conforms to `public.data`, any process that can deal with generic data can also deal with your UTI\).
|
||||
* e.g.: You define your own proprietary file data format and you want this data format to be also known to other apps, plugins, extensions, and so on.
|
||||
* `UTImportedTypeDeclarations`: You use `UTImportedTypeDeclarations` do **teach the system about UTIs that you want to be known in the system but that are not your UTIs**.
|
||||
* e.g.: Your app is able to read the proprietary data format of another application, yet you don't know if that application is even installed on the system.
|
||||
* `CFBundleDocumentTypes`: You use `CFBundleDocumentTypes` to tell the system which Document types your app is able to open. Unless you **also list your UTIs here**, these UTIs are not associated with your app in Finder and your app won't appear in the `Open With >` menu. The only thing you always must set for a document type is the role. The **role** can be "**Viewer**" \(you can display that file type but you cannot edit it\), "**Editor**" \(you can display and edit that file type\), "**None**" \(it's not specified what you can do with that file\).
|
||||
* e.g.: You want your **app do be associated with certain file types**, identified either by extension, by MIME type, or by UTI identifier. **If you want your app to be associated with an UTI type, the app should either import or export the type**, as otherwise the type may not be known to the system and registering to unknown UTI type has simply no effect at all.
|
||||
|
||||
### Dynamic Testing
|
||||
|
||||
For **sending activities** you can:
|
||||
|
||||
* Hook the method we have seen in the static analysis \([`init(activityItems:applicationActivities:)`](https://developer.apple.com/documentation/uikit/uiactivityviewcontroller/1622019-init)\) to get the `activityItems` and `applicationActivities`.
|
||||
* Find out the excluded activities by hooking [`excludedActivityTypes` property](https://developer.apple.com/documentation/uikit/uiactivityviewcontroller/1622009-excludedactivitytypes).
|
||||
|
||||
For receiving items you can:
|
||||
|
||||
* _Share_ a file with the app from another app or send it via AirDrop or e-mail. Choose the file so that it will trigger the "Open with..." dialogue \(that is, there is no default app that will open the file, a PDF for example\).
|
||||
* Hook `application:openURL:options:` and any other methods that were identified in a previous static analysis.
|
||||
* Observe the app behavior.
|
||||
* In addition, you could send specific malformed files and/or use a fuzzing technique.
|
||||
|
||||
**Read how** [**here**](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#dynamic-analysis-8)**.**
|
||||
|
Loading…
Reference in a new issue