고스트메일 작전: 러시아 APT, 짐브라 웹메일을 악용해 우크라이나 정부 기관 공격
목차
- 개요
- 목표
- 피싱 이메일
- 감염 분석
- 1단계: 자바스크립트 로더
- 2단계: 브라우저 스틸러
- 인프라 및 귀속
- CVE 평가
- 맺음말
- Seqrite 커버리지
- IOC
- MITER ATT & CK
개요
Seqrite Labs는 크로스 사이트 스크립팅(XSS) 취약점을 악용하는 표적 피싱 캠페인을 발견했습니다. 짐브라 콜라보레이션 (ZCS)를 이용해 우크라이나 정부 기관을 해킹하려는 시도입니다. 해당 피싱 이메일에는 악성 첨부 파일, 의심스러운 링크, 매크로가 없습니다. 전체 공격 과정은 단일 이메일의 HTML 본문 내에 포함되어 있으며, 악성 첨부 파일은 없습니다.
사회공학적 기법을 이용한 인턴십 문의 메일은 이메일 본문에 직접 삽입된 난독화된 자바스크립트 페이로드를 전달합니다. 피해자가 취약한 Zimbra 웹메일 세션에서 이메일을 열면 해당 페이로드가 악용됩니다. CVE-2025-66376 이는 HTML 콘텐츠 내 CSS @import 지시문의 부적절한 검증으로 인해 발생하는 저장형 XSS 버그입니다. 해당 스크립트는 브라우저에서 조용히 실행되어 자격 증명, 세션 토큰, 백업 2FA 코드, 브라우저에 저장된 암호, 그리고 피해자의 메일함 내용(최대 90일치)을 수집하며, 모든 데이터는 DNS와 HTTPS를 통해 유출됩니다.
짐브라 공격과의 기술적 유사성 및 지정학적 목표 설정의 일치성을 바탕으로, 본 캠페인이 이전에 기록된 공격 기법과 일치한다고 중간 정도의 확신을 가지고 평가합니다. 러시아 국가 지원 우크라이나 정부 기관을 표적으로 삼는 침입 시도가 발견되었습니다. 이는 CERT-UA에 보고되었습니다.
목표
- 국가: 우크라이나
- 부문: 정부
이메일 수신자는 우크라이나 국가수문청 소속으로, 선박의 항해, 해양 및 수로 지원을 담당하는 국가 중요 기반 시설 분야에서 활동하고 있습니다. 이 기관은 우크라이나 인프라부 산하(구체적으로는 우크라이나 해양 및 하천 운송 국가청 소속)에 있습니다. 이번 공격은 현재 진행 중인 지역 분쟁 상황 속에서 우크라이나 공공 부문 기관을 대상으로 하는 광범위한 사이버 공격의 일환입니다.
피싱 이메일
피싱 이메일은 22일에 수신되었습니다.nd 2026년 1월, 우크라이나 국립내과학원(NAVS) 학생이 우크라이나 정부 수문국에 보낸 이메일입니다. (발신자 IP 주소가 헤더에 표시된 것으로 보아 학생의 이메일 주소는 해킹당했을 가능성이 높습니다.) 우크라이나어로 작성된 이 이메일은 일반적인 인턴십 문의처럼 보이며, 발신자는 자신을 4학년 학생이라고 소개하고 수신자가 인턴십 기회나 관련 담당자를 알고 있는지 묻습니다. 또한, 이메일이 잘못된 수신함에 도착했을 경우를 대비해 사과하는 내용도 포함되어 있는데, 이는 신뢰를 구축하기 위한 전형적인 전략입니다.

주요 관찰 사항:
- NAVS와 관련된 인프라에서 전송됨
- 언뜻 보기에 합법적으로 보인다
- 악성 첨부 파일이나 의심스러운 외부 링크가 없습니다.
- HTML 본문에 직접 삽입된 악성 코드
- 해당 바이러스는 2월 26일 우크라이나에서 처음 발견되어 업로드되었으며, VirusTotal에서는 아무런 탐지 결과도 나오지 않았습니다.

