macOS Launch/Environment Constraints & Trust Cache
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
macOS의 실행 제약은 프로세스가 어떻게, 누구에 의해, 어디서 시작될 수 있는지를 규제하여 보안을 강화하기 위해 도입되었습니다. macOS Ventura에서 시작된 이들은 각 시스템 바이너리를 별개의 제약 카테고리로 분류하는 프레임워크를 제공합니다. 이 카테고리는 신뢰 캐시 내에 정의되어 있으며, 시스템 바이너리와 해당 해시 목록을 포함합니다. 이러한 제약은 시스템 내의 모든 실행 가능한 바이너리에 적용되며, 특정 바이너리를 실행하기 위한 요구 사항을 설명하는 규칙 세트를 포함합니다. 규칙은 바이너리가 충족해야 하는 자기 제약, 부모 프로세스가 충족해야 하는 부모 제약, 그리고 관련된 다른 엔티티가 준수해야 하는 책임 제약을 포함합니다.
이 메커니즘은 환경 제약을 통해 서드파티 앱으로 확장되며, macOS Sonoma부터 개발자가 환경 제약을 위한 키와 값의 세트를 지정하여 앱을 보호할 수 있도록 합니다.
실행 환경 및 라이브러리 제약은 launchd
속성 목록 파일에 저장하거나 코드 서명에 사용하는 별도의 속성 목록 파일에 정의합니다.
제약의 종류는 4가지입니다:
자기 제약: 실행 중인 바이너리에 적용되는 제약.
부모 프로세스: 프로세스의 부모에 적용되는 제약 (예: **launchd
**가 XP 서비스를 실행하는 경우)
책임 제약: XPC 통신에서 서비스를 호출하는 프로세스에 적용되는 제약
라이브러리 로드 제약: 로드할 수 있는 코드를 선택적으로 설명하기 위해 라이브러리 로드 제약을 사용합니다.
따라서 프로세스가 다른 프로세스를 실행하려고 할 때 — execve(_:_:_:)
또는 posix_spawn(_:_:_:_:_:_:)
를 호출하여 — 운영 체제는 실행 파일이 자기 제약을 충족하는지 확인합니다. 또한 부모 프로세스의 실행 파일이 부모 제약을 충족하는지 확인하고, 책임 프로세스의 실행 파일이 책임 프로세스 제약을 충족하는지 확인합니다. 이러한 실행 제약 중 하나라도 충족되지 않으면 운영 체제는 프로그램을 실행하지 않습니다.
라이브러리를 로드할 때 라이브러리 제약의 일부가 참이 아닐 경우, 프로세스는 라이브러리를 로드하지 않습니다.
LC는 사실과 논리 연산(and, or..)으로 구성되어 사실을 결합합니다.
LC가 사용할 수 있는 사실은 문서화되어 있습니다. 예를 들어:
is-init-proc: 실행 파일이 운영 체제의 초기화 프로세스(launchd
)여야 하는지를 나타내는 부울 값.
is-sip-protected: 실행 파일이 시스템 무결성 보호(SIP)로 보호된 파일이어야 하는지를 나타내는 부울 값.
on-authorized-authapfs-volume:
운영 체제가 인증된 APFS 볼륨에서 실행 파일을 로드했는지를 나타내는 부울 값.
on-authorized-authapfs-volume
: 운영 체제가 인증된 APFS 볼륨에서 실행 파일을 로드했는지를 나타내는 부울 값.
Cryptexes 볼륨
on-system-volume:
운영 체제가 현재 부팅된 시스템 볼륨에서 실행 파일을 로드했는지를 나타내는 부울 값.
/System 내부...
...
Apple 바이너리가 서명되면 신뢰 캐시 내의 LC 카테고리에 할당됩니다.
iOS 16 LC 카테고리는 여기에서 역설계되어 문서화되었습니다.
현재 **LC 카테고리 (macOS 14 - Sonoma)**는 역설계되었으며 그 설명은 여기에서 찾을 수 있습니다.
예를 들어 카테고리 1은:
(on-authorized-authapfs-volume || on-system-volume)
: 시스템 또는 Cryptexes 볼륨에 있어야 합니다.
launch-type == 1
: 시스템 서비스여야 합니다 (LaunchDaemons의 plist).
validation-category == 1
: 운영 체제 실행 파일입니다.
is-init-proc
: Launchd
여기에 대한 더 많은 정보는 여기에서 확인할 수 있지만, 기본적으로 **AMFI (AppleMobileFileIntegrity)**에 정의되어 있으므로 KEXT를 얻기 위해 Kernel Development Kit을 다운로드해야 합니다. **kConstraintCategory
**로 시작하는 기호들이 흥미로운 것들입니다. 이들을 추출하면 DER (ASN.1) 인코딩 스트림을 얻을 수 있으며, 이를 ASN.1 Decoder 또는 python-asn1 라이브러리와 그 dump.py
스크립트를 사용하여 디코드해야 합니다. andrivet/python-asn1로 더 이해하기 쉬운 문자열을 얻을 수 있습니다.
이것은 서드파티 애플리케이션에서 설정된 Launch Constraints입니다. 개발자는 애플리케이션에서 자신에게 접근을 제한하기 위해 사용할 사실과 논리 연산자를 선택할 수 있습니다.
애플리케이션의 환경 제약을 나열하는 것은 가능합니다:
macOS에는 몇 가지 신뢰 캐시가 있습니다:
/System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/BaseSystemTrustCache.img4
/System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/StaticTrustCache.img4
/System/Library/Security/OSLaunchPolicyData
iOS에서는 **/usr/standalone/firmware/FUD/StaticTrustCache.img4
**에 있는 것 같습니다.
Apple Silicon 장치에서 실행되는 macOS에서는 Apple 서명 이진 파일이 신뢰 캐시에 없으면 AMFI가 이를 로드하는 것을 거부합니다.
이전 신뢰 캐시 파일은 IMG4 및 IM4P 형식이며, IM4P는 IMG4 형식의 페이로드 섹션입니다.
데이터베이스의 페이로드를 추출하려면 pyimg4를 사용할 수 있습니다:
(또 다른 옵션은 도구 img4tool를 사용하는 것입니다. 이 도구는 M1에서도 실행되며, 릴리스가 오래되었더라도 x86_64에서 적절한 위치에 설치하면 실행됩니다).
이제 도구 trustcache를 사용하여 읽기 쉬운 형식으로 정보를 얻을 수 있습니다:
신뢰 캐시는 다음 구조를 따릅니다. 따라서 LC 카테고리는 4번째 열입니다.
그런 다음, 이 스크립트와 같은 스크립트를 사용하여 데이터를 추출할 수 있습니다.
그 데이터에서 launch constraints 값이 0
인 앱을 확인할 수 있으며, 이는 제약이 없는 앱입니다 (여기에서 확인 각 값이 무엇인지).
Launch Constraints는 프로세스가 예상치 못한 조건에서 실행되지 않도록 보장함으로써 여러 오래된 공격을 완화했을 것입니다: 예를 들어 예상치 못한 위치에서 실행되거나 예상치 못한 부모 프로세스에 의해 호출되는 경우(launchd만이 이를 실행해야 하는 경우).
게다가, Launch Constraints는 다운그레이드 공격도 완화합니다.
그러나, 이들은 일반적인 XPC 남용, Electron 코드 주입 또는 dylib 주입을 라이브러리 검증 없이 완화하지 않습니다(로드할 수 있는 팀 ID가 알려지지 않는 한).
소노마 릴리스에서 주목할 점은 데몬 XPC 서비스의 책임 구성입니다. XPC 서비스는 연결된 클라이언트가 책임지는 것이 아니라 스스로 책임을 집니다. 이는 피드백 보고서 FB13206884에 문서화되어 있습니다. 이 설정은 XPC 서비스와의 특정 상호작용을 허용하므로 결함이 있는 것처럼 보일 수 있습니다:
XPC 서비스 시작: 버그로 간주된다면, 이 설정은 공격자 코드로 XPC 서비스를 시작하는 것을 허용하지 않습니다.
활성 서비스에 연결: XPC 서비스가 이미 실행 중인 경우(원래 애플리케이션에 의해 활성화되었을 가능성이 있음), 연결하는 데 장애물이 없습니다.
XPC 서비스에 대한 제약을 구현하는 것은 잠재적 공격의 창을 좁힘으로써 유익할 수 있지만, 주요 문제를 해결하지는 않습니다. XPC 서비스의 보안을 보장하려면 연결 클라이언트를 효과적으로 검증하는 것이 근본적으로 필요합니다. 이는 서비스의 보안을 강화하는 유일한 방법입니다. 또한, 언급된 책임 구성은 현재 운영 중이며, 이는 의도된 설계와 일치하지 않을 수 있습니다.
애플리케이션이 LaunchService에 의해 열려야 한다는 요구가 있더라도(부모 제약에서). 이는 **open
**을 사용하거나(환경 변수를 설정할 수 있음) Launch Services API를 사용하여(환경 변수를 지정할 수 있음) 달성할 수 있습니다.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)