macOS xpc_connection_get_audit_token Attack

HackTricks 지원하기

자세한 정보는 원본 게시물을 확인하세요: https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/. 요약은 다음과 같습니다:

Mach 메시지 기본 정보

Mach 메시지가 무엇인지 모른다면 이 페이지를 확인하세요:

macOS IPC - Inter Process Communication

현재 기억해야 할 것은 (여기서 정의): Mach 메시지는 _mach 포트_를 통해 전송되며, 이는 mach 커널에 내장된 단일 수신자, 다중 송신자 통신 채널입니다. 여러 프로세스가 메시지를 mach 포트로 보낼 수 있지만, 어떤 시점에서도 단일 프로세스만 읽을 수 있습니다. 파일 설명자 및 소켓과 마찬가지로 mach 포트는 커널에 의해 할당되고 관리되며, 프로세스는 커널에 사용하고자 하는 mach 포트를 나타내기 위해 정수만 볼 수 있습니다.

XPC 연결

XPC 연결이 어떻게 설정되는지 모른다면 확인하세요:

macOS XPC

취약점 요약

당신이 알아야 할 흥미로운 점은 XPC의 추상화가 일대일 연결이라는 것이지만, 이는 다수의 송신자를 가질 수 있는 기술 위에 기반하고 있습니다. 따라서:

  • Mach 포트는 단일 수신자, 다중 송신자입니다.

  • XPC 연결의 감사 토큰은 가장 최근에 수신된 메시지에서 복사된 감사 토큰입니다.

  • XPC 연결의 감사 토큰을 얻는 것은 많은 보안 검사에 중요합니다.

이전 상황이 유망하게 들리지만, 이것이 문제를 일으키지 않을 몇 가지 시나리오가 있습니다 (여기서):

  • 감사 토큰은 종종 연결을 수락할지 결정하기 위한 권한 확인에 사용됩니다. 이는 서비스 포트에 메시지를 사용하여 발생하므로, 아직 연결이 설정되지 않았습니다. 이 포트에 대한 추가 메시지는 단순히 추가 연결 요청으로 처리됩니다. 따라서 연결을 수락하기 전에 검사가 취약하지 않습니다 (이는 -listener:shouldAcceptNewConnection: 내에서 감사 토큰이 안전하다는 것을 의미합니다). 따라서 우리는 특정 작업을 확인하는 XPC 연결을 찾고 있습니다.

  • XPC 이벤트 핸들러는 동기적으로 처리됩니다. 이는 하나의 메시지에 대한 이벤트 핸들러가 다음 메시지에 대해 호출되기 전에 완료되어야 함을 의미하며, 동시 디스패치 큐에서도 마찬가지입니다. 따라서 XPC 이벤트 핸들러 내에서 감사 토큰은 다른 일반(비응답!) 메시지에 의해 덮어씌워질 수 없습니다.

이것이 악용될 수 있는 두 가지 방법이 있습니다:

  1. 변형 1:

  • 악용 서비스 A서비스 B연결합니다.

  • 서비스 B는 사용자가 할 수 없는 특권 기능을 서비스 A에서 호출할 수 있습니다.

  • 서비스 Axpc_connection_get_audit_token을 호출하는데, 이때 _이벤트 핸들러_ 내에 있지 않습니다 **dispatch_async**에서.

  • 따라서 다른 메시지가 감사 토큰을 덮어쓸 수 있습니다. 왜냐하면 이벤트 핸들러 외부에서 비동기적으로 디스패치되고 있기 때문입니다.

  • 악용은 서비스 B에 서비스 A에 대한 SEND 권한을 전달합니다.

  • 따라서 svc B는 실제로 서비스 A메시지를 보내고 있습니다.

  • 악용특권 작업을 호출하려고 시도합니다. RC svc A는 이 작업의 권한을 확인하는 동안 svc B가 감사 토큰을 덮어썼습니다 (악용이 특권 작업을 호출할 수 있는 접근 권한을 부여합니다).

  1. 변형 2:

  • 서비스 B는 사용자가 할 수 없는 특권 기능을 서비스 A에서 호출할 수 있습니다.

  • 악용은 서비스 A와 연결되며, 응답을 기대하는 메시지를 악용에 전송합니다 특정 응답 포트에서.

  • 악용은 서비스 B그 응답 포트를 전달하는 메시지를 보냅니다.

  • 서비스 B가 응답할 때, 서비스 A에 메시지를 보내고, 악용은 서비스 A에 다른 메시지를 보내면서 특권 기능에 도달하려고 시도하고, 서비스 B의 응답이 감사 토큰을 완벽한 순간에 덮어쓸 것이라고 기대합니다 (경쟁 조건).

