1P by GN⁺ | ★ favorite | 댓글 1개
  • Apple은 2024년 10월 28일 배포한 macOS Sequoia 15.1, Sonoma 14.7.1, Ventura 13.7.1에서 CVE-2024-54471을 패치했으며, 업데이트 전 환경에서는 NetAuthAgent를 통해 저장된 자격 증명이 노출될 수 있었음
  • 문제의 핵심은 NetAuthAgent의 MIG 서버가 메시지 발신자를 확인하지 않고 파일 서버 자격 증명 조회·생성·일부 덮어쓰기 루틴을 열어둔 점임
  • 공격자는 com.apple.netauth.user.gui Mach 서비스로 메시지를 보내 Keychain의 internet password 항목을 대신 조회하게 만들고, 사용자명과 비밀번호를 받을 수 있었음
  • 영향은 Finder의 “Connect to Server”로 저장한 FTP, Samba, WebDAV, 프린터 서버 자격 증명에 그치지 않고, 별도 체인을 통해 iCloud 계정 정보와 API 토큰 노출까지 이어질 수 있었음
  • 패치 후 NetAuthAgent는 Mach 메시지의 audit token으로 발신 프로세스의 entitlement를 검사하며, com.apple.private.netauth.useragent.allow=true가 없으면 응답하지 않음

CVE-2024-54471 패치 범위

  • CVE-2024-54471은 Apple 보안 업데이트에 포함돼 수정된 macOS 취약점임
  • 패치가 포함된 버전은 모두 2024년 10월 28일 릴리스됨
    • macOS Sequoia 15.1
    • macOS Sonoma 14.7.1
    • macOS Ventura 13.7.1
  • 해당 버전으로 업데이트하지 않은 macOS 기기는 즉시 업데이트가 필요함

macOS IPC와 Mach 기반 구조

  • macOS와 대부분의 Apple OS 커널은 XNU이며, BSD 계열 요소와 크게 수정된 Mach 커널 변형을 포함하는 하이브리드 커널임
  • Mach는 현대 macOS에서도 네 가지 추상화를 기반으로 함
    • task: 스레드가 실행되는 실행 환경이며 리소스 할당의 기본 단위
    • thread: CPU 사용의 기본 단위
    • port: 커널이 보호하는 메시지 큐에 해당하는 통신 채널
    • message: 스레드 간 통신에 쓰이는 타입 있는 데이터 객체 모음
  • Mach의 포트는 사용자 공간에 직접 노출되는 큐가 아니라, 각 task의 포트 이름 공간 안에 있는 port right 형태로 다뤄짐
  • 주요 권한은 두 가지임
    • send right: 여러 task가 같은 포트에 대해 가질 수 있음
    • receive right: 하나의 task만 가질 수 있음
  • 이 구조는 하나의 서버 task가 여러 클라이언트 task의 메시지를 받는 클라이언트-서버 모델을 만듦
  • macOS의 bootstrap server는 모든 task가 send right를 가진 포트를 받고, 클라이언트가 문자열 이름으로 등록된 Mach service의 send right를 요청할 수 있게 함

MIG 서버에서 생긴 인증 공백

  • MIG는 Mach 메시지 송수신을 함수형 인터페이스로 감싸는 도구임
  • MIG는 pseudo-C IDL과 컴파일러로 구성되며, IDL 파일에서 다음 파일을 생성함
    • 클라이언트용 C 소스
    • 서버용 C 소스
    • 양쪽에서 쓰는 C 헤더
  • 각 함수는 routine, 루틴 모음은 subsystem으로 불리며, subsystem 번호와 routine 인덱스가 메시지 ID에 반영됨
  • macOS의 사용자 공간 통신에서는 MIG가 대체로 XPC API에 밀렸지만, XPC 역시 Mach 메시지 위에 구축됨
  • MIG 서버 자체에는 강제 인증 메커니즘이 없으므로, 서버가 발신자를 검증하지 않으면 send right를 가진 임의의 task가 원격 루틴을 호출할 수 있음
  • MIG 서버 탐색에는 blacktop의 ipsw CLI가 유용하며, NDR_record 심볼을 import하는 바이너리를 찾는 방식이 사용됨
    • 이 방법은 MIG 서버뿐 아니라 MIG 클라이언트도 함께 찾을 수 있음
    • 서버와 클라이언트 코드는 디스어셈블러나 디컴파일러에서 비교적 쉽게 구분 가능함

