APT29는 어떤 방식으로 Windows 자격 증명 로밍 기능을 악용했을까?
2022년 초 맨디언트(Mandiant)는 APT29 공격 그룹이 유럽 지역의 외교 기관을 대상으로 한 피싱 공격에 성공한 것을 감지하고 대응한 바 있습니다. 이때 APT29는 피싱 성공 이후 Windows 자격 증명 로밍(Windows Credential Roaming) 기능을 악용해 침투를 시도했습니다. 참고로 Windows 자격 증명 로밍은 액티브 디렉토리 환경에서 사용자에게 투명하고 안전한 방식으로 자격 증명을 이용할 수 있는 기능입니다. Windows 자격 증명 로밍은 처음으로 컴퓨터에 로그인할 때 생성된 로컬 프로필을 이용해 이후 로그인을 할 때 번거롭게 자격 증명 과정을 거치지 않아도 되는 편의를 제공합니다.
맨디어트가 2022년 초 피싱 공격 배후로 APT29를 지목한 것은 이 공격 그룹이 러시아의 전략적 우선순위를 전제로 표적을 골라왔고, 유럽의 외교 기관은 그중 하나이기 때문입니다. 맨디언트는 2014년 이전부터 러시아의 해외정보총국(SVR: Foreign Intelligence Service)가 후원하는 것으로 보이는 공격 그룹인 APT29를 추적해왔습니다. 일부 APT29의 활동은 마이크로소프트가 노밸리움(Nobelium)이라는 이름으로 추적하고 있습니다.
맨디언트는 APT29가 피싱 성공 후 피해자 네트워크에 있는 액티브 디렉토리 시스템을 대상으로 다음 예와 같은 LDAP 쿼리들을 실행한 것을 관찰하였습니다.
|
쿼리는 일반적인 자격 증명 정보 수집(예: unixUserPassword)와 관련된 것으로 보입니다. 관찰에 따르면 두드러진 속성이 있었는데 바로 {b7ff5a38-0818-42b0-8110-d3d154c97f24} 또는 msPKI-CredentialRoamingTokens입니다. 이는 마이크로소프트의 설명에 따르면 이는 '로밍을 위한 암호화된 사용자 자격 증명 토큰 BLOB 저장소'입니다. 맨디언트는 추가 검사를 통해 이 속성이 자격 증명 로밍의 일부임을 확인했습니다.
자격 증명 로밍 심층 분석
자격 증명 로밍은 Windows Server 2003 SP1부터 지원한 기능으로 Windows 11, Windows Server 2022까지 포함되어 있습니다. 이 기능은 사용자가 인증서를 로밍 방식으로 이용할 수 있도록 하기 위해 만든 것입니다. 보안성을 보장하는 가운데 사용자와 관리자의 업무 편의를 높이는 기능이라 할 수 있습니다.
자격 증명 로밍의 예를 들어 보겠습니다. 회사에서 조직원에게 이메일 클라이언트(S/MIME: Secure/Multipurpose Internet Mial Extention) 인증서를 자동으로 제공하는 시나리오를 살펴보겠습니다. 앨리스라는 이름의 사용자가 장치 A에 로그인하면 자동 등록 절차가 시작됩니다. 그리고 앨리스의 자격 증명 정보가 인증서 템플릿에 자동으로 등록됩니다. 이후 앨리스가 장치 B에서 로그인을 할 때 새 인증서를 받을 필요가 없습니다. 자격 증명 로밍을 통해 이전에 장치 A에서 등록한 S/MIME 인증서가 장치 B에도 저장되어 있기 때문입니다. 따라서 앨리스는 하나의 인증서만 등록하면 됩니다. 덕분에 관리자의 인증서 관리 부담도 줄어듭니다.
자격 증명 로밍은 PKI 공급 업체 같은 외부 소스의 인증서를 비롯한 모든 종류의 인증서를 지원합니다. 단 TPM 같이 하드웨어 기반으로 인증서를 관리할 경우는 이용할 수 없습니다. 이외 더 많은 예외 상황에 대해서는 2012년 발행한 마이크로소프트의 자격 증명 로밍 관련 백서를 참조 바랍니다.
Windows Vista는 자격 증명 로깅 기능을 확장하여 Windows 자격 증명 관리자에 저장된 사용자 이름과 암호도 컴퓨터 간 로밍을 가능하게 하였습니다. 이 기능은 보안 이유로 Windows 7부터 제외된 것으로 보입니다.
자격 증명 로밍 관련 보안은 이전에 Michael Grafnitter가 작성한 블로그에 관련 언급이 있었습니다. 그 내용에는 Active Directory에서 로밍 된 자격 증명을 추출하는 데 DSInternals 툴킷을 사용하는 방법과 Mimikatz 도구를 사용하는 것에 대한 설명이 포함됩니다.
자격 증명 로밍은 사용자의 액티브 디렉토리 계정을 데이터 저장소로 사용해 인증서와 자격 증명(로밍 토큰이라고 함)을 동기화합니다. 2021년 마이크로소프트가 발행한 백서에 따르면 자격 증명 로밍에 사용되는 LDAP 속성은 다음과 같습니다.
msPKI-CredentialRoamingTokens
msPKIRoamingTimeStamp
msPKIDPAPIMasterKeys
msPKIAccountCredentials
이러한 속성은 Private-Information 속성 집합을 형성합니다. 마지막 속성인 msPKIAccountCredentials는 로밍 토큰이 저장되는 위치입니다. msPKIRoamingTimeStamp 속성에는 msPKIAccountCredentials와 msPKIDPAPIMasterKeys의 최근 업데이트 시간이 포함되어 있습니다. 참고로 msPKIDPAPIMasterKeys에는 사용자의 DPAPI 마스터 키가 포함됩니다.
자격 증명 로밍은 그림 2와 같이 예약된 작업으로 처리됩니다(\Microsoft\Windows\CertificateServicesClient\UserTask-Roam). 이 예약된 작업은 DLL에 해당하는 CLSID가 있는 COM 객체를 시작합니다(자격 증명 로밍 서비스는 이전에 DIMS라 불렀음). 문자열 "KEYROMING "이 인수로 전달됩니다.
dimsjob.dll 엔트리 포인트 평가를 통해 맨디언트는 dimsjob.dll 이 다른 DLL을 로드하는 것을 관찰하였습니다. 참고로 검사한 DLL은 Windows Server 2008 R2에서 가져온 것입니다. 최신 버전의 Windows는 다양한 COM 객체를 사용해 자격 증명 로밍을 처리합니다.
dimsjob.dll 평가 후 맨디언트는 msPKIAccountCredentialsLDAP 속성에 있는 항목의 이진 구조를 식별했습니다.
이진 구조는 로밍 토큰 유형을 나타내는 것으로 시작합니다. 맨디언트는 다음 유형을 식별하였습니다.
- %0: DPAPI Master Key
- %1: CAPI Private Key (RSA)
- %2: CAPI Private Key (DSA)
- %3: CAPI Certificate
- %4: CAPI Certificate Request
- %5: Username/Password (Enterprise Credential Data)
- %6: (unknown – presumably unused)
- %7: CNG Certificate
- %8: CNG Certificate Request
- %9: CNG Private Key
그런 다음 로밍 토큰의 식별자를 찾았습니다. 이것은 디스크에 있는 해당 파일의 이름입니다. 구조는 로밍 토큰의 마지막 업데이트 스탬프, 일부 NULL 바이트 및 로밍 토큰 데이터의 SHA1 해시로 되어 있으며 로밍 토큰 데이터 크기와 로우(raw) 데이터를 포함합니다.
dimsroam.dll 시작 시 현재 사용자의 msPKIAccountCredentials의 LDAP 속성에서 이러한 구조를 검색합니다. 로밍 토큰에 해당하는 로컬 파일이 있는지 확인한 다음 파일을 찾으면 dimsroam.dll은 마지막으로 파일을 쓴 시간과 SHA1을 비교합니다. 그러고 나서 필요시 파일을 업데이트합니다. 로컬 파일을 찾을 수 없는 경우 다음 그림과 같이 로밍 토큰 유형에 따라 바이너리 데이터의 올바른 저장 위치를 식별합니다.
로밍 토큰의 최정 저장 위치를 결정하기 위해 다음 그림과 같이 식별자(바이트 0x03 ~ 0x0F)가 폴더 경로 문자열에 추가됩니다.
그런 다음 이 파일 경로는 kernel32!CreateFileWAPI 호출로 직접 전달되며(그림 7) 로밍 토큰 데이터가 기록됩니다.
CVE-2022-30170: 임의 파일 쓰기와 원격 코드 실행으로 전환됨
앞서 언급한 동작은 임의 파일 쓰기 취약점입니다. 파일 경로가 제대로 삭제되지 않았으며 디렉토리 탐색("..\") 문자가 포함될 수 있습니다. 공격자가 msPKIAccountCredentialsLDAP 속성을 제어할 수 있는 경우 식별자 문자열에 디렉토리 탐색 문자가 포함된 악의적인 로밍 토큰 항목을 추가할 수 있습니다. 이를 통해 피해자 계정으로 가장하여 파일시스템의 모든 파일에 임의의 바이트 수를 쓸 수 있습니다. 이때 유일한 제약 조건은 전체 파일 이름과 디렉토리 순회 문자가 92바이트 버퍼에 들어맞는다는 것입니다.
맨디언트는 개념 증명을 위해 다음과 같은 악성 로밍 토큰을 개발했습니다.
msPKIAccountCredentials 악성 로밍 토큰 항목을 피해자 계정의 LDAP 삽입하려면 다음 파워쉘 스크립트를 실행하면 됩니다.
|
msPKIRoamingTimeStamp
속성을 업데이트하려면 자격 증명 로밍 서비스는 피해자가 그때부터 로그인하는 모든 컴퓨터에서 동기화를 트리거 합니다. dimsroam.dll
은 msPKIAccountCredentials
LDAP 속성을 파싱하고 ‘%APPDATA%\Microsoft\SystemCertificates\My\Certificates\..\..\..\Windows\Start Menu\Programs\Startup\malicious.bat
‘ (또는 간소화하여 ‘%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\malicious.bat
‘)를 생성합니다. 여기에는 ‘@echo off [newline] start calc.exe
’ 컨텐츠가 포함됩니다. 이 BAT 파일은 다음에 사용자가 시스템에 로그인할 때 실행됩니다. 이를 통해 공격자는 원격 코드 실행이라는 목표에 한 발짝 다가서게 됩니다.
이 취약점은 2022년 4월 MSRC에 보고되었으며 '권한 상승' 취약점으로 분류되었습니다. 마이크로소프트는 이 문제 해결을 위해 2022년 9월 13일에 CVE-2022-3017 취약점에 대한 문서(KB5017365, KB5017367)를 게시했습니다. 참고로 맨디언트는 이 취약점을 MNDT-2022-0038로 게시하였습니다.
공격자의 관점
조직에서 자격 증명 로밍을 사용한다면 공격자 또는 레드팀이 권한 상승을 위해 저장된 자격 증명을 남용할 수 있습니다. 공격자가 자격 증명 로밍을 남용할 수 있는 상황은 다음과 같이 정리할 수 있습니다.
- 조직에서 자격 증명 로밍이 사용되는 각 시스템에 2022년 9월에 올라온 패치를 적용하지 않은 상황
영향을 받는 시스템은 CVE-2022-30170에 취약합니다. 공격자는 이 취약점을 악용하여 자신이 제어할 수 있는 모든 사용자의 컨텍스트에 영향을 받는 시스템에 임의의 파일을 작성하여 측면 이동을 허용할 수 있습니다. 이 기술을 사용하여 공격자는 피해자가 접근할 수 있는 모든 시스템으로 침투할 수 있습니다. 공격자는 계정 자체에 대한 접근 권한을 갖거나 피해자 계정에 대한 충분한 권한이 있는 다른 액티브 디렉토리 계정을 통해 사용자 계정에 대한 쓰기 접근 권한을 필요로 합니다. - 공격자가 자격 증명 로밍을 사용 중이거나 적절한 정리 없이 과거에 사용했던 도메인 관리자 권한을 얻은 경우
이 시나리오에서 공격자는 DPAPI 도메인 백업 키를 검색하고 자격 증명 로밍을 위해 액티브 디렉토리 특성에 저장된 모든 자격 증명의 암호를 해독할 수 있습니다. 앞서 언급한 Michael Grafnitter는 액티브 디렉토리에서 로밍 된 개인 키 추출에 대한 내용을 다루는 블로그 포스팅에서 액티브 디렉토리에서 자격 증명을 추출하는 방법과 Mimikatz 도구를 사용해 DPAPI 도메인 백업 키로 암호를 푸는 방법을 설명합니다.
조직에서 현재 자격 증명 로밍을 사용하지 않지만 과거에 자격 증명 로밍을 사용한 경우도 자격 증명이 액티브 디렉토리에 계속 남아 있을 수 있습니다. 2012년 공개된 마이크로소프트의 백서에는 시스템 관리자가 인증서 로밍을 해제해는 방법을 안내합니다. 액티브 디렉토리에서 로밍 자격 증명은 수작업으로 지울 수 있습니다. 이렇게 정리를 하지 못했다면 액티브 디렉토리 환경에 중요한 자격 증명 정보가 저장되어 있을 수 있습니다.
또한, 조직에서 Windows Vista를 사용할 경우 인증서와 개인 키 외에 사용자 이름과 암호도 액티브 디렉토리에 저장되어 있을 수 있습니다. 이런 잠재적 보안 문제 해결을 위해 마이크로소프트는 Windows 7부터 사용자 이름과 암호를 저장하는 기능을 제거한 것으로 보입니다. - 공격자가 자격 증명 로밍을 사용 중이거나 과거에 사용되었던 사용자의 일반 텍스트 암호에 접근할 수 있는 경우
2번째 시나리오와 같이 공격자는 피해자 계정으로 접근해 액티브 디렉토리에서 자격 증명 특성을 검색할 수 있습니다. 공격자는 사용자의 일반 텍스트 암호를 사용하여 DPAPI 마스터 키를 해독하고 로밍 속성에 저장된 자격 증명을 얻을 수 있습니다. - 공격자가 피해자 계정의
msPKIDPAPIMasterKeys
속성에 읽기 권한을 가지고 있지만 일반 텍스트 암호가 없는 경우
속성을 읽음으로써 공격자는 사용자의 DPAPI 마스터 키를 추출하고 인기 있는 John the Ripper 암호 크래킹 소프트웨어의 DPAPImk2john.pyPththon 스크립트를 사용해 사용자 암호 해시를 추출할 수 있습니다. 이 해시는 John the Ripper 또는 hashcat을 사용해 오프라인에서 크랙 할 수 있습니다.
권장 사항
맨디언트의 권장 사항은 현재 조직에서 자격 증명 로밍을 사용하고 있는지 확인하는 것입니다. 만약 사용하고 있다면 2022년 9월 패치를 적용해 CVE-2022-30170 취약점 문제를 해결하십시오. 또한, 지금은 아니지만 예전에 자격 증명 로밍을 사용했다면 마이크로소프트의 안내에 따라 정리를 하십시오.
참고로 본 포스팅에 소개한 연구는 자격 증명 로밍에 대한 이해와 함께 APT29가 어떻게 관련 취약점을 활용하는지에 대한 통찰력을 제공합니다. 맨디언트는 IR 컨설턴트가 관찰한 ( msPKI-CredentialRoamingTokens {b7ff5a38-0818-42b0-8110-d3d154c97f24}) 속성이 어떻게 자격 증명 로밍 환경에서 악용되는지에 대한 상세 내용을 앞으로 확인해 나아갈 계획입니다.
참고 문헌
- Certs On Wheels: Understanding Credential Roaming – Microsoft
- Extracting Roamed Private Keys from Active Directory – Michael Grafnetter
- Windows: Credential Roaming (Whitepaper) – Microsoft
- CVE-2022-30170: Windows Credential Roaming Service Elevation of Privilege Vulnerability – Microsoft
- MNDT-2022-0038: Windows Credential Roaming Service Elevation of Privilege Vulnerability
부록
- 2022년 4월 20일 - Microsoft에 문제 제출
- 2022년 4월 26일 - 케이스 열림
- 2022년 5월 18일 - Microsoft에서 문제 확인
- 2022년 6월 1일 - Microsoft는 문제를 '심층 방어' 취약점으로 분류
- 2022년 6월 7일 - MSRC에 범위 및 영향 재설명
- 2022년 6월 9일 - MSRC에서 문제의 심각성을 재평가
- 2022년 6월 17일 - MSRC에서 CVE-2022-30170 할당
- 2022년 9월 13일 - 패치 릴리스