변형 1: 이벤트 핸들러 외부에서 xpc_connection_get_audit_token 호출하기

시나리오:

  • 우리가 모두 연결할 수 있는 두 개의 mach 서비스 AB (샌드박스 프로필 및 연결 수락 전 권한 확인에 따라).

  • _A_는 **B**가 전달할 수 있는 특정 작업에 대한 권한 확인을 가져야 합니다 (하지만 우리의 앱은 할 수 없습니다).

  • 예를 들어, B가 일부 권한을 가지고 있거나 root로 실행되고 있다면, A에게 특권 작업을 수행하도록 요청할 수 있습니다.

  • 이 권한 확인을 위해, **A**는 비동기적으로 감사 토큰을 얻습니다. 예를 들어, **dispatch_async**에서 xpc_connection_get_audit_token을 호출하여.

이 경우 공격자는 경쟁 조건을 유발하여 악용A에게 작업을 수행하도록 요청하는 동안 B가 A에 메시지를 보내도록 할 수 있습니다. RC가 성공적일 경우, B의 감사 토큰이 메모리에 복사되며, 악용의 요청이 A에 의해 처리되는 동안 특권 작업에 대한 접근 권한을 부여합니다.

이것은 **A**가 smd이고 **B**가 diagnosticd인 경우 발생했습니다. SMJobBless 함수는 새로운 특권 헬퍼 도구를 설치하는 데 사용될 수 있습니다 ( root로). 만약 root로 실행되는 프로세스가 smd에 연락하면, 다른 검사는 수행되지 않습니다.

따라서 서비스 B는 **diagnosticd**입니다. 이는 root로 실행되며 프로세스를 모니터링하는 데 사용될 수 있습니다. 모니터링이 시작되면, 초당 여러 메시지를 보냅니다.

공격을 수행하기 위해:

  1. 표준 XPC 프로토콜을 사용하여 smd라는 서비스에 연결을 시작합니다.

  2. diagnosticd에 대한 두 번째 연결을 형성합니다. 일반적인 절차와는 달리, 두 개의 새로운 mach 포트를 생성하고 보내는 대신, 클라이언트 포트의 송신 권한이 smd 연결과 관련된 송신 권한의 복사본으로 대체됩니다.

  3. 그 결과, XPC 메시지는 diagnosticd에 디스패치될 수 있지만, diagnosticd의 응답은 smd로 리다이렉트됩니다. smd에게는 사용자와 diagnosticd의 메시지가 동일한 연결에서 발생하는 것처럼 보입니다.

  1. 다음 단계는 diagnosticd에게 선택한 프로세스(사용자의 프로세스일 가능성 있음)를 모니터링하도록 지시하는 것입니다. 동시에, smd에 대한 1004 메시지의 홍수를 보냅니다. 여기서 의도는 특권이 있는 도구를 설치하는 것입니다.

  2. 이 작업은 handle_bless 함수 내에서 경쟁 조건을 유발합니다. 타이밍이 중요합니다: xpc_connection_get_pid 함수 호출은 사용자의 프로세스의 PID를 반환해야 합니다 (특권 도구가 사용자의 앱 번들에 있기 때문입니다). 그러나 xpc_connection_get_audit_token 함수는 **diagnosticd**의 감사 토큰을 참조해야 합니다.

변형 2: 응답 전달

XPC(프로세스 간 통신) 환경에서 이벤트 핸들러는 동시 실행되지 않지만, 응답 메시지 처리에는 고유한 동작이 있습니다. 구체적으로, 응답을 기대하는 메시지를 보내는 두 가지 방법이 있습니다:

  1. xpc_connection_send_message_with_reply: 여기서 XPC 메시지는 지정된 큐에서 수신되고 처리됩니다.

  2. xpc_connection_send_message_with_reply_sync: 반대로, 이 방법에서는 XPC 메시지가 현재 디스패치 큐에서 수신되고 처리됩니다.