이 이메일은 자동화된 도구를 사용한 것이 아니라, 공격자가 크롬 132(2026년 1월 14일 안정 버전)의 Zimbra 웹 인터페이스를 통해 수동으로 작성한 것입니다.
- 8.15_GA_4717 – 발신자의 Zimbra 서버 버전
- 10.1.7_GA_4200002 – ZimbraWebClient 프런트엔드 UI 빌드 번호

이메일에는 악성 자바스크립트가 숨겨져 있습니다. 블록입니다. HTML 본문 내에 있는 큰 base64로 인코딩된 스크립트입니다. `@import` 태그 이름 우회는 정규 표현식 기반 검사에서는 잘못된 HTML처럼 보이지만 브라우저 파싱에서는 유효한 상태로 유지되도록 설계되었습니다.

이 샘플의 익스플로잇은 Zimbra Collaboration Suite의 저장형 XSS 취약점인 CVE-2025-66376에 해당하며, 이 취약점은 ZCS 10.0.18 / 10.1.13(2025년 11월) 버전에서 패치되었습니다. CVE 설명에는 "HTML 콘텐츠에 대한 불충분한 검증, 특히 @import 지시문 및 기타 스크립트 삽입 벡터를 포함하는 조작된 태그 구조 및 속성 값과 관련된 취약점"이라고 명시되어 있습니다. 이 취약점은 사용자가 클래식 UI에서 조작된 이메일 메시지를 볼 때 발생합니다.
우회 방법은 태그 이름과 속성 키/값 문자열 내부에서 `@import` 토큰을 제거하는 방식을 사용합니다. 이메일에는 동일한 원리를 이용한 보조 미끼도 포함되어 있습니다. and tags with @import noise injected into the tag name itself, and an HTML comment inserted mid-tag-name. This tag-name bypass causes AntiSamy to reconstruct from fragmented tokens, and executes the outer Base64 decoded code and the self-executing function runs.
감염 분석
피해자는 짐브라 웹메일에서 피싱 이메일을 수신합니다. 실행을 위해서는 피해자가 인증된 세션이 활성화된 상태에서 브라우저 기반 짐브라 인터페이스에서 해당 이메일을 열어야 합니다. 자바스크립트는 해당 세션 컨텍스트 내에서 실행되며, 쿠키, localStorage 및 동일 출처 SOAP API 권한을 상속받습니다.

1단계: 자바스크립트 로더
로더는 자체 실행 함수로 래핑되어 있으며, ID가 "인 스크립트인지 확인하여 다중 주입을 방지하는 것으로 시작합니다.zmb_pl_v3_"가 이미 실행 중인지 여부. 다음으로 중요한 부분은 base64 페이로드를 디코딩하는 것입니다." 아토브() 그런 다음 키 "를 사용하여 XOR 연산을 수행합니다.트위치바5e"최종 JavaScript 페이로드를 로드합니다. 이 코드는 세션 컨텍스트, 쿠키 접근 권한 및 웹메일 iframe 샌드박스 탈출 기능을 포함하고 있으므로 최상위 문서에 삽입됩니다.

2단계: 브라우저 스틸러
최종 페이로드는 브라우저 메모리에서 실행되는 스틸러입니다. 이 스틸러는 로그인 자격 증명, SOAP 세션 토큰, 메일 내용 및 첨부 파일, 쿠키 등을 캡처합니다. 실행될 때마다 세션 토큰을 생성하는데, 이 토큰은 모든 C2 요청에서 고유한 피해자 식별자로 사용되는 12자리의 임의 영숫자 문자열입니다. 하드코딩된 C2 도메인은 다음과 같습니다. 짐브라소프트[.]com[.]ua페이로드의 어느 부분에서든 예외가 발생하면 스테이지 이름, 오류 메시지 및 스택 트레이스를 포함한 POST 요청이 /v/p로 전송됩니다. C2 운영자는 모든 피해자 시스템에서 어떤 단계가 실패했는지, 그리고 그 원인이 무엇인지 정확하게 확인할 수 있습니다. 모든 작업에는 try/catch 블록이 적용되어 오류를 격리하므로 하나의 작업 실패가 다른 작업에 영향을 미치지 않습니다.