NetAuthAgent가 다루는 자격 증명

  • NetAuthAgent는 macOS에서 FTP, Samba, WebDAV 같은 파일 서버 자격 증명을 처리하는 사용자 에이전트임
  • Finder의 “Go → Connect To Server”로 파일 서버에 접속할 때 나타나는 인증 대화상자는 NetAuthAgent 또는 관련 프로세스에서 제공됨
  • 사용자가 비밀번호 저장 체크박스를 선택하면 자격 증명은 macOS Keychain에 저장됨
  • NetAuthAgent가 비밀번호를 직접 저장하는 것은 아니며, Keychain을 중앙 비밀 저장소처럼 사용함
  • Keychain 항목은 자체 접근 제어 목록을 갖고 있어, 일반적으로 애플리케이션이 접근하면 안 되는 비밀에 접근하지 못하게 함
  • 다만 특정 프로세스가 다른 프로세스의 Keychain 조회를 대신 수행하는 메커니즘을 노출하면 전체 보안 모델이 약해질 수 있음

취약했던 NetAuthAgent MIG 서비스

  • NetAuthAgent는 bootstrap server에서 조회 가능한 MIG 서버를 노출했음
  • 서비스 이름은 com.apple.netauth.user.gui
  • 이 서버는 파일 서버 자격 증명을 읽고, 생성하고, 일부 경우 덮어쓰는 루틴을 제공했음
  • 패치 전에는 이 루틴들이 메시지 발신자를 검증하지 않았음
  • Routine 19, 메시지 ID 40219는 Keychain의 internet password 클래스 항목 조회를 프록시할 수 있었음
  • 이 루틴은 직렬화된 옵션 딕셔너리를 out-of-line 데이터 descriptor로 받고, 사용자명과 비밀번호를 out-of-line 데이터 descriptor 두 개로 반환했음

공격 흐름과 PoC 구성

  • PoC는 Swift로 작성된 보안 연구 도구 Kass를 사용해 Mach 메시지와 MIG 클라이언트를 다룸
  • NetAuthAgent 클라이언트는 다음 값으로 정의됨
    • 서비스 이름: com.apple.netauth.user.gui
    • subsystem 기준 routine ID: 40200
  • 조회 옵션은 Property List 형태로 직렬화되며, Scheme, Host, AlternatePort, Path 같은 필드를 포함할 수 있음
  • macOS Keychain API인 SecItemCopyMatching은 비밀값을 요청하지 않는 경우, 권한 없는 프로세스도 Keychain 항목의 메타데이터를 얻는 데 사용될 수 있음
  • 접근 제어 목록 역시 메타데이터로 접근 가능해, 항목의 trusted application 목록에 /System/Library/CoreServices/NetAuthAgent.app가 포함됐는지 확인할 수 있었음
  • 공격 코드는 NetAuthAgent가 접근 가능한 internet password 항목을 순회하며 다음 정보를 추출할 수 있었음
    • 표시 이름
    • 프로토콜
    • 호스트
    • 포트
    • 경로
    • 사용자명
    • 비밀번호

파일 서버 자격 증명 유출 영향

  • 패치 전에는 NetAuthAgent에 대한 send right를 얻은 악성 프로세스가 파일 서버 자격 증명 전체를 유출할 수 있었음
  • 기업 환경에서는 해당 자격 증명이 SSO 자격 증명일 수 있어, 공격자가 회사 시스템의 여러 리소스에 접근할 가능성이 생김
  • Finder의 Connect to Server 기능 사용 규모는 알 수 없지만, 여러 대학과 교육기관의 도움말 문서가 학생과 교직원에게 이 기능 사용을 안내했고 일부는 Keychain 저장 체크박스 선택을 권장했음
  • 프린트 서버 업체의 프린터 연결 안내도 발견됐으며, NetAuthAgent는 프린터 서버 자격 증명도 처리함
  • 최소 한 문서는 저장된 비밀번호 갱신 시 Keychain Access 앱이 일반 사용자에게 다루기 어렵다는 이유로 저장 체크박스를 선택하지 말라고 안내했음
  • 관리형 기기에서 같은 자격 증명이 superuser 자격 증명으로도 쓰인다면 권한 상승으로 이어질 가능성이 있지만, 관리형 기기 테스트가 없어 확인되지는 않았음
  • 개인 사용자가 NAS에 Finder로 접속하고 자격 증명을 저장한 경우에도 NAS 자격 증명이 공격자에게 노출될 수 있었음
  • 같은 자격 증명을 다른 인터넷 계정에 재사용했다면 해당 계정도 침해될 수 있음
  • FTP, Samba, WebDAV는 인터페이스가 잘 정의돼 있어, 자격 증명 유출 후 서버 파일 탐색과 반출을 자동화하기 쉬움