이 구분은 응답 패킷이 XPC 이벤트 핸들러의 실행과 동시에 구문 분석될 가능성을 허용하기 때문에 중요합니다. 특히, _xpc_connection_set_creds는 감사 토큰의 부분 덮어쓰기를 방지하기 위해 잠금을 구현하지만, 전체 연결 객체에 대한 보호는 확장하지 않습니다. 따라서 패킷 구문 분석과 이벤트 핸들러 실행 사이의 간격 동안 감사 토큰이 교체될 수 있는 취약점이 발생합니다.

이 취약점을 악용하기 위해서는 다음과 같은 설정이 필요합니다:

  • A 및 **B**라는 두 개의 mach 서비스, 모두 연결을 설정할 수 있습니다.

  • 서비스 **A**는 특정 작업에 대한 권한 확인을 포함해야 하며, 이는 오직 **B**만 수행할 수 있습니다 (사용자의 애플리케이션은 수행할 수 없습니다).

  • 서비스 **A**는 응답을 기대하는 메시지를 보내야 합니다.

  • 사용자는 **B**에 응답할 메시지를 보낼 수 있습니다.

악용 프로세스는 다음 단계를 포함합니다:

  1. 서비스 **A**가 응답을 기대하는 메시지를 보낼 때까지 기다립니다.

  2. **A**에 직접 응답하는 대신, 응답 포트를 탈취하여 서비스 **B**에 메시지를 보냅니다.

  3. 이후, 금지된 작업과 관련된 메시지를 디스패치하며, 이 메시지가 **B**의 응답과 동시에 처리될 것으로 기대합니다.

아래는 설명된 공격 시나리오의 시각적 표현입니다:

![https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/variant2.png](../../../../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png)

발견 문제

  • 인스턴스 찾기 어려움: xpc_connection_get_audit_token 사용 사례를 정적 및 동적으로 검색하는 것이 어려웠습니다.

  • 방법론: Frida를 사용하여 xpc_connection_get_audit_token 함수를 후킹하고, 이벤트 핸들러에서 발생하지 않는 호출을 필터링했습니다. 그러나 이 방법은 후킹된 프로세스에 한정되었고, 활성 사용이 필요했습니다.

  • 분석 도구: IDA/Ghidra와 같은 도구를 사용하여 접근 가능한 mach 서비스를 검사했지만, 이 과정은 시간이 많이 소요되었고 dyld 공유 캐시와 관련된 호출로 인해 복잡해졌습니다.

  • 스크립팅 제한: dispatch_async 블록에서 xpc_connection_get_audit_token 호출을 분석하기 위한 스크립팅 시도가 블록 구문 분석 및 dyld 공유 캐시와의 상호작용의 복잡성으로 인해 방해받았습니다.

수정 사항

  • 보고된 문제: smd 내에서 발견된 일반 및 특정 문제를 Apple에 보고했습니다.

  • Apple의 응답: Apple은 smd에서 xpc_connection_get_audit_tokenxpc_dictionary_get_audit_token으로 대체하여 문제를 해결했습니다.

  • 수정의 성격: xpc_dictionary_get_audit_token 함수는 수신된 XPC 메시지와 연결된 mach 메시지에서 직접 감사 토큰을 검색하므로 안전한 것으로 간주됩니다. 그러나 이는 xpc_connection_get_audit_token과 유사하게 공개 API의 일부가 아닙니다.

  • 더 넓은 수정의 부재: Apple이 연결의 저장된 감사 토큰과 일치하지 않는 메시지를 폐기하는 것과 같은 보다 포괄적인 수정을 구현하지 않은 이유는 불분명합니다. 특정 시나리오(예: setuid 사용)에서 합법적인 감사 토큰 변경 가능성이 요인이 될 수 있습니다.

  • 현재 상태: 이 문제는 iOS 17 및 macOS 14에서 여전히 존재하며, 이를 식별하고 이해하려는 사람들에게 도전 과제가 되고 있습니다.

HackTricks 지원하기

Last updated