다음으로, 인증된 SOAP 요청을 피해자 측 Zimbra 서버로 전송하는 Zimbra SOAP 래퍼가 있습니다./서비스/비누/X-Zimbra-Csrf-Token 헤더에는 탈취된 CSRF 토큰이 포함되어 있어 요청이 정상적인 웹메일 활동과 구별할 수 없게 됩니다. SOAP 호출은 오류를 발생시키는 대신 실패 시 null을 반환하도록 래핑되어 있어 하나의 SOAP 호출이 거부되더라도 다른 병렬 작업이 가능합니다.

DNS 데이터 유출 공격은 값을 RFC 4648 Base32로 인코딩하고 60자 단위로 나누어 다음과 같은 형식의 DNS 호스트 이름을 구성합니다.
- 디- . . .i[.]zimbrasoft[.]com[.]ua
다음으로, JSON 객체를 application/octet-stream 블롭으로 직렬화하여 X-Filename 헤더와 함께 /v/d로 POST 요청을 보냅니다. 이 헤더는 전체 서버 구성 덤프와 같은 더 큰 구조화된 객체에 사용됩니다. 비콘은 DNS와 함께 또는 DNS 대신 작은 구조화된 데이터를 전송하기 위한 간단한 POST 요청으로 /v/p로 전송됩니다. 또한 동일한 값을 DNS와 HTTPS를 통해 모두 전송할 수 있습니다. HTTPS가 차단된 경우에도 DNS를 통해 데이터가 전송되며, HTTPS는 차단되지 않은 경우 완전한 데이터를 전달합니다.

Zimbra Classic UI는 세션 CSRF 토큰을 평문으로 localStorage.getItem(“csrfToken”)에 저장합니다. 이 토큰이 없으면 모든 SOAP 호출이 거부됩니다. 이 작업은 모든 SOAP 작업이 시작되기 전에 동기적으로 먼저 실행됩니다.

9개의 병렬 작업이 모두 동시에 시작됩니다. 약속.모두C2 관점에서 볼 때, 탭이 10초 후에 닫히면 발생할 수 있는 모든 작업이 이미 완료된 것이므로 피해자 세션당 데이터 수집량이 극대화됩니다.
SendStartPing: 페이로드 실행이 시작되면 C2에 알립니다. 이를 통해 공격자는 피해자별 시작/종료 시간을 상호 연관시킬 수 있습니다.
이메일 수집이메일 수집을 위한 두 가지 방법 중 첫 번째 방법은 인라인으로 스크래핑하는 것입니다. tags for the 배치 정보 응답 페이지 로드 시 Zimbra에 JS 변수가 삽입됩니다. 그렇지 않을 경우 다른 값으로 대체됩니다. 신원 가져오기 요청 SOAP는 별칭을 포함한 모든 구성된 ID를 반환하며 DNS 및 HTTPS를 통해 데이터를 유출합니다.

환경을 모으다: 고객의 지문을 확인하고 전화를 겁니다. 정보 요청 서버 구성 응답 전체를 가져온 다음 전체 JSON을 다음과 같이 출력합니다. zimbra_batch_analytics.json. 이 객체에는 Zimbra 버전, 계정 할당량, 구성된 기능, 서버 호스트 이름 및 수십 가지 계정 기본 설정이 포함되어 있습니다.
- 클래식(?client=고급)
- HTML (/h/)
- 현대적(/modern/).
gather_2fa_codes: 사용합니다 스크래치 코드 요청하기 이 과정에서 계정의 백업 2FA 복구 코드가 반환됩니다. 이 코드는 비상시 접속을 위한 일회용 코드이며, 공격자는 이 코드를 이용해 피해자가 비밀번호를 변경하고 모든 세션을 취소하더라도 인증할 수 있습니다. 각 코드는 DNS를 통해 개별적으로 유출됩니다.