Keychain을 이용한 추가 악용

  • NetAuthAgent는 Keychain 항목을 생성하는 루틴도 노출했기 때문에, 악성 프로세스가 임의 데이터를 password 필드에 넣어 숨길 수 있었음
  • 이 방식은 디스크에 직접 쓰는 동작을 피할 수 있어 보안 소프트웨어를 우회하는 데이터 은닉 수단이 될 수 있음
  • Keychain의 의심스러운 항목을 명시적으로 검사하는 보안 소프트웨어에 대해서는 알려진 바가 없음
  • 악성 프로세스가 합법적인 자격 증명을 Keychain에 저장하는 것도 가능했음
  • 이 동작은 단독으로는 효과가 제한적일 수 있지만, 공격자가 통제하는 파일 서버 자격 증명을 저장한 뒤 사용자를 사회공학적으로 유도하는 복합 공격에 쓰일 가능성이 있음

iCloud API 토큰까지 이어지는 익스플로잇 체인

  • Connect to Server를 쓰지 않는 사용자도 이 취약점의 영향에서 자유롭지 않았음
  • macOS 기기 대부분에는 NetAuthAgent가 접근할 수 있을 만큼 넓은 ACL을 가진 Keychain 항목이 존재함
  • 이 Keychain 항목은 디스크의 특정 파일을 복호화하는 복호화 키를 포함함
  • 해당 파일에는 사용자의 iCloud 계정 정보와 API 토큰이 들어 있음
  • 공격자는 Keychain 항목과 알려진 위치의 파일을 이용해 다음 정보를 얻을 수 있었음
    • 이름과 성
    • 이메일 주소
    • 이메일 별칭
    • 활성화된 기능과 endpoint
    • 여러 장기 지속 API 토큰

iCloud 토큰으로 가능한 작업

  • Wojciech Reguła의 이전 연구는 같은 API 토큰을 다른 방법으로 찾아 다음 데이터를 유출할 수 있음을 보였음
    • Contacts
    • Calendars
    • Reminders
    • Find My를 통한 사용자 위치
  • 해당 결과 중 Reminders를 제외한 항목이 재현됐음
  • 새 계정과 마이그레이션된 계정의 Reminders는 Apple이 더 안전한 CloudKit으로 옮겨 암호화된 형태로만 접근 가능해졌음
  • 추가로 가능한 작업은 다음과 같았음
    • 연락처 사진 유출
    • CloudKit 조회, 단 복호화는 불가
    • iCloud key-value store 데이터 유출
    • iCloud 백업 메타데이터 유출, 기기 일련번호 포함
    • Find My로 사용자의 다른 기기 위치 유출
    • Find My로 사용자의 친구 위치 유출
    • Find My를 통한 잠금, 삭제, 사운드 재생 작업 수행
  • CloudKit 데이터 복호화는 조사했지만 완료하지 못했음
  • 상업용 포렌식 업체가 이 API 토큰과 필요 시 iOS 기기 PIN을 함께 사용해 CloudKit 데이터나 iCloud 백업에서 CloudKit 데이터를 복호화할 가능성은 배제되지 않았음

Apple의 수정 방식

  • 패치 후 NetAuthAgent는 메시지를 받으면 먼저 발신자의 entitlement를 확인함
  • entitlement는 코드 서명 시 바이너리에 붙는 key-value 쌍임
  • 표준 보안 설정의 macOS에서는 Apple Mobile File Integrity가 프로세스 실행 시 restricted entitlement를 검사하고, 적절한 provisioning profile이 없으면 프로세스를 종료함
  • provisioning profile은 Apple이 서명해야 하므로 이 검사를 우회하기 어렵게 설계돼 있음
  • NetAuthAgent가 요구하는 entitlement는 다음과 같음
    • 키: com.apple.private.netauth.useragent.allow
    • 값: boolean true
  • 이 entitlement가 없는 발신자에게 NetAuthAgent는 응답하지 않음
  • Mach 메시지의 수신 시 커널이 붙이는 trailer에는 audit token이 포함됨
  • 수신 task는 audit token으로 발신 task를 식별하고, 커널에 해당 task의 entitlement 딕셔너리를 요청한 뒤 값을 검사할 수 있음

