GitBook: [master] one page modified

This commit is contained in:
CPol 2021-05-17 16:11:05 +00:00 committed by gitbook-bot
parent 47ac5534af
commit 17cd871714
No known key found for this signature in database
GPG Key ID: 07D2180C7B12D0FF

View File

@ -643,6 +643,193 @@ In the open source bitcoin wallet app, [Bither](https://github.com/bither/bither
This is PIN is stored in the file `net.bither.plist` inside the **pin\_code** **key**. This is PIN is stored in the file `net.bither.plist` inside the **pin\_code** **key**.
If you clear this key from that plist in the backup and restores the backup, you will be able to access the wallet. If you clear this key from that plist in the backup and restores the backup, you will be able to access the wallet.
## 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.
The [**Local Authentication framework**](https://developer.apple.com/documentation/localauthentication) ****provides a set of APIs for developers to extend an authentication dialog to a user. In the context of connecting to a remote service, it is possible \(and recommended\) to leverage the [keychain](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html) for implementing local authentication.
The **fingerprint ID** sensor is operated by the [SecureEnclave security coprocessor](https://www.blackhat.com/docs/us-16/materials/us-16-Mandt-Demystifying-The-Secure-Enclave-Processor.pdf) and does not expose fingerprint data to any other parts of the system. Next to Touch ID, Apple introduced _Face ID_: which allows authentication based on facial recognition.
Developers have two options for incorporating Touch ID/Face ID authentication:
* `LocalAuthentication.framework` is a high-level API that can be used to **authenticate the user via Touch ID**. The app can't access any data associated with the enrolled fingerprint and is notified only whether authentication was successful.
* `Security.framework` is a lower level API to access [keychain services](https://developer.apple.com/documentation/security/keychain_services). This is a secure option if your app needs to **protect some secret data with biometric authentication**, since the access control is managed on a system-level and can not easily be bypassed. `Security.framework` has a C API, but there are several [open source wrappers available](https://www.raywenderlich.com/147308/secure-ios-user-data-keychain-touch-id), making access to the keychain as simple as to NSUserDefaults.
{% hint style="danger" %}
Please be aware that using either the `LocalAuthentication.framework` or the `Security.framework`, will be a control that can be bypassed by an attacker as it does only return a boolean and no data to proceed with. See [Don't touch me that way, by David Lindner et al](https://www.youtube.com/watch?v=XhXIHVGCFFM) for more details.
{% endhint %}
### Local Authentication Framework
Developers can display an **authentication prompt** by utilizing the function `evaluatePolicy` of the `LAContext` class. Two available policies define acceptable forms of authentication:
* `deviceOwnerAuthentication`\(Swift\) or `LAPolicyDeviceOwnerAuthentication`\(Objective-C\): When available, the user is prompted to perform Touch ID authentication. If Touch ID is not activated, the device passcode is requested instead. If the device passcode is not enabled, policy evaluation fails.
* `deviceOwnerAuthenticationWithBiometrics` \(Swift\) or `LAPolicyDeviceOwnerAuthenticationWithBiometrics`\(Objective-C\): Authentication is restricted to biometrics where the user is prompted for Touch ID.
The **`evaluatePolicy` function returns a boolean** value indicating whether the user has authenticated successfully. Which means that it can be easily bypassed \(see below\)
### Local Authentication using Keychain
The **iOS keychain APIs can \(and should\) be used to implement local authentication**. During this process, the app stores either a secret authentication token or another piece of secret data identifying the user in the keychain. In order to authenticate to a remote service, the user must unlock the keychain using their passphrase or fingerprint to obtain the secret data.
The keychain allows saving items with the special `SecAccessControl` attribute, which will allow access to the item from the keychain only after the user has passed Touch ID authentication \(or passcode, if such a fallback is allowed by attribute parameters\).
In the following example we will save the string "test\_strong\_password" to the keychain. The string can be accessed only on the current device while the passcode is set \(`kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly` parameter\) and after Touch ID authentication for the currently enrolled fingers only \(`SecAccessControlCreateFlags.biometryCurrentSet` parameter\):
{% tabs %}
{% tab title="Swift" %}
```swift
// 1. create AccessControl object that will represent authentication settings
var error: Unmanaged<CFError>?
guard let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
SecAccessControlCreateFlags.biometryCurrentSet,
&error) else {
// failed to create AccessControl object
return
}
// 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute
var query: [String: Any] = [:]
query[kSecClass as String] = kSecClassGenericPassword
query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
query[kSecAttrAccount as String] = "OWASP Account" as CFString
query[kSecValueData as String] = "test_strong_password".data(using: .utf8)! as CFData
query[kSecAttrAccessControl as String] = accessControl
// 3. save item
let status = SecItemAdd(query as CFDictionary, nil)
if status == noErr {
// successfully saved
} else {
// error while saving
}
```
{% endtab %}
{% tab title="Objective-C" %}
```objectivec
// 1. create AccessControl object that will represent authentication settings
CFErrorRef *err = nil;
SecAccessControlRef sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
kSecAccessControlUserPresence,
err);
// 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute
NSDictionary* query = @{
(_ _bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrLabel: @"com.me.myapp.password",
(__bridge id)kSecAttrAccount: @"OWASP Account",
(__bridge id)kSecValueData: [@"test_strong_password" dataUsingEncoding:NSUTF8StringEncoding],
(__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacRef
};
// 3. save item
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, nil);
if (status == noErr) {
// successfully saved
} else {
// error while saving
}
```
{% endtab %}
{% endtabs %}
Now we can request the saved item from the keychain. Keychain services will present the authentication dialog to the user and return data or nil depending on whether a suitable fingerprint was provided or not.
{% tabs %}
{% tab title="Swift" %}
```swift
// 1. define query
var query = [String: Any]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecReturnData as String] = kCFBooleanTrue
query[kSecAttrAccount as String] = "My Name" as CFString
query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
query[kSecUseOperationPrompt as String] = "Please, pass authorisation to enter this area" as CFString
// 2. get item
var queryResult: AnyObject?
let status = withUnsafeMutablePointer(to: &queryResult) {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
}
if status == noErr {
let password = String(data: queryResult as! Data, encoding: .utf8)!
// successfully received password
} else {
// authorization not passed
}
```
{% endtab %}
{% tab title="Objective-C" %}
```objectivec
// 1. define query
NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecReturnData: @YES,
(__bridge id)kSecAttrAccount: @"My Name1",
(__bridge id)kSecAttrLabel: @"com.me.myapp.password",
(__bridge id)kSecUseOperationPrompt: @"Please, pass authorisation to enter this area" };
// 2. get item
CFTypeRef queryResult = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &queryResult);
if (status == noErr){
NSData* resultData = ( __bridge_transfer NSData* )queryResult;
NSString* password = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
NSLog(@"%@", password);
} else {
NSLog(@"Something went wrong");
}
```
{% endtab %}
{% endtabs %}
### Detection
Usage of frameworks in an app can also be detected by analyzing the app binary's list of shared dynamic libraries. This can be done by using `otool`:
```bash
$ otool -L <AppName>.app/<AppName>
```
If `LocalAuthentication.framework` is used in an app, the output will contain both of the following lines \(remember that `LocalAuthentication.framework` uses `Security.framework` under the hood\):
```bash
/System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication
/System/Library/Frameworks/Security.framework/Security
```
If `Security.framework` is used, only the second one will be shown.
### Local Authentication Framework Bypass
[Objection Biometrics Bypass](https://github.com/sensepost/objection/wiki/Understanding-the-iOS-Biometrics-Bypass) can be used to bypass LocalAuthentication. Objection **uses Frida to instrument the `evaluatePolicy` function so that it returns `True`** even if authentication was not successfully performed. Use the `ios ui biometrics_bypass` command to bypass the insecure biometric authentication. Objection will register a job, which will replace the `evaluatePolicy` result. It will work in both, Swift and Objective-C implementations.
```bash
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios ui biometrics_bypass
(agent) Registering job 3mhtws9x47q. Type: ios-biometrics-disable
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # (agent) [3mhtws9x47q] Localized Reason for auth requirement: Please authenticate yourself
(agent) [3mhtws9x47q] OS authentication response: false
(agent) [3mhtws9x47q] Marking OS response as True instead
(agent) [3mhtws9x47q] Biometrics bypass hook complete
```
If vulnerable, the module will automatically bypass the login form.
### Custom URI Handlers / Deeplinks / Custom Schemes ### Custom URI Handlers / Deeplinks / Custom Schemes
A custom URI handler is used to invoke an application from an URI. A custom URI handler is used to invoke an application from an URI.