로봇이냐, 아니냐: 러시아 정부 후원을 받는 COLDRIVER 소행으로 추정되는 새로운 악성코드
Google Threat Intelligence Group
Google Threat Intelligence
Visibility and context on the threats that matter most.
Contact Us & Get a Demo소개
NGO, 정책 고문, 반체제 인사의 고위 인사를 표적으로 삼는 것으로 알려진 러시아 정부 후원 위협 그룹인 COLDRIVER는 2025년 5월 공개 발표 이후 5일 만에 새로운 악성코드 제품군을 운용하며 신속하게 작전을 전환했습니다. COLDRIVER가 이 악성코드를 얼마나 오랫동안 개발했는지는 불분명하지만, GTIG는 발표 이후 LOSTKEYS의 단일 사례도 관찰하지 못했습니다. 대신 GTIG는 Google이 COLDRIVER(UNC4057, Star Blizzard, Callisto라고도 함) 소행으로 추정한 이전의 다른 어떤 악성코드 캠페인보다 더 공격적으로 사용되는 새로운 악성코드를 확인했습니다.
GTIG가 COLDRIVER의 소행으로 직접 추정한 이 새로운 악성코드는 발견 이후 여러 차례 반복되었으며, 이는 COLDRIVER의 개발 및 작전 속도가 급격히 빨라졌음을 나타냅니다. 이것은 전달 체인을 통해 연결된 관련 악성코드 제품군의 모음입니다. GTIG는 최근 Zscaler 블로그 게시물에서 공개된 이 감염 체인의 일부에 대한 세부 정보를 기반으로 감염 체인 및 관련 악성코드에 대한 더 넓은 세부 정보를 공유하고자 합니다.
악성코드 개발 개요
이러한 재정비는 맞춤형 CAPTCHA인 척하는 업데이트된 COLDCOPY "ClickFix" 유인책을 통해 전달되는 NOROBOT이라는 새로운 악성 DLL로 시작되었습니다. 이는 COLDRIVER의 이전 LOSTKEYS 배포와 유사하지만, 이전의 다단계 PowerShell 방법 대신 rundll32를 통해 사용자가 악성 DLL을 실행하도록 유도하여 감염을 업데이트합니다.


그림 1: 악성코드 개발 개요
NOROBOT의 초기 버전은 YESROBOT으로 추적되는 번거로운 Python 백도어를 배포했지만, COLDRIVER는 MAYBEROBOT으로 추적하는 더 유연하고 확장 가능한 Powershell 백도어를 위해 YESROBOT을 빠르게 포기했습니다.
NOROBOT과 그 이전의 감염 체인은 지속적으로 발전해 왔습니다. 처음에는 배포 성공률을 높이기 위해 단순화되었다가, 암호화 키를 분할하여 복잡성을 다시 도입했습니다. 더 복잡한 전달 체인으로의 전환은 캠페인 추적의 어려움을 증가시킵니다. 이러한 지속적인 개발은 고가치 표적에 대한 지속적인 정보 수집을 위해 전달 메커니즘에 대한 탐지 시스템을 회피하려는 그룹의 노력을 강조합니다.
"ClickFix" 및 Rundll32를 통한 전달
이 새로운 악성코드 감염 체인은 이전에 LOSTKEYS를 전달하는 것으로 관찰된 COLDCOPY "ClickFix" 유인책(c4d0fba5aaafa40aef6836ed1414ae3eadc390e1969fdcb3b73c60fe7fb37897)의 새로운 변종을 통해 전달되는 세 가지 고유한 구성 요소를 포함합니다. COLDCOPY의 새로운 변종은 사용자가 로봇이 아님을 확인하는 텍스트를 포함하여 캡차(captcha)로 위장하면서, 사용자가 rundll32를 사용하여 DLL을 다운로드하고 실행하도록 유도합니다. 처음 관찰된 DLL의 이름은 "iamnotarobot.dll"이었고 내보내기(export) 이름은 "humanCheck"였으며, 이 두 가지 모두 페이지의 CAPTCHA 테마와 관련이 있으며 뒤따르는 악성코드의 ROBOT 테마 명명 규칙에 부분적으로 영감을 주었습니다.