gather_app_password: 이것은 사용합니다 앱별 암호 요청 생성 새로운 영구 자격 증명을 생성하려면 짐브라웹앱별 암호는 암호 재설정 후에도 유지됩니다. 이는 공격자가 장기간 접근 권한을 확보하는 수단입니다. 일단 생성되면 IMAP 또는 API 인증을 통해 무기한 접근이 가능하며, DNS를 통해 정보를 유출할 수 있습니다.
기기 상태 수집: 장치 상태 가져오기 요청 (네임스페이스 urn:zimbraSync)는 ActiveSync에 연결된 모든 모바일 장치를 장치 ID, 유형, 동기화 상태 등의 세부 정보와 함께 반환합니다. 이는 대상 프로필을 구축하고 후속 모바일 공격에 활용될 수 있습니다.
gather_oauth_consumers: GetOAuthConsumersRequest 이 기능은 계정에 승인된 모든 타사 OAuth 앱 목록을 표시하는 데 사용됩니다. 이를 통해 대상이 사용하는 다른 플랫폼과 해당 플랫폼 중 어떤 플랫폼이 받은 편지함에 API 수준 액세스 권한을 가지고 있는지 알 수 있습니다.

gather_autocomplete_password이 공격은 DOM에 두 개의 숨겨진 폼 필드(autocomplete="username" 및 autocomplete="current-password")를 삽입하고 브라우저의 암호 관리자가 해당 필드를 자동 완성할 때까지 5초 동안 기다립니다. 그런 다음 나타난 데이터를 읽어 유출하고 삽입된 모든 요소를 제거합니다. 이 작업은 Zimbra가 아닌 브라우저를 대상으로 하므로 CSRF 토큰이 필요하지 않은 유일한 작업입니다.
메일 프로토콜 활성화다음 환경설정 수정 요청 피해자의 계정에 zimbraPrefImapEnabled: TRUE를 설정합니다. 이렇게 하면 IMAP 액세스가 자동으로 활성화되어 앱 암호를 사용하여 모든 IMAP 클라이언트에서 사서함을 지속적으로 감시할 수 있습니다.

이제 가장 큰 영향을 미치는 부분으로 넘어가겠습니다. sendArchives 90일 동안의 이메일 유출을 위한 스크립트입니다. 0일부터 89일까지 반복 실행되며, 매일 Zimbra의 내장 내보내기 엔드포인트 "/home/~/?fmt=tgz"에서 스팸이 아닌 이메일을 다운로드합니다. 다운로드한 .tgz 파일은 매일 직접 업로드됩니다. /v/d두 가지 업로드 모드가 사용됩니다.
- 최신 브라우저를 위한 스트리밍(ReadableStream을 직접 파이프하여 사용, 메모리 버퍼 불필요).
- 기존 시스템의 경우 500MB 용량 제한이 있는 버퍼링된 배열을 사용합니다.

이 기능은 로컬 스토리지 키(zd_comp_YYYY-MM-DD)를 체크포인트로 사용합니다. 탭이 다시 열리면 이미 유출된 날짜는 건너뛰게 됩니다. 타임아웃은 하루 24시간으로 설정되어 있어 탭이 열려 있는 동안 계속 스트리밍됩니다.
마지막으로, sendFinishPing 모든 작업이 완료되었음을 확인하기 위해 비콘을 사용합니다. C2 서버는 시작/종료 정보를 이용하여 피해자 세션이 얼마나 지속되었는지 측정하고 캡처된 내용을 추론할 수 있습니다.