보안 구조의 약한 연결고리

  • 파일 서버 자격 증명은 특정 애플리케이션만 접근할 수 있게 저장됐더라도, 그 애플리케이션이 다른 애플리케이션의 조회 명령을 받아들이면 해당 애플리케이션이 약한 연결고리가 됨
  • iCloud API 토큰이 디스크의 암호화된 파일에 저장돼 있더라도, 복호화 키가 넓은 ACL을 가진 Keychain 항목에 있으면 그 ACL이 약한 연결고리가 됨
  • macOS는 프로세스 주입을 어렵게 만드는 보안 장치를 갖추고 있으며, 전반적인 보안 인프라는 강한 편으로 평가됨
  • 그러나 이 취약점처럼 단순한 발신자 검증 누락 하나가 파일 서버 자격 증명과 iCloud API 토큰 노출로 이어질 수 있음

사용자 권장 조치

  • 아직 가능하다면 Advanced Data Protection을 활성화하는 것이 권장됨
  • iCloud를 웹브라우저로 사용하지 않는다면 iCloud 데이터 웹 접근 비활성화도 선택지임
  • iCloud 웹사이트는 Apple의 iCloud 앱과 다른 API endpoint를 쓰는 경우가 있음
  • 이 취약점으로는 더 이상 토큰에 접근할 수 없지만, 이전 취약점으로 노출된 적이 있고 이후 다른 취약점으로 노출될 가능성도 있음
  • 이 익스플로잇이 악성 행위자에게 사용됐거나 발견됐다는 증거는 없음
  • 그래도 자격 증명 악용이 특히 우려된다면 비밀번호를 변경해야 함
  • 2024년 10월 이후 macOS를 업데이트하지 않은 기기는 즉시 업데이트해야 함

댓글과 토론

