hacktricks/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/macos-xpc-connecting-process-check.md
2023-06-06 18:56:34 +00:00

7.1 KiB

Verificação de Conexão XPC do macOS

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Verificação de Conexão XPC

Quando uma conexão é estabelecida com um serviço XPC, o servidor verificará se a conexão é permitida. Estas são as verificações que normalmente são realizadas:

  1. Verificar se o processo de conexão é assinado com um certificado assinado pela Apple (apenas fornecido pela Apple).
    • Se isso não for verificado, um atacante pode criar um certificado falso para corresponder a qualquer outra verificação.
  2. Verificar se o processo de conexão é assinado com o certificado da organização (verificação do ID da equipe).
    • Se isso não for verificado, qualquer certificado de desenvolvedor da Apple pode ser usado para assinar e se conectar ao serviço.
  3. Verificar se o processo de conexão contém um ID de pacote apropriado.
  4. Verificar se o processo de conexão tem um número de versão de software apropriado.
    • Se isso não for verificado, clientes antigos e inseguros, vulneráveis à injeção de processo, podem ser usados para se conectar ao serviço XPC, mesmo com as outras verificações em vigor.
  5. Verificar se o processo de conexão tem uma autorização que permite se conectar ao serviço. Isso é aplicável para binários da Apple.
  6. A verificação deve ser baseada no token de auditoria do cliente de conexão em vez de seu ID de processo (PID), pois o primeiro impede ataques de reutilização de PID.
    • Os desenvolvedores raramente usam a chamada de API de token de auditoria, pois ela é privada, então a Apple pode alterá-la a qualquer momento. Além disso, o uso de API privada não é permitido em aplicativos da Mac App Store.

Para obter mais informações sobre a verificação de ataque de reutilização de PID:

{% content-ref url="macos-pid-reuse.md" %} macos-pid-reuse.md {% endcontent-ref %}

Exemplos de Código

O servidor implementará essa verificação em uma função chamada shouldAcceptNewConnection.

- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
    //Check connection
    return YES;
}

{% endcode %}

O objeto NSXPCConnection tem uma propriedade privada chamada auditToken (a que deve ser usada, mas pode mudar) e uma propriedade pública chamada processIdentifier (a que não deve ser usada).

O processo de conexão pode ser verificado com algo como:

{% code overflow="wrap" %}

[...]
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);

Se um desenvolvedor não quiser verificar a versão do cliente, ele poderia verificar se o cliente não é vulnerável à injeção de processo pelo menos:

{% code overflow="wrap" %}

[...]
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 %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