인프라 및 귀속
C2 도메인은 2026년 1월 20일 12시 10분 33초(UTC)에 생성되었으며, 이는 피싱 이메일이 발송되기 직전이고 등록기관은 ua.drs입니다. 현재까지 생성된 도메인은 두 개가 확인되었습니다.
- js-l1wt597cimk[.]i[.]zimbrasoft[.]com[.]ua
- js-26tik3egye4[.]i[.]zimbrasoft[.]com[.]ua
러시아와 연관된 여러 APT 공격 그룹(Fancy Bear(APT28), Cozy Bear(APT29), Winter Vivern(TA473))이 이전에 동유럽 지역을 대상으로 Zimbra를 대규모로 악용한 바 있습니다. 문서화 된 Zimbra 취약점 공격은 취약한 메일 서버를 통해 이메일 자격 증명을 탈취하는 명령 주입 취약점을 이용합니다. 이는 이메일 상호 작용이 필요 없는 서버 측 공격으로, 피해자가 웹메일에서 열어야 하는 HTML 이메일 XSS 페이로드를 사용하는 피싱 이메일 공격과는 완전히 다른 유형입니다. TA473 정교한 도구를 사용하지 않고 Zimbra XSS 취약점을 이용한 간단한 JavaScript 자격 증명 탈취 공격만 사용했습니다. 구조화된 SOAP API 악용이나 이중 채널 데이터 유출은 없었습니다.
ESET의 운영 방식에서 언급했듯이 라운드프레스 2024년 연구에 따르면 APT28은 Roundcube에서 Zimbra, Horde, MDaemon으로 공격 대상을 확장하여 동유럽의 정부 기관과 방위 산업체를 표적으로 삼았습니다. 우리가 해독한 페이로드 구조는 SpyPress.ZIMBRA와 매우 유사하며, 이는 Zimbra API 엔드포인트에 SOAP 요청을 보내 피해자의 연락처 목록을 수집하고 이메일 소스를 가져와 데이터를 유출합니다. 이러한 유사점과 공격 대상을 바탕으로, 우리는 GhostMail 작전이 APT28의 소행이라고 중간 정도의 확신을 가지고 판단합니다.
맺음말
Operation GhostMail은 공격자가 기존의 악성코드 바이너리 대신 브라우저에 상주하는 스틸러에 전적으로 의존하는 웹메일 중심 침입 공격의 지속적인 진화를 보여줍니다. 공격자는 난독화된 자바스크립트를 HTML 이메일에 직접 삽입하고 Zimbra 웹메일의 XSS 취약점을 악용하여 파일 드롭, 매크로 사용 또는 엔드포인트 기반 탐지를 유발하지 않고도 세션을 완전히 가로챌 수 있었습니다. 자격 증명 수집 및 사서함 내보내기를 위해 합법적인 SOAP API 호출을 악용한 것은 플랫폼 기본 기능을 어떻게 은밀한 데이터 수집을 위한 무기로 사용할 수 있는지를 보여줍니다.
우크라이나 정부 기관을 표적으로 삼은 이번 공격은 해당 지역의 공공 부문 기관을 대상으로 한 지속적인 지정학적 사이버 활동과 맥락을 같이합니다. 최종적인 공격 주체를 밝히기 위해서는 추가적인 인프라 또는 코드 중복 확인이 필요하지만, 사용된 기법은 이전에 동유럽 전역의 웹메일 플랫폼을 악용한 러시아 국가 지원 그룹들의 공격 방식과 일치합니다. 웹메일 환경에서 엄격한 HTML 검증, 신속한 패치 관리, 그리고 비정상적인 SOAP 활동 모니터링의 중요성은 브라우저 기반 세션 침해 가능성을 시사합니다.
Seqrite 커버리지
스크립트.트로이.50486.GC
추천
- Zimbra 8.8.15에서 지원되는 릴리스(최소 10.1.x 버전) 또는 다른 플랫폼으로 즉시 마이그레이션하십시오.
- ZimbraWeb이라는 이름이 있거나 의심스러운 이메일이 발송된 날짜와 비슷한 날짜에 생성된 앱별 암호가 있는 모든 계정을 감사하십시오. 해당 암호는 즉시 취소하십시오.
- 특히 IMAP 액세스가 필요하지 않은 계정에서 예기치 않은 zimbraPrefImapEnabled: TRUE 변경 사항이 있는지 계정 설정을 감사하십시오.
- Zimbra 감사 로그에서 비정상적인 IP 주소 또는 정상 업무 시간 외의 경로에서 /home/~/?fmt=tgz에 접근한 내역을 확인하십시오.
- 애플리케이션 계층에서 SOAP API 모니터링을 배포하십시오. 특히 GetScratchCodesRequest 및 CreateAppSpecificPasswordRequest 호출은 일반적인 사용 환경에서 거의 발생하지 않으므로 기준선 설정이 용이합니다.
- IOC 도메인에 대한 DNS 필터링을 구현하고 DNS 유출 채널을 특징짓는 d-[a-z0-9]{12}.i.* 서브도메인 패턴에 대한 행동 경고를 고려하십시오.
- 사용자 계정에 대해 IMAP 및 POP3 액세스를 기본적으로 활성화해야 하는지 검토하십시오. 관리자 수준에서 사용하지 않는 프로토콜을 비활성화하면 자격 증명이 나중에 유출되더라도 지속성 확보 경로 하나를 제거할 수 있습니다.
- 웹메일 환경에서 HTML 이메일 본문에 실행 파일이 포함될 수 있음을 직원들에게 알리십시오. 첨부 파일이나 링크가 없다고 해서 안전한 것은 아닙니다.
IOC
이메일
c010f64080b0b0997b362a8e6b9c618e
C2
짐브라소프트[.]com[.]ua
js-[a-z0-9]{12}.i.zimbrasoft[.]com[.]ua
MITER ATT & CK
| 술책 | TID | 기술 | 순서 |
| 자원 개발 | T1583.001 | 인프라 획득: 도메인 | 공격 직전에 등록된 C2 도메인 |
| 자원 개발 | T1586.002 | 해킹 계정: 이메일 계정 | NAVS 이메일 주소에서 발송된 피싱 이메일 |
| 초기 액세스 | T1566.001 | 피싱: 스피어피싱 첨부 파일 | XSS 공격 페이로드가 포함된 HTML 이메일 |
| 실행 | T1059.007 | 명령 및 스크립팅 해석기: JavaScript | 브라우저에 상주하는 페이로드 |
| 실행 | T1203 | 클라이언트 실행을 위한 악용 | CVE-2025-66376 XSS 취약점 공격 |
| 고집 | T1098.001 | 계정 조작: 추가 클라우드 자격 증명 | CreateAppSpecificPasswordRequest는 새로운 영구 자격 증명을 생성합니다. |
| 방어 회피 | T1027 | 난독화된 파일 또는 정보 | XOR + Base64 계층형 인코딩, @import 토큰 |
| 방어 회피 | T1564.001 | 아티팩트 숨기기: 숨겨진 파일 및 디렉터리 | 탑재물은 육안 검사에서 보이지 않도록 숨겨져 있습니다. |
| 자격 증명 액세스 | T1528 | 애플리케이션 액세스 토큰 탈취 | GetOAuthConsumersRequest |
| 자격 증명 액세스 | T1539 | 웹 세션 쿠키 도용 | localStorage에서 가져온 CSRF 토큰 |
| 자격 증명 액세스 | T1111 | 다중 요소 인증 가로채기 | GetScratchCodesRequest를 통한 2FA 코드 도난 방지 백업 |
| 자격 증명 액세스 | T1555.003 | 암호 저장소의 자격 증명: 웹 브라우저의 자격 증명 | 자동 완성 DOM 주입 수확 |
| 발견 | T1082 | 시스템 정보 검색 | GetInfoRequest 서버 지문 |
| 발견 | T1087.003 | 계정 검색: 이메일 계정 | GetIdentitiesRequest 및 DOM 스크래핑 |
| 발견 | T1069 | 권한 그룹 검색 | GetOAuthConsumersRequest |
| 발견 | T1120 | 주변 장치 검색 | 장치 상태 가져오기 요청 |
| 수집 | T1114.002 | 이메일 수집: 원격 | 90일 스윕 |
| 수집 | T1185 | 브라우저 세션 하이재킹 | 창 상단 문서 iframe 탈출 |
| 수집 | T1213 | 정보 저장소의 데이터 | zimbra_batch_analytics.json 설정 덤프 |
| 여과 | T1041 | C2 채널을 통한 유출 | HTTPS POST /v/d 및 /v/p |
| 여과 | T1071.004 | 애플리케이션 계층 프로토콜: DNS | Base32로 인코딩된 DNS 데이터 유출 |
작성자
사트윅 람 프라키
카르틱 지바니