Hacker News 의견들
  • 글이 잘 쓰였고, Apple이 어느 정도 덮으려 했던 빈 비밀번호를 두 번 시도하면 root 로그인이 우회되던 제로데이가 떠오름. 2017년쯤, 어쩌면 2018년이었음
    root 로그인 상자 어디서든 관리자 사용자명을 넣고 비밀번호를 비운 채 로그인하면, 첫 번째는 비밀번호가 틀렸다고 나오지만 경고를 닫고 두 번째로 누르면 그 사용자로 로그인됐음
    당일에 100% 재현됐고 소셜 미디어에 퍼진 뒤 곧 패치됐지만, 그래도 엄청난 oversight처럼 보였음. Mac 인증 메커니즘 주변에 아직 오래된 찌꺼기가 남아 있는 듯하고, Mach 커널의 port 시스템이 언급된 것도 흥미로움

    • 빈 비밀번호 두 번이라는 표현을 보니, 고양이가 키보드에 앉아서 Sun 3/60을 해킹했던 때가 떠오름
      사용자명 버퍼가 임의 문자 256자에 도달하자 XDM이 크래시 나고 root 셸을 띄웠음. 다만 이건 보안에 대해 모두가 훨씬 순진했던 90년대 초 이야기임
    • 2017년으로 보이고, 당시 제출 글은 “macOS High Sierra: Anyone can login as “root” with empty password”였음 - 3001점 | 1073댓글 - https://news.ycombinator.com/item?id=15800676
    • 그 정도는 아무것도 아님. 예전에는 여러 해 동안 page file에서 어떤 사용자의 FileVault 비밀번호grep 한 줄로 뽑을 수 있었고, 100% 동작했음
    • Mach에 대해 안다면 그 핵심 시스템을 모를 수 있다는 게 오히려 놀라움. 내게는 port 시스템이야말로 Mach를 설명하는 대표적 사실임
    • 비밀번호 없는 로그인 관련해서 CVE-2011-3226도 제보했었고, 여기에서 참조됨: https://support.apple.com/en-us/103345
  • “ACLs don't”: https://waterken.sourceforge.net/aclsdont/current.pdf

  • 글에 작은 수정이 들어감: entitlement 검사는 커널의 Mach 계층에 있지 않음
    https://github.com/nmggithub/wts/commit/2bdce1c0c76c7adc360e17a6a42ee547462b99d3
    XNU 동작을 설명하던 부분의 사실 오류를 고친 한 단어짜리 변경임

  • “프로세스가 다른 프로세스가 keychain 질의를 사실상 프록시하도록 하는 메커니즘을 노출하면 전체 시스템 보안을 약화할 수 있다”는 부분은 혼동된 대리인 문제처럼 보임: https://en.wikipedia.org/wiki/Confused_deputy_problem
    capability 기반 설계라면 이런 종류의 문제를 체계적으로 막을 수 있어야 함

    • Entitlements도 capability의 한 종류로 볼 수 있을 듯함. 그렇다면 맞는 말이고, 실제 해결책도 데몬 자체와 대화하려면 entitlement가 필요하도록 만드는 것이었음
  • 작성자가 실제 PoC 코드를 어디 제공했는지 궁금함. 완화책 테스트를 좀 해보고 싶은데 예제 코드는 보이지만 불완전해 보임
    현실적인 위험은 어느 정도인가?

    • PoC 코드는 동작해야 함. 의존성으로 Kass를 설치하기만 하면 됨. 그렇게 했는데도 다른 문제가 있다면 어떤 문제인지 궁금함
      위험 측면에서는 NetAuthAgent에 대한 send right를 얻을 수 있는 앱, 사실상 거의 모든 비샌드박스 앱이 FTP, WebDAV, Samba 같은 파일 드라이브의 저장된 자격 증명을 NetAuthAgent에 조용히 요청할 수 있음. 여기에 iCloud 연락처와 캘린더 전체 유출, 그 외 iCloud 관련 데이터 유출로도 이어질 수 있음
      샌드박싱은 이를 어렵게 만들지만 불가능하게 하지는 않음. 최신 상태라면 위험은 0이고, 패치는 작년 10월에 들어갔으니 솔직히 이미 업데이트되어 있어야 함. 업데이트하지 않았고 앞으로도 안 할 생각이라면, 기기에서 실행되는 모든 프로세스를 빠짐없이 확인하지 않는 한 위험은 훨씬 큼
  • 아주 자세한 글이고, 여러 커널의 역사까지 다뤄서 좋았음. 다만 심각한 보안 이슈에 대한 글이라면 초반에 영향 범위, 공격 조건, 논리 오류인지 메모리 손상인지 같은 아주 짧은 설명이 있으면 좋겠음
    나머지를 읽을지 판단할 수 있을 만큼만 간단히 있으면 충분함

    • 피드백 고마움. 독자가 더 읽도록 일부러 핵심을 조금 늦게 꺼냈지만, 그런 관점도 충분히 이해됨
  • 정말 흥미로운 글임. Mach와 Darwin 커널이 만들어지는 과정에 이렇게 많은 뒷이야기가 있는 줄 몰랐음

  • 지금쯤이면 Mach가 macOS 버그의 안정적인 공급원처럼 느껴짐. Apple이 열심히 잠그고 있다는 건 알지만, Mach에서 완전히 벗어나는 경로가 있나?

    • 여기서 버그의 원인은 Mach라기보다 entitlement 검사 부재라고 봄. Entitlements는 솔직히 매우 좋은 보안 시스템이지만 opt-in임
      데몬이 entitlement를 확인하지 않으면 안전하지 않음. 메시징 메커니즘을 탓하기보다 그 사용 방식을 탓해야 함
      사실 어떤 잠긴 메시징 시스템이든 단순 메시지 전달 이상, 예를 들면 송신자 검증 같은 것이 필요함. Mach 같은 저수준 통신 프로토콜에서 그냥 얻을 수 있는 것은 아님. Apple이 MIG 컴파일러를 개편해 entitlement 검사를 추가하지 않는 한 그렇다
      Mach는 entitlement 검사와 함께 쓰면 훌륭함
    • 최근에 Mach 밖으로 점점 더 많은 부분을 옮기는 글이 있었음. 일부는 L4로, 일부는 사용자 공간으로 이동하는 방향임
      기술적으로는 서로 다른 구성 요소가 더 많이 함께 존재하게 되어 잠재 공격 표면이 늘어날 수도 있음. 하지만 더 특화된 표면은 제어를 단순화하고, 결과적으로 그 표면을 더 잘 보호하게 만들 수 있음