GITBOOK-3939: change request with no subject merged in GitBook

This commit is contained in:
CPol 2023-05-22 19:31:06 +00:00 committed by gitbook-bot
parent 2ffd838832
commit 008b95b536
No known key found for this signature in database
GPG Key ID: 07D2180C7B12D0FF

View File

@ -769,6 +769,73 @@ The ones in **`LaunchDameons`** are run by root. So if an unprivileged process c
Applications can **subscribe** to different event **messages**, enabling them to be **initiated on-demand** when such events happen. The **setup** for these services is done in l**aunchd plist files**, located in the **same directories as the previous ones** and containing an extra **`LaunchEvent`** key.
### XPC Security
When a connection is stablished to an XPC service, the server will check if the connection is allowed. These are the checks it would usually perform:
1. Check if the connecting **process is signed with an Apple-signed** certificate (only given out by Apple).
* If this **isn't verified**, an attacker could can create a **fake certificate** to match any other check.
2. Check if the connecting process is signed with the **organizations certificate**, (team ID verification).
* If this **isn't verified**, **any developer certificate** from Apple can be used for signing, and connect to the service.
3. Check if the connecting process **contains a proper bundle ID**.
4. Check if the connecting process has a **proper software version number**.
* If this **isn't verified,** an old, insecure clients, vulnerable to process injection could be used to connect to the XPC service even with the other checks in place.
5. Check if the connecting process has an **entitlement** that allows it to connect to the service. This is applicable for Apple binaries.
6. The **verification** must be **based** on the connecting **clients audit token** **instead** of its process ID (**PID**) since the former prevents PID reuse attacks.
* Developers rarely use the audit token API call since its **private**, so Apple could **change** at any time. Additionally, private API usage is not allowed in Mac App Store apps.
The server will implement this **verification** in a function called **`shouldAcceptNewConnection`**.
{% code overflow="wrap" %}
```objectivec
- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
//Check connection
return YES;
}
```
{% endcode %}
The object NSXPCConnection has a **private** property **`auditToken`** (the one that should be used but could change) and a the **public** property **`processIdentifier`** (the one that shouldn't be used).
The connecting process could be verified with something like:
{% code overflow="wrap" %}
```objectivec
[...]
SecRequirementRef requirementRef = NULL;
NSString requirementString = @"anchor apple generic and identifier \"xyz.hacktricks.service\" and certificate leaf [subject.CN] = \"TEAMID\" and info [CFBundleShortVersionString] >= \"1.0\"";
/* Check:
- Signed by a cert signed by Apple
- Check the bundle ID
- Check the TEAMID of the signing cert
- Check the version used
*/
// Check the requirements
SecRequirementCreateWithString(requirementString, kSecCSDefaultFlags, &requirementRef);
SecCodeCheckValidity(code, kSecCSDefaultFlags, requirementRef);
```
{% endcode %}
If a developer doesn't want to ceck the version of the client, he could check that the client is not vulnerable to process injection at least:
{% code overflow="wrap" %}
```objectivec
[...]
CFDictionaryRef csInfo = NULL;
SecCodeCopySigningInformation(code, kSecCSDynamicInformation, &csInfo);
uint32_t csFlags = [((__bridge NSDictionary *)csInfo)[(__bridge NSString *)kSecCodeInfoStatus] intValue];
const uint32_t cs_hard = 0x100; // don't load invalid page.
const uint32_t cs_kill = 0x200; // Kill process if page is invalid
const uint32_t cs_restrict = 0x800; // Prevent debugging
const uint32_t cs_require_lv = 0x2000; // Library Validation
const uint32_t cs_runtime = 0x10000; // hardened runtime
if ((csFlags & (cs_hard | cs_require_lv)) {
return Yes; // Accept connection
}
```
{% endcode %}
### C Code Example
{% tabs %}