그림 2: NOROBOT을 실행하도록 사용자를 유인하는 COLDCOPY
NOROBOT
Zscaler에 의해 BAITSWITCH로도 공개된 NOROBOT은 2025년 5월부터 9월까지 정기적으로 개발되는 것이 관찰된 DLL입니다. 관찰된 모든 버전에서 NOROBOT의 주요 목적은 하드코딩된 명령 및 제어(C2) 주소에서 다음 단계를 검색하고 최종 페이로드를 위해 시스템을 준비하는 것이었습니다. NOROBOT의 가장 초기 버전(2e74f6bd9bf73131d3213399ed2f669ec5f75392de69edf8ce8196cd70eb6aee)은 키가 여러 구성 요소에 걸쳐 분할되어 최종 페이로드를 성공적으로 해독하기 위해 특정 방식으로 재조합해야 하는 암호화를 사용했습니다. 이는 다운로드한 구성 요소 중 하나가 누락되면 최종 페이로드가 제대로 해독되지 않기 때문에 감염 체인을 재구성하기 더 어렵게 만들기 위해 수행된 것으로 보입니다. 분석을 방해하려는 이러한 시도에도 불구하고 NOROBOT의 가장 초기 버전에는 전체 Python 3.8 설치를 가져와 추출하는 것이 포함되어 있으며, 이는 의심을 불러일으킬 가능성이 있는 노이즈가 많은 아티팩트입니다.
이 버전의 NOROBOT이 검색한 파일의 세부 정보는 다음과 같습니다.
-
Windows용 Python 3.8 설치가 포함된 SFX RAR
-
암호화 키의 일부를 레지스트리에 저장하는 명령
-
예약된 작업을 통한 지속성
-
libsystemhealthcheck.py라는 파일을 검색하기 위해 bitsadmin을 실행하는 명령
-
libcryptopydatasize.py라는 파일을 검색하기 위해 bitsadmin을 실행하는 명령
bitsadmin을 사용하여 검색된 두 파일은 모두 inspectguarantee[.]org에서 가져온 것입니다.
레지스트리 키 명령어는 다음과 같습니다.
reg add "HKEY_CURRENT_USER\SOFTWARE\Classes\.pietas" /v "ratio" /t REG_BINARY /d "f5e210ec114e1992b81ff89be58cfb2778005f734972239b9655b23fcee5593f19554d0a74dad52c67956781367b06e6" /f지속성은 예약된 작업을 통해 수행됩니다.
powershell -c "
$s = New-Object -ComObject Schedule.Service;
$s.Connect();
$t = $s.NewTask(0);
$p = $t.principal;
$p.logontype = 3;
$p.RunLevel = 0;
$a = $t.Actions.Create(0);
$a.Path = \"$env:APPDATA\Python38-64\pythonw.exe\";
$a.Arguments = \"$env:APPDATA\Python38-64\Lib\libsystemhealthcheck.py\";
$a.WorkingDirectory = \"$env:APPDATA\Python38-64\";
$tr = $t.Triggers.Create(9);
$tr.userID = \"$env:computername\"+\"\\\"+\"$env:username\";
$tr.enabled = $true;
$s.GetFolder(\"\").RegisterTaskDefinition(\"System health check\", $t, 6, $null, $null, 0) | Out-Null;
"libsystemhealthcheck.py에는 레지스트리에 저장된 키와 결합되어 libcryptopydatasize.py를 해독하는 AES 키의 일부가 포함되어 있으며, 저희는 이를 YESROBOT으로 명명했습니다.
YESROBOT
해독된 버전의 YESROBOT은 하드코딩된 C2에서 명령을 검색하기 위해 HTTPS를 사용하는 Python 백도어입니다. 명령은 하드코딩된 키로 AES 암호화됩니다. 시스템 정보 및 사용자 이름은 요청의 User-Agent 헤더에 인코딩됩니다. YESROBOT은 모든 명령이 유효한 Python이어야 하는 최소한의 백도어로, 파일 다운로드 및 실행 또는 문서 검색과 같은 일반적인 기능을 구현하기가 더 번거롭습니다. 일반적인 접근 방식은 백도어에 검색 및 실행 로직을 포함하고 운영자가 URL만 보내도록 요구하는 것입니다. 이로 인해 YESROBOT은 확장 및 운영이 어려우며, YESROBOT의 배포가 성급하게 이루어진 선택이었음을 암시합니다. GTIG는 5월 말 2주 동안 YESROBOT 배포 사례를 두 번만 관찰한 후 다른 백도어인 MAYBEROBOT을 위해 폐기했습니다. 이러한 이유로 GTIG는 LOSTKEYS에 대한 Google의 발표 이후 YESROBOT이 임시방편으로 성급하게 배포되었다고 평가합니다.


그림 3: 파이썬 명령어 실행으로만 제한된 YESROBOT의 메인 루프
MAYBEROBOT
2025년 6월 초, GTIG는 이전 버전보다 대폭 단순화된 NOROBOT 변종(3b49904b68aedb6031318438ad2ff7be4bf9fd865339330495b177d5c4be69d1)을 관찰했습니다. 이 버전은 단일 파일을 가져오는데, 저희가 관찰한 바로는 이 파일은 지속성을 위해 로그온 스크립트를 설정하는 단일 명령이었습니다. 로그온 스크립트는 Zscaler에서는 SIMPLEFIX로도 알려진, 저희가 MAYBEROBOT이라고 부르는 다음 단계를 다운로드하고 실행하는 Powershell 명령이었습니다.
로그온 스크립트에 의해 가져온 파일은 심하게 난독화된 Powershell 스크립트(b60100729de2f468caf686638ad513fe28ce61590d2b0d8db85af9edc5da98f9)로, 하드코딩된 C2와 3개의 명령을 지원하는 사용자 지정 프로토콜을 사용합니다.
-
-
지정된 URL에서 다운로드 및 실행
-
cmd.exe를 사용하여 지정된 명령 실행
-
지정된 powershell 블록 실행
-
모든 경우에 C2에 다른 경로로 확인 응답이 전송되며, 명령 2와 3의 경우 출력은 세 번째 경로로 전송됩니다.
GTIG는 MAYBEROBOT이 YESROBOT을 대체하기 위해 개발되었다고 평가합니다. 그 이유는 실행하는 데 Python 설치가 필요하지 않고, 프로토콜이 확장 가능하며 공격자가 대상 시스템에서 목표를 달성할 때 더 많은 유연성을 제공하기 때문입니다. 유연성이 확실히 향상되었지만, MAYBEROBOT은 여전히 내장 기능이 최소화되어 있으며 이전의 YESROBOT처럼 운영자가 더 복잡한 명령을 제공해야 한다는 점은 주목할 가치가 있습니다.
ROBOT의 진화는 계속된다
GTIG가 2025년 6월부터 9월까지 관심 대상에게 NOROBOT을 전달하려는 COLDRIVER의 시도를 계속 모니터링하고 대응하면서, 저희는 NOROBOT과 악성코드 실행 체인 모두에서 COLDRIVER가 개발 속도를 높이고 있음을 나타내는 변경 사항을 관찰했습니다. GTIG는 시간이 지남에 따라 다양한 수준의 단순성을 가진 여러 버전의 NOROBOT을 관찰했습니다. NOROBOT 변종 간에 이루어진 구체적인 변경 사항은 고가치 표적에 대한 지속적인 정보 수집을 보장하면서 탐지 시스템을 회피하려는 그룹의 지속적인 노력을 강조합니다. 그러나 NOROBOT 다운로더를 단순화함으로써 COLDRIVER는 의도치 않게 GTIG가 그들의 활동을 더 쉽게 추적할 수 있도록 만들었습니다.
NOROBOT 악성코드의 진화에 대한 GTIG의 통찰력은 그들이 오래된 YESROBOT 백도어에서 새로운 MAYBEROBOT 백도어로 전환하는 것을 관찰한 것과 일치했습니다. GTIG는 COLDRIVER가 여러 가지 이유로 최종 백도어를 변경했을 수 있다고 평가합니다. YESROBOT이 작동하려면 전체 Python 인터프리터가 필요하므로 MAYBEROBOT에 비해 탐지 가능성이 높아질 수 있으며, YESROBOT 백도어는 쉽게 확장할 수 없었습니다.
이러한 작전에서 MAYBEROBOT이 더 일반적으로 관찰되는 최종 백도어가 되면서, 거기에 도달하기 위한 NOROBOT 감염 체인은 계속 진화했습니다. 이 기간 동안 COLDRIVER는 악성코드 감염 체인을 단순화하고 인프라 및 파일 이름 규칙 순환, 파일 검색 경로, 해당 경로 구성 방식, 내보내기 이름 변경, DLL 이름 변경과 같은 기본적인 회피 기술을 구현했습니다. 이러한 사소한 변경과 함께 COLDRIVER는 전체 감염 체인을 올바르게 재구성하기 위해 암호화 키와 중간 다운로더 단계를 수집해야 할 필요성을 다시 도입했습니다. 복잡성을 다시 추가하면 활동 재구성을 더 어렵게 만들어 작전의 작전 보안을 높일 수 있습니다. 네트워크 방어자는 전체 공격 체인을 재구성하기 위해 여러 파일과 암호화 키를 수집해야 합니다. 반면 단순화된 NOROBOT 체인에서는 로그온 스크립트에서 URL만 있으면 최종 페이로드를 검색할 수 있습니다.
GTIG는 일관된 개발 노력을 나타내는 여러 버전의 NOROBOT을 관찰했지만, MAYBEROBOT의 최종 백도어는 변경되지 않았습니다. 이는 COLDRIVER가 MAYBEROBOT이 탐지될 가능성이 낮다는 높은 확신을 가지면서 전달 메커니즘의 탐지를 회피하는 데 관심이 있음을 나타냅니다.
피싱인가, 악성코드인가?
COLDRIVER가 그들이 알려진 더 전통적인 피싱 대신 악성코드를 배포하는 이유는 현재 알려져 있지 않지만, 특정 대상에 악성코드를 재정비하고 배포하는 데 상당한 개발 노력을 기울인 것은 분명합니다. 하나의 가설은 COLDRIVER가 이전에 피싱을 통해 침해했을 수 있고 이미 이메일과 연락처를 훔친 중요한 대상에 NOROBOT 및 MAYBEROBOT을 배포하려고 시도하며, 이제 기기에서 직접 정보를 얻어 추가적인 정보 가치를 얻으려는 것입니다.
COLDRIVER가 이 체인을 계속 개발하고 배포함에 따라, 저희는 그들이 정보 수집 요구 사항을 달성하기 위해 고가치 표적에 대한 공격적인 배포를 계속할 것이라고 믿습니다.
커뮤니티 보호
위협 행위자와 싸우기 위한 노력의 일환으로, 저희는 연구 결과를 사용하여 Google 제품의 안전과 보안을 개선합니다. 발견 즉시 모든 식별된 악성 웹사이트, 도메인 및 파일이 Safe Browsing에 추가되어 사용자를 추가적인 악용으로부터 보호합니다. 또한 대상 Gmail 및 Workspace 사용자에게 정부 지원 공격자 경고를 보내 활동을 알리고 잠재적 대상이 Chrome용 향상된 안전 브라우징을 사용하도록 권장하고 모든 기기가 업데이트되었는지 확인하도록 권장합니다.
저희는 이러한 활동의 대상이 되었을 수 있는 회사 및 개인과 인식을 높이기 위해 보안 커뮤니티와 결과를 공유하기 위해 최선을 다하고 있습니다. 전술 및 기술에 대한 이해가 향상되면 위협 추적 기능이 향상되고 업계 전반에 걸쳐 더 강력한 사용자 보호로 이어지기를 바랍니다.
침해 지표(IOC) 및 YARA 규칙이 이 게시물에 포함되어 있으며, GTI 컬렉션 및 규칙 팩으로도 제공됩니다.
침해 지표(IOC)
다음 침해 지표는 등록된 사용자를 위해 Google Threat Intelligence(GTI) 컬렉션에서 확인할 수 있습니다.
YARA 룰
rule G_APT_Downloader_NOROBOT_2 {
meta:
author = "Google Threat Intelligence"
description = "DLL which pulls down and executes next stages"
strings:
$path = "/konfiguration12/" wide
$file0 = "arbeiter" wide
$file1 = "schlange" wide
$file2 = "gesundheitA" wide
$file3 = "gesundheitB" wide
$new_file0 = "/reglage/avec" wide
$new_file1 = "/erreur" wide
condition:
filesize <= 1MB and
(
$path or
all of ($file*) or
all of ($new_file*) or
(
for any s in ("checkme.dll", "iamnotarobot.dll", "machinerie.dll"): (pe.dll_name == s) and
for any s in ("humanCheck", "verifyme"): (pe.exports(s))
)
)
}rule G_APT_BACKDOOR_YESROBOT_1 {
meta:
author = "Google Threat Intelligence Group (GTIG)"
strings:
$s0 = "return f'Mozilla/5.0 {base64.b64encode(str(get_machine_name()).encode()).decode()} {base64.b64encode(str(get_username()).encode()).decode()} {uuid} {get_windows_version()} {get_machine_locale()}'"
$s1 = "'User-Agent': obtainUA(),"
$s2 = "url = f\"https://{target}/connect\""
$s3 = "print(f'{target} is not availible')"
$s4 = "tgtIp = check_targets(tgtList)"
$s5 = "cmd_url = f'https://{tgtIp}/command'"
$s6 = "print('There is no availible servers...')"
condition:
4 of them
}rule G_APT_BACKDOOR_MAYBEROBOT_1 {
meta:
author = "Google Threat Intelligence Group (GTIG)"
strings:
$replace = "-replace '\\n', ';' -replace '[^\\x20-\\x7E]', '' -replace '(?i)x[0-9A-Fa-f]{4}', '' -split \"\\n\""
condition:
all of them
}