今日表示しない

トップへ戻る

トップへ戻る

脅威インテリジェンス

脅威インテリジェンス

脅威インテリジェンス

エンキホワイトハット

エンキホワイトハット

コンテンツ

コンテンツ

コンテンツ

1. 概要

この技術分析レポートは、大韓民国国家情報院、警察庁、韓国インターネット振興院、金融セキュリティ院が合同で発表したサイバーセキュリティ勧告「国家を背景とするハッキング組織による自国国民・企業へのハッキング攻撃に関する注意勧告」の一環として作成されました。


昨年下半期から、国内の正常なウェブサイトを侵害し、ウェブページに特定のソリューションのエクスプロイトコードを挿入してマルウェアを拡散させる水飲み場攻撃(ウォータリングホール攻撃)が多数観測されています。代表的な例として、攻撃者はAnySign4PCのゼロデイ(0-day)脆弱性を悪用しており、これによりAnySign4PCがインストールされたシステムからエクスプロイトコードが挿入されたウェブページにアクセスすると、マルウェアがシステムにインストールされ、実行されます。


確認されたマルウェアは、共通してChaCha20またはAES-128アルゴリズムにより後続のペイロードを復号し、メモリ上で実行する多段階のローディングチェーンを構成していました。また、暗号化されたペイロードと設定データが一般的なファイル探索やセキュリティソフトウェアによって識別されないよう、レジストリやNTFS ADSといった正常なWindowsシステム構成要素内に隠蔽していました。


最終的に実行されるマルウェアは、攻撃者に侵害された国内の正常なウェブサーバーとHTTP/HTTPS通信を行い、リモートコマンド実行、ファイルの窃取、シェルコード実行、プロセスインジェクションなどを実行します。


本レポートでは、確認された3種類のマルウェアに関する分析内容と、キャンペーンで確認された攻撃の戦術・技術・手順(TTPs)について説明し、検知および対応の防御策を提示します。

2. 악성코드 분석

2.1. 분석 대상 개요

확보한 악성코드는 총 6개이며, 감염 체인 구성에 따라 3개 유형으로 구분할 수 있다. 유형별 단계 구성과 각 단계의 역할은 아래 표와 같다.

유형

파일명

역할

TYPE 1

smss.exe

드로퍼


edgsvc.dll

로더


gsosvc.dat

백도어

TYPE 2

rasgreeng.dll

로더


bold.dll

다운로더

TYPE 3

ipbootp.dll

로더

위 표의 단계 구성은 확보한 악성코드로만 재구성한 것으로, 실제 공격에 사용된 전체 감염 체인과는 차이가 있다. 분석 과정에서 확인되지 않은 항목은 다음과 같다.

  1. 각 유형별 유포 경로 및 초기 침투 악성코드

  2. TYPE 1 드로퍼 실행 인자

  3. TYPE 2 셸코드

  4. TYPE 3 ADS 데이터

유형별 특징을 정리한 표는 아래와 같다.

항목

TYPE 1

TYPE 2

TYPE 3

암호 알고리즘

ChaCha20

AES-CBC-128

AES-CBC-128

파일 및 설정 데이터 은닉 위치

레지스트리, NTFS ADS(설정 데이터)

레지스트리(다운로더, 설정 데이터)

NTFS ADS

지속성 확보 방식

서비스 하이재킹, SSP 등록

미확인

미확인

C&C 통신 방식

POST(hash, lang, ei/ie 또는 oq)

POST(type, data)

미확인

전송 데이터 처리 방식

ChaCha20 + XOR → Base64

AES-CBC-128 → Base64

미확인

2.2. TYPE 1

해당 유형은 드로퍼, 로더, 백도어로 구성되어 있고 최종 백도어는 COPPERHEDGE 변종으로 확인되었다.

2.2.1. smss.exe - 드로퍼

32비트 Windows MFC 실행 파일로, 내부 프로젝트명은 shayTamir이다. 정상 파일로 보이지만 실행 시 특정 길이의 인자가 전달되면 악성 로직이 실행된다.

caption - 파일 정보

악성 로직 실행 조건

악성코드 실행 시 34자(wide-char)의 인자가 전달되면 악성 로직이 실행된다. 전달된 인자에서 첫 번째와 마지막 글자를 제외한 나머지 글자는 다이얼로그 객체에 저장되며, 이후 오버레이 데이터를 복호화하는 ChaCha20 키로 사용된다.

caption - 인자 파싱 루틴

34자 인자가 전달되지 않으면 악성 로직은 실행되지 않아 정상 프로그램이 실행된 것처럼 보인다.

안티 리버싱 기법

악성코드에는 분석을 방해하기 위한 4가지 기법이 적용되어 있다. 적용된 기법은 아래 표와 같다.

기법

내용

효과

문자열 암호화

모든 민감 문자열을 ChaCha20으로 암호화하였다. 복호화의 경우 하드코딩된 키를 이용한다.

문자열 기반 정적 분석 및 시그니처 탐지 회피

API 이름 암호화 및 동적 API

API 이름은 XOR로 암호화되어 있다. 실행 시점에 복호화되어 API 함수 주소를 동적으로 resolve한다.

IAT 은닉으로 Import 목록만으로 기능 추정 불가

명령줄 게이트

34자 인자가 없으면 악성 로직이 실행되지 않는다.

샌드박스 자동 분석 회피(상위 바이너리가 존재하지 않는 경우)

드롭 파일명 랜덤 생성 및 바이너리 패딩

악성코드가 실행될 때마다 드롭 파일명을 무작위로 생성하고, 60MiB ~ 80MiB의 정크 데이터를 추가한다.

파일명, 해시 기반 탐지 회피

문자열 복호화에 사용되는 ChaCha20 키, IV, Counter 값은 아래와 같다.

  • ChaCha20 키(16진수 형태): BC B4 E7 B1 E6 B7 B4 E7 BD B1 B4 B7 B3 B2 E0 E4 B6 E0 BC E7 E4 E7 BC B7 B6 BC B3 B6 B4 BD E0 B2

  • ChaCha20 IV: 876543210987

  • ChaCha20 Counter: 255

API 이름은 XOR 연산만으로 암호화되어 있으나, 복호화 루틴은 단일 키를 반복하는 형태가 아니다. 복호화에는 아래 세 값을 조합해 한 바이트씩 평문을 구한다.

  • 암호화된 이름

  • xor 키 테이블

  • 데이터 영역의 바이트 데이터

암호화된 이름과 xor 키 테이블은 고정된 값이지만 데이터 영역의 바이트 데이터는 복호화 과정에서 계속 변경된다. 이로 인해 특정 바이트를 복호화하려면 이전 연산이 모두 정확히 수행되어야 한다.

caption - api 이름 복호화 로직

복호화에 사용되는 xor 키 테이블 데이터는 아래와 같다.

  • 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05 00 03 82(16진수 형태)

이 중 06 09 2A 86 48 86 F7 0D 01 01 01은 DER로 인코딩된 rsaEncryption OID의 바이트열과 일치한다. 이는 암호 관련 표준 상수를 본래 용도와 무관하게 사용한 것으로 보인다.

드롭 파일명 생성

드로퍼는 실행될 때마다 서비스로 실행되는 DLL과 백도어의 파일명을 무작위로 생성한다. 파일명이 고정되어 있지 않으므로 파일명 기반 탐지 규칙으로는 식별이 어렵다. 드롭되는 두 파일의 구성은 아래 표와 같다.

확장자

설명

.dll

서비스로 등록되어 실행되는 로더, .dat 파일을 복호화해 메모리에서 실행한다.

.dat

로더에 의해 복호화되어 메모리에서 실행되는 백도어

파일명 생성 루틴은 2회 호출되며, 각 자리별로 지정된 알파벳 집합에서 문자를 하나씩 무작위로 선택하되 세 글자가 모두 서로 다르도록 제한한다. 자리별 알파벳 집합은 아래와 같다.

  • 첫 번째 자리: [abcdefgmnpsw]

  • 두 번째 자리: [abcdefhlmnprs]

  • 세 번째 자리: [acefghinoprst]

이후 GetTickCount 함수 반환 값의 최하위 비트에 따라 svc 또는 mgr 문자열을 결합하고, 확장자를 붙여 최종 파일명을 완성한다. 이때 동일한 이름의 파일이 이미 존재하는 경우 최대 100회까지 재생성을 시도한다. 분석 과정에서 확인된 파일명은 edgsvc.dll, gsosvc.dat이다. 생성 경로는 C:\Windows\System32이다.

caption - 드롭 파일 생성 로직

하이재킹 대상 서비스 선정

로더 DLL을 svchost.exe가 자동으로 실행하도록 만들기 위해, 새로운 서비스명을 생성하지 않고 netsvcs 그룹에 이름은 등록되어 있으나 실제 서비스 키가 존재하지 않는 빈 슬롯을 찾아 하이재킹 대상으로 삼는다.

먼저 암호화된 레지스트리 경로(HKLM\SOFTWARE\Microsoft\Windows NT\currentVersion\Svchost)를 복호화해 해당 경로의 netsvcs 값에서 서비스 목록을 조회한다. 이후 각 항목에 대해 HKLM\SYSTEM\CurrentControlSet\Services\<서비스명> 키 열기를 시도하고, 열기에 실패한 이름만 수집한다. 마지막으로 수집된 목록에서 rand 함수 반환 값을 이용해 하나를 선택하고 하이재킹한다.

caption - 레지스트리 조회 로직

로더, 백도어 추출 및 드롭

로더와 백도어는 악성코드 오버레이 영역에 암호화 및 압축된 상태로 내장되어 있다.

먼저 악성코드에 존재하는 28바이트 마커 34567890ABCDEFGHIJklmnopqrst를 탐색해 오버레이 위치를 식별한다. 이후 인자로 전달된 데이터를 키로 사용해 28바이트 헤더를 ChaCha20으로 복호화하고, 복호화된 첫 4바이트 값이 나머지 6개 DWORD의 합과 일치하는지 확인하는 체크섬 검사를 한다. 이 검사는 전달된 인자가 올바른 경우에만 통과하므로, 인자 값을 모르면 내장된 로더와 백도어를 추출할 수 없다.

caption - 검증 로직

체크섬 검사를 통과하면 헤더의 오프셋 및 길이 정보를 이용해 데이터 세그먼트 2개를 복호화하고, 각각 C:\Windows\System32 경로에 미리 생성된 파일명으로 저장한다.

caption - 파일 생성 로직

설정 데이터 구성 및 저장

로더는 자신이 복호화해야 할 백도어의 파일명과 복호화 키를 알아야 한다. 이를 위해 두 정보를 레지스트리에 암호화해 기록한다.

4,204 바이트의 설정 블롭을 구성해 생성된 파일명 등의 정보를 기록하고, 이를 ChaCha20으로 암호화해 아래 레지스트리 경로에 REG_BINARY 형식으로 저장한다. 이때 %d 형식 지정자에는 파일명 첫 3글자에서 각각 0x60을 뺀 값을 대입하고, 레지스트리 기록에 성공하면 다이얼로그 플래그를 1로 세팅한다. 확인된 레지스트리 경로는 아래와 같다.

  • 레지스트리 경로: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\USB_Keyboard_547

caption - 레지스트리 경로 생성 로직

설정 데이터 구조는 아래 표와 같다.

  • 설정 데이터는 다른 감염 사례에서 확인하였다. 레지스트리 값, 로더명, 백도어명이 본 보고서에서 언급되는 것과 다르다.

  • 그러나 설정 데이터에 있는 백도어 ChaCha20 키를 이용해 다음 단계 복호화가 가능하였다.

오프셋

크기

타입

필드

+0x000

4

DWORD

C&C URL 개수

5

+0x004

260

ASCII

C&C URL[0]

hxxps://f****.com/include/security.asp

+0x108

260

ASCII

C&C URL[1]

hxxp://1*****2/default.php

+0x20C

260

ASCII

C&C URL[2]

hxxp://1*****7/default.php

+0x310

260

ASCII

C&C URL[3](=URL[1] 중복)

hxxp://1*****2/default.php

+0x414

260

ASCII

C&C URL[4](=URL[2] 중복)

hxxp://1*****7/default.php

+0x518

4

DWORD

직접 IP 연결 모드 플래그

0(비활성)

+0x51C

4

in_addr

C&C 직접 IP

0

+0x520

2

WORD

C&C 포트

0

+0x522

4

DWORD

연속 접속 실패 허용 횟수

5

+0x526

4

DWORD

논리 드라이브 변경 감시 스레드 사용 여부

0

+0x52A

4

DWORD

터미널 세션 변경 감시 스레드 사용 여부

0

+0x52E

4

DWORD

자가 보호 사용 여부

0(미사용)

+0x532

2

WORD

재접속 대기 시간(분)

60(0x3C)

+0x534

8

double

활성화 대기 시각(VARIANT time)

45709.45 → 2025-02-21 10:48:01

+0x53C

32

UTF-16

로더 DLL명

bhamgr.dll

+0x55C

32

UTF-16

백도어 페이로드명(.dat)

wchmgr.dat

+0x57C

32

UTF-16

C&C 보고 식별자

uploadmgr

+0x59C

32

-

0x2026 명령 응답에 포함되는 필드(용도 미상)

0

+0x5BC

4

DWORD

동작 모드(설정 로드 직후 현재 모드 값으로 덮어씀)

5

+0x5C0

32

ASCII

백도어 ChaCha20 키

GX152-6M2V9Z-16KIPG-KAJRE4-PR376

+0x5E0

4

-

(0)

-

+0x5E4

520

UTF-16

명령 실행 셸 경로

c:\windows\system32\cmd.exe

+0x7EC

520

UTF-16

명령 결과 임시 파일 생성 경로

(비어있음, 미설정 시 %TEMP% 사용)

+0x9F4

520

UTF-16

PNG 파일 경로 0

(비어있음)

+0xBFC

520

UTF-16

PNG 파일 경로 1

(비어있음)

+0xE04 ~ +0x100C

-

-

0x00 패딩/예약

-

+0x100C

32

bytes

PNG 모듈 복호화 키 0(0xBD-XOR 저장)

00 00 AC 23 00 00 00 00 70 23 00 00 00 00 78 23 38 DF 3F 7C 06 00 00 00 00 00 10 7C B8 DF 4D 82

+0x102C

32

bytes

PNG 모듈 복호화 키 1

동일 값

+0x104C ~ +0x106C

-

-

0x00 패딩(끝)

-

서비스 등록 및 실행

위 과정에서 다이얼로그 플래그가 1이 되면 SCM API를 이용해 서비스를 등록하고 실행한다. 과정은 다음과 같다.

  1. CreateServiceW로 서비스를 생성하고, ImagePath는 %SystemRoot%\system32\svchost.exe -k netsvcs로 지정해 공유 프로세스 방식으로 동작하게 한다.

  2. ChangeServiceConfig2로 서비스 설명과 복구 옵션을 설정한다. 실패 시 120초 지연 후 자동 재시작하며, 실패 카운터는 24시간 주기로 초기화된다.

  3. HKLM\SYSTEM\CurrentControlSet\Services\<선택된 서비스명>\Parameters\ServiceDll 값에 드롭한 DLL 경로를 REG_EXPAND_SZ 형식으로 기록한다.

  4. StartService로 서비스를 실행한다.

이로 인해 시스템 부팅 시마다 로더가 자동으로 실행되며, 서비스가 비정상 종료되더라도 복구 설정에 의해 재시작된다.

2.2.2. edgsvc.dll - 로더

edgsvc.dll은 하이재킹된 서비스로 등록되어 실행되는 로더이다. 앞 단계인 드로퍼와 동일하게 API를 실행 시점에 해석해 IAT를 은닉하고, 레지스트리에 저장된 설정 데이터를 복호화해 백도어 파일 경로와 복호화 키를 획득한다. 백도어는 리플렉티브 로딩 방식으로 메모리에서 실행한다.

API 이름 암호화 및 동적 API

API 이름은 xor 연산만으로 암호화되어 있으나, 복호화 루틴은 단일 키를 반복하는 형태가 아니다. 복호화 함수는 분기와 호출 없이 약 8,960개 명령으로 구성되어 있다. 복호화에는 아래 세 값을 조합해 한 바이트씩 평문을 구한다.

  • 암호화된 이름

  • xor 키 테이블

  • 데이터 영역의 바이트 데이터

암호화된 이름과 xor 키 테이블은 고정된 값이지만 데이터 영역의 바이트 데이터는 복호화 과정에서 계속 변경된다. 이로 인해 특정 바이트를 복호화하려면 이전 연산이 모두 정확히 수행되어야 한다.

caption - api 이름 복호화 로직

복호화에 사용되는 xor 키 테이블 데이터는 아래와 같다.

  • 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05 00 03 82(16진수 형태)

이 중 06 09 2A 86 48 86 F7 0D 01 01 01은 DER로 인코딩된 rsaEncryption OID의 바이트열과 일치한다. 이는 암호 관련 표준 상수를 본래 용도와 무관하게 사용한 것으로 보인다.

설정 데이터 조회 및 복호화

먼저 악성코드에 하드코딩된 ChaCha20 키와 IV로 레지스트리 서브키 문자열과 값 이름을 각각 복호화한다. ChaCha20 키와 IV는 드로퍼가 사용하는 것과 동일하다.

  • ChaCha20 키(16진수 형태): BC B4 E7 B1 E6 B7 B4 E7 BD B1 B4 B7 B3 B2 E0 E4 B6 E0 BC E7 E4 E7 BC B7 B6 BC B3 B6 B4 BD E0 B2

  • ChaCha20 IV: 876543210987

  • ChaCha20 Counter: 255

복호화된 서브키 문자열에는 드로퍼와 동일하게 %d 형식 지정자 3개가 포함되어 있으며, 로더 파일명의 첫 3글자에서 0x60을 뺀 값이 대입되면 최종 경로가 완성된다.

  • 최종 레지스트리 경로: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\USB_Keyboard_547

레지스트리 경로에서 암호화된 설정 데이터(4,204바이트)를 읽어 ChaCha20으로 복호화한다. 복호화된 설정 데이터에서 추출하는 정보는 아래 2가지이다.

  • 백도어 파일명

  • 백도어 복호화용 ChaCha20 키

caption - 설정 데이터 복호화 및 추출 로직

로더는 서로 다른 2개의 ChaCha20 키를 사용하고, 획득 경로가 상이하다. 상세 정보는 아래 표와 같다.

용도

출처

비고

레지스트리 경로, 값 이름, 설정 데이터 복호화

바이너리에 하드코딩

IV는 876543210987(드로퍼가 사용하는 ChaCha20 IV와 동일)

백도어 복호화

설정 데이터에서 추출

바이너리에 존재하지 않는다. 레지스트리에 기록된 설정 데이터 없이는 백도어 복호화 불가

백도어 복호화 및 실행

위 과정에서 백도어 파일명과 백도어 복호화용 ChaCha20 키를 추출하였으므로 먼저 C:\Windows\System32 문자열과 백도어 파일명을 결합해 전체 경로를 구성한다. 이후 파일 데이터를 읽어 백도어 복호화용 ChaCha20 키를 이용해 복호화한다. 만약 복호화 과정에서 키 인자가 전달되지 않은 경우 하드코딩된 키를 사용하도록 구현되어 있다. 확인된 복호화 키는 아래와 같다.

  • 백도어 복호화용 ChaCha20 키: GX152-6M2V9Z-16KIPG-KAJRE4-PR376

caption - 복호화 키 설정 로직

복호화된 백도어는 파일로 생성되지 않고 자체 구현된 PE로더 로직을 통해 메모리에서 실행된다. 단계는 다음과 같다.

  1. MZ 및 PE 시그니처 탐색 및 검증

  2. 메모리 할당 이후 헤더와 섹션 데이터 복사

  3. 베이스 재배치 및 임포트 테이블 해석

  4. 섹션별 메모리 보호 속성 적용

  5. TLS 콜백 실행

  6. 엔트리포인트 호출

2.2.3. gsosvc.dat - 백도어

로더에 의해 메모리에서 실행되는 백도어로, 해당 백도어는 COPPERHEDGE 변종으로 확인되었다.

동작 모드 조건

DllMain 함수 실행 시 ChaCha20으로 프로세스명 2개(lsass.exe, svchost.exe)를 복호화한 뒤, 현재 프로세스명 및 로드된 DLL명 길이와 비교해 동작 모드를 결정한다. 복호화에 사용되는 ChaCha20 키, IV는 드로퍼 및 로더와 동일하다.

  • ChaCha20 키(16진수 형태): BC B4 E7 B1 E6 B7 B4 E7 BD B1 B4 B7 B3 B2 E0 E4 B6 E0 BC E7 E4 E7 BC B7 B6 BC B3 B6 B4 BD E0 B2

  • ChaCha20 IV: 876543210987

  • ChaCha20 Counter: 255

전체 동작 모드의 동작 조건과 설명은 아래 표와 같다.

모드

동작 조건

설정 저장

자가 보호

0

외부 로더가 설정한 경우

저장 없음

없음

1

프로세스가 lsass.exe인 경우

HKLM 레지스트리

로더, 백도어 데이터를 전역 변수에 저장한 뒤 로더와 백도어, 설정 데이터 삭제

2

프로세스가 svchost.exe이고 DLL명이 10자 이하인 경우

HKLM 레지스트리

로더, 백도어 데이터를 전역 변수에 저장한 뒤 로더와 백도어, 설정 데이터 삭제

3

외부 로더가 설정한 경우

NTFS ADS 파일

없음

4

프로세스가 lsass.exe, svchost.exe가 아닌 경우

HKLM 레지스트리

로더, 백도어 데이터를 전역 변수에 저장한 뒤 로더와 백도어, 설정 데이터 삭제

5

프로세스가 svchost.exe이고 DLL명이 10자 초과인 경우

HKLM 레지스트리

로더, 백도어 데이터를 전역 변수에 저장한 뒤 로더와 백도어, 설정 데이터 삭제

모드 1은 악성코드가 SSP(Security Support Provider)로 lsass.exe에 로드된 상태이고 모드 3은 설정 데이터를 %LOCALAPPDATA%\Microsoft\Internet Explorer\brndlog.txt:loginfo ADS에 저장한 형태이다.

모드 값은 프로세스명 매칭 결과로만 1, 2, 4, 5 중 하나로 결정되고 모드 0, 3은 별도의 외부 로더가 컨텍스트(모드 필드, 설정 포인터)를 직접 구성해 실행한 방식에서만 사용된다. 본 보고서에서는 동작 모드가 2 또는 5인 경우에 대해 설명한다.

지속성 확보

위 과정이 완료되면 중복 실행 방지를 위해 뮤텍스를 생성하고 지속성을 확보한다. 뮤텍스명은 아래와 같다.

  • 뮤텍스명: MsSecurityObj

caption - 뮤텍스 설정 로직

지속성은 SSP 등록을 통해 확보한다. HKLM\SYSTEM\CurrentControlSet\Control\Lsa경로의 Security Packages 값에 로더 파일명을 추가하고, 이때 System32 경로의 reg.exe를 이용해 기존 Security Packages 값을 읽어 기존 항목을 64자 단위로 그대로 보존한 채 로더 파일명만 목록에 추가해 REG_MULTI_SZ 값을 재구성한다. 이후 시스템 부팅 시 lsass.exe가 SSP로 등록된 DLL을 자동으로 로드한다.

caption - 레지스트리 값 작성 로직

자가 보호 루틴

모드 1, 2, 4, 5에서는 초기화 과정에서 자가 보호 루틴이 실행된다. 먼저 설정 데이터가 담긴 레지스트리 값을 삭제하고, 로더와 백도어 데이터를 각각 메모리에서 읽은 뒤 로더와 백도어를 삭제한다. 이후 콘솔 컨트롤 핸들러를 등록해, 시스템 종료 이벤트 발생 시 메모리에 저장 중인 로더와 백도어 그리고 설정 데이터가 복원되도록 설정한다.

caption - 메모리 저

설정 데이터는 이미 메모리에 존재하므로 따로 읽지는 않는다. 또한 복원 시 로더는 파일 데이터에 64MiB ~ 80MiB 정크 데이터가 추가된 상태로 복원된다. 설정 파일은 기존 레지스트리 경로에 복원된 후 SSP를 재등록한다.

시스템 정보 수집

컴퓨터명, 사용자명, 네트워크 어댑터의 IPv4 주소, OS 제품명, ANSI 코드 페이지를 수집한다. 또한 현재 동작 모드도 수집하며 컴퓨터명과 CPU 모델명을 결합한 데이터의 CRC32 값을 시스템 식별 값으로 생성한다. 이후 자신의 실행 경로를 획득해 해당 디렉토리를 작업 디렉토리로 설정한다.

caption - 시스템 정보 수집 로직

C&C 서버 통신

설정 데이터에 포함된 C&C 서버 URL에 대해 요청을 전송한다. 확인된 C&C 서버 URL은 총 3개로 모두 국내 서버이다.

  • hxxps://f*****.com/include/security.asp

  • hxxp://1*****.2/default.php

  • hxxp://1*****.7/default.php

C&C 서버 SSL 적용 여부에 따라 통신 시 사용하는 파라미터 구성이 상이하다.

  • SSL: hash=<1000~9999 랜덤>&lang=T3F56E5UJH0JC3D4&ei=<50~255 랜덤>&ie=<통신 데이터>

  • Non-SSL: hash=<1000~9999 랜덤>&lang=T3F56E5UJH0JC3D4&oq=<통신 데이터>

통신 데이터는 12바이트 헤더와 가변 길이 페이로드로 구성되며, 헤더 구조는 아래 표와 같다.

오프셋

크기

항목

+0

2

랜덤 값

+2

2

명령 ID

+4

4

완료 플래그

+8

4

페이로드 크기

통신 데이터와 헤더는 각각 ChaCha20 및 XOR로 암호화된 후 Base64로 인코딩되어 URL 파라미터에 연결된다. 첫 통신 시 C&C 서버의 응답이 전송한 hash 파라미터 값과 일치하는지 검증하며, 불일치할 경우 연결을 종료한다.

caption - 응답 데이터 검증 로직

명령 수신 루프는 먼저 hash=<기존 hash 파라미터 값+10000> 값과 명령 ID 0x2047로 폴링 요청을 전송한다. 이후 기존 hash 파라미터 값과 함께 C&C의 명령 데이터를 수신하면 명령 ID에 따라 핸들러를 호출하며, 명령 실행 결과를 기존 hash 파라미터 값과 함께 전송한 후 다시 <기존 hash 파라미터 값+10000> 값으로 폴링한다.

확인된 명령 코드는 총 30개로 상세 동작은 “부록 C. 명령 코드” 참고 바란다.

추가 모듈 로드 및 인젝션

실행 중 반복적으로 설정 데이터에 저장된 2개의 PNG 파일 경로에서 은닉된 추가 모듈 데이터를 읽어와 복호화한 뒤 explorer.exe에 인젝션해 실행한다. 다만 분석된 설정 데이터에는 PNG 파일 경로가 기록되어 있지 않았다.

복호화 과정은 다음과 같다.

  1. 각 32바이트 블록에 대해 i = 31부터 0까지 역순으로 순회하며, key[i] 값을 12로 나눈 나머지가 0이 아닌 경우에만 아래를 수행한다.

  2. 교환 위치 j = (key[i] % 12 + i) % 32를 산출한 뒤, block[i]block[j]를 교환한다.

  3. 교환 후 block[i](원래 block[j]에 있던 값)를 key[i]와 XOR한다.

복호화에 사용되는 키는 설정 데이터(+0x100C)에 각 바이트가 0xBD와 XOR된 형태로 저장되어 있으며, 이를 XOR해 원본 키를 복원한다. 원본 복호화 키는 아래와 같다.

  • 원본 복호화 키(16진수 형태): BD BD 11 9E BD BD BD BD CD 9E BD BD BD BD C5 9E 85 62 82 C1 BB BD BD BD BD BD AD C1 05 62 F0 3F

2.3. TYPE 2

해당 유형은 로더, 다운로더, 셸코드로 구성되어 있으나 셸코드는 확보하지 못하였다.

2.3.1. rasgreeng.dll - 로더

해당 로더에는 ES-Computing의 유효하지 않은 인증서로 서명이 적용되어 있다.

항목

Subject

C=KR, ST=Gyeongsangnam-do, L=Jinju-si, O=ES-Computing, OU=IT Team, CN=ES-Computing

Issuer

thawte SHA256 Code Signing CA

Serial Number

13F8F43FFAFEAD5F5EA8C0D259C2D0E6

Thumbprint(SHA1)

2E1DD779B28F86B5766C08245B86E37E9C5E4937

Thumbprint(SHA256)

76C71C03440826ADF26F4C35C36B97343ADCFF6A48188393EDD375F9A7289F14

유효기간

2019-02-14 ~ 2020-05-15(만료)

레지스트리 조회 및 복호화

특정 레지스트리 경로에 존재하는 다운로더와 설정 데이터를 읽어 복호화한다. 레지스트리 경로는 평문으로 존재하고, 각 레지스트리 경로에 대한 설명은 아래 표와 같다.

레지스트리 경로

설명

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts\GiddyupStda Bold

암호화된 다운로더 데이터

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts\GiddyupStda

암호화된 설정 데이터(C&C 서버 URL 포함)

암호화된 다운로더 데이터는 AES-CBC-128로 복호화한다. 복호화에 사용되는 키와 IV는 아래와 같다.

  • AES 키: g2Oc6qWRU3n.B0Pm

  • AES IV(16진수 형태): 00000000000000000000000000000000

caption - 레지스트리 조회 및 복호화 로직

암호화된 설정 데이터는 로더에서 복호화하지 않고 다음 단계인 다운로더에서 복호화한다.

다운로더 실행 및 인자 전달

복호화된 다운로더를 메모리에서 실행하는데, 이때 다운로더의 DllMain 함수를 호출하면서 AES 키와 암호화된 설정 데이터를 인자로 전달한다.

caption - 메모리 실행 로직

2.3.2. bold.dll - 다운로더

네임드 파이프 생성

DllMain 함수가 호출되면 네임드 파이프를 생성한다. 이때 파이프 이름은 다음 단계를 통해 생성된다.

  1. D9hWnVEqdgzJ673B8euS 문자열에서 무작위 인덱스 문자 2개를 골라 서로 위치를 교환한다.

  2. 위 과정을 201회 반복한다.

  3. \\.\pipe\<셔플 결과 문자열> 형식으로 최종 이름을 조합한다.

caption - 파이프 생성 로직

C&C 서버 통신

인자로 전달받은 암호화된 설정 데이터를 함께 전달된 AES 키로 복호화해 C&C 서버 URL을 추출한다. 확인된 C&C 서버 URL은 아래와 같다.

  • hxxps://d*****.com/lgdacom_mobile/lgdacom.asp

  • hxxps://www.l*****.co.kr/lib/asp/include_view.asp

통신을 시도하기 전에 각 C&C 서버 URL별로 실제 통신 가능 여부를 먼저 확인한다. 먼저 봇 ID를 4바이트 rand 함수 반환 값으로 생성한 뒤 type=<봇 ID(hex)>&data=8Rvi4-UPMQvFgjMJ3cZF 형식으로 파라미터를 구성해 POST 요청을 전송하고, 응답이 <!DOCTYPE html>로 시작하는지 확인해 활성 여부를 판단한다.

caption - 통신 가능 여부 확인 로직

활성으로 확인되면 데이터를 수신한다. 이때 type=cisco 형식으로 POST 요청을 전송해 C&C 서버로부터 데이터를 수신한다. 응답 데이터의 앞 15바이트가

<!DOCTYPE html>

로 시작하면 나머지 데이터를 복호화한다. 복호화는 응답 데이터의 공백 문자를 +로 치환하고 Base64로 디코딩한다. 이후 AES-CBC-128로 복호화한다.

caption - 응답 데이터 복호화 로직

복호화된 데이터는 10바이트 헤더와 실제 데이터로 구성되며, 헤더 구조는 아래 표와 같다.

오프셋

크기

항목

+0

2

명령 코드

+2

4

데이터 크기

+6

4

종료 플래그(수신 완료·루프 종료 신호)

+10

-

실제 데이터

이때 수신한 명령 코드가 60(0x3C) 이하이면 오프셋 10부터의 데이터를 셸코드 실행 함수로 전달한다. 셸코드 실행 시에는 파이프 이름, 복호화된 설정 데이터, 다운로더의 상태 정보 등을 함께 전달한다. 셸코드 실행을 마친 뒤, 방금 실행한 명령 코드가 19(0x13)이고 실행 결과가 0이면 통신 루프를 정상 종료한다. 추가로 크기가 큰 셸코드의 경우 헤더의 종료 플래그가 설정되고 누적 수신량이 전체 크기에 도달할 때까지 type=cisco 요청을 반복해 분할 수신한다.

수신한 명령 코드가 60(0x3C)을 초과하는 경우에는 셸코드를 실행하지 않고, 명령 코드 24(0x18)와 플래그 1로 확인 응답만 전송한 뒤 다음 명령을 대기한다.

caption - 셸코드 실행 로직

파이프 데이터 송신

네임드 파이프 스레드는 메인 C&C 통신 루틴과 별도의 스레드로 생성되어, 파이프를 통해 전달되는 데이터를 C&C 서버로 전송한다. 데이터 앞 10바이트에 수신 시와 동일한 구조의 헤더를 추가하고, 수신 데이터 복호화에 사용한 것과 동일한 키로 AES-CBC-128 암호화를 한다. 최종적으로 암호화된 데이터를 Base64로 인코딩해 type=article&data=<인코딩된 데이터> 형식으로 POST 요청을 전송한다.

caption - 파이프 데이터 송신 로직

C&C 서버에서 다운로드하는 셸코드는 확보하지 못해 이후 과정은 분석할 수 없었다.

2.4. TYPE 3

2.4.1. ipbootp.dll - 로더

해당 로더는 자기 자신의 ADS에 저장된 암호화된 DLL을 복호화해 메모리에서 실행한다.

API 이름 암호화 및 동적 API

API 이름은 AES-CBC-128로 암호화되어 있다. 복호화에 사용되는 키와 IV는 하드코딩되어 존재한다.

  • AES 키(16진수 형태): CE F6 E7 9D D1 F2 C6 1B 5F 26 5D A1 7D 73 A2 15

  • AES IV(16진수 형태): CD 85 ED 5E 75 20 CB 3F 98 3E 6B 7F DA 53 71 1D

ADS 페이로드 추출 및 실행

ADS 관련 문자열도 AES-CBC-128로 복호화된다. ADS 관련 문자열은 아래와 같다.

  • :dat, :kgb

자기 자신의 ADS에서 암호화된 페이로드와 복호화 키를 추출한다. 각 ADS 경로는 아래 표와 같다.

ADS 경로

내용

<자기 자신 경로>:dat

암호화된 페이로드

<자기 자신 경로>:kgb

AES 키 16바이트 + IV 16바이트

:kgb의 첫 16바이트가 AES 키이고 다음 16바이트가 IV이다. 이후 AES-CBC-128로 암호화된 페이로드를 복호화한다. 복호화된 페이로드는 파일로 생성되지 않고 자체 구현된 PE로더 로직을 통해 메모리에서 실행된다. 단계는 다음과 같다.

  1. MZ 및 PE 시그니처 탐색 및 검증

  2. 메모리 할당 이후 헤더와 섹션 데이터 복사

  3. 베이스 재배치 및 임포트 테이블 해석

  4. 섹션별 메모리 보호 속성 적용

  5. TLS 콜백 실행

  6. 엔트리포인트 호출

ADS는 확보하지 못해 이후 과정은 분석할 수 없었다.

3. 공격 기술 분석

3.1. 다단계 로딩 체인

세 유형 모두 기능을 한 파일에 담지 않고 여러 단계로 분리하였다.

유형

체인 구성

다음 단계 전달 방식

TYPE 1

드로퍼 → 로더 → 백도어

드로퍼가 로더·백도어를 파일로 드롭하고, 백도어 파일명과 복호화 키는 레지스트리 설정 데이터에 기록

TYPE 2

로더 → 다운로더 → 셸코드

로더가 다운로더의 DllMain을 호출하면서 AES 키와 암호화된 설정 데이터를 인자로 직접 전달

TYPE 3

로더 → ADS 페이로드

로더가 자기 자신의 ADS에서 페이로드와 복호화 키를 추출

단계 진행 조건

각 단계는 특정 입력이 갖춰졌을 때만 다음으로 넘어간다. 이러한 조건은 분석 방해와 표적 외 실행 차단 효과를 동시에 낸다.

단계

조건

TYPE 1 드로퍼 실행

34자(wide-char) 인자가 전달되어야 악성 로직 진입

TYPE 1 오버레이 추출

인자에서 파생한 키로 28바이트 헤더를 복호화한 뒤, 첫 DWORD가 나머지 6개 DWORD의 합과 일치해야 진행

TYPE 1 백도어 복호화

레지스트리에 기록된 설정 데이터가 있어야 키 획득 가능. 로더 바이너리에는 키가 존재하지 않음

TYPE 3 페이로드 복호화

자기 자신의 :kgb ADS에서 키와 IV를 읽어야 진행

오버레이는 28바이트 마커로 위치를 식별하며, 내부 데이터는 암호화와 LZ 압축이 함께 적용되어 있다. 인자 값이 정확하지 않으면 헤더 복호화 결과가 유효하지 않아 체크섬 검증에서 걸러진다. 따라서 인자를 모르는 상태에서는 내장된 로더와 백도어를 추출할 수 없다.

이 설계로 인하여 검체를 한 개만 확보해서는 전체 감염 체인을 복원할 수 없다. 실제로 본 분석에서도 TYPE 2의 셸코드와 TYPE 3의 ADS 데이터를 확보하지 못하여 최종 단계를 확인할 수 없었다.

메모리 실행

로더는 복호화한 페이로드를 파일로 생성하지 않고 자체 구현한 PE 로더로 실행한다. MZ·PE 시그니처 검증, 메모리 할당과 헤더·섹션 복사, 베이스 재배치, 임포트 테이블 해석, 섹션별 메모리 보호 속성 적용, TLS 콜백 실행, 엔트리포인트 호출 순으로 진행되며 LoadLibrary 계열 API를 거치지 않는다. 로드된 모듈이 프로세스의 모듈 목록에 나타나지 않으므로 모듈 열거 기반 점검으로는 식별되지 않는다.

3.2. 지속성 확보

확인된 지속성 기법은 모두 새로운 자동 실행 항목을 등록하는 대신, 윈도우가 부팅 시 정상적으로 수행하는 로딩 절차에 악성 DLL을 삽입하는 넣는 방식이다. 이로 인하여 자동 실행 항목 점검이나 서비스 목록 비교만으로는 식별이 어렵다.

빈 서비스 슬롯 하이재킹

TYPE 1 드로퍼는 새 서비스명을 생성하지 않는다. HKLM\Software\Microsoft\Windows NT\CurrentVersion\SvcHostnetsvcs 값에서 서비스 목록을 조회한 뒤, 각 이름에 대하여 HKLM\SYSTEM\CurrentControlSet\Services\<서비스명> 키 열기를 시도하여 실패한 이름만 수집한다. netsvcs 그룹에 이름은 등록되어 있으나 실제 서비스 키가 존재하지 않는 빈 슬롯이 대상이며, 수집된 목록에서 rand 함수 반환 값으로 하나를 선택한다.

선택된 이름으로 서비스를 생성하면서 ImagePath를 %SystemRoot%\system32\svchost.exe -k netsvcs로 지정하므로, 로더 DLL은 정상 svchost.exe 프로세스 안에서 로드된다. 프로세스명과 이미지 경로가 모두 정상이고 서비스명 역시 윈도우에 원래 등록되어 있는 이름이므로, 실행 주체만으로는 악성 여부를 판단할 수 없다.

여기에 복구 옵션을 설정하여 서비스가 비정상 종료되더라도 120초 후 자동으로 재시작되도록 하고, 실패 카운터는 24시간 주기로 초기화한다. 대응 과정에서 프로세스를 강제 종료해도 2분 뒤 다시 기동된다.

SSP 등록

TYPE 1 백도어는 서비스 하이재킹과 별개로 SSP(Security Support Provider) 등록을 통하여 또 하나의 지속성 경로를 확보한다. HKLM\SYSTEM\CurrentControlSet\Control\LsaSecurity Packages 값에 로더 파일명을 추가하면 부팅 시 lsass.exe가 해당 DLL을 자동으로 로드한다.

이때 레지스트리 API를 직접 호출하지 않고 System32의 정상 reg.exe를 실행하여 값을 재구성한다. 기존 항목을 64자 단위로 그대로 보존한 채 파일명만 목록에 덧붙이므로 기존 보안 패키지 구성이 손상되지 않으며, 레지스트리를 변경한 주체가 정상 시스템 도구로 기록된다.

lsass.exe에 로드된 백도어는 동작 모드 1로 진입한다. 결과적으로 서비스 경로와 SSP 경로가 서로를 보완하므로, 한쪽을 제거해도 다른 한쪽으로 감염이 유지된다.

3.3. 디스크 흔적 제거

실행 후 자기 삭제와 종료 시 복원

TYPE 1 백도어는 초기화 과정에서 자가 보호 루틴을 실행한다. 설정 데이터가 담긴 레지스트리 값을 삭제하고, 로더와 백도어 파일을 각각 메모리로 읽어 들인 뒤 원본 파일을 삭제한다. 이 시점부터 악성코드는 디스크에 존재하지 않는다.

이어서 콘솔 컨트롤 핸들러를 등록하여 시스템 종료 이벤트를 감시한다. 시스템이 정상 종료되면 메모리에 보관하던 로더와 백도어를 원래 경로에 다시 기록하고, 설정 데이터를 레지스트리에 복원한 뒤 SSP를 재등록한다.

결과적으로 파일은 시스템이 종료된 동안에만 디스크에 존재한다. 가동 중인 시스템을 대상으로 한 파일 스캔에는 포착되지 않으며, 복원되는 로더에는 매번 새로운 정크 데이터가 덧붙으므로 해시도 달라진다. 이 루틴은 동작 모드가 1, 2, 4, 5이고 설정 데이터의 자가 보호 플래그가 설정된 경우에만 실행된다.

파일이 아닌 저장 경로 활용

세 유형 모두 설정 데이터를 파일 시스템 대신 레지스트리나 NTFS ADS에 보관하며, TYPE 2와 TYPE 3은 실행될 페이로드 자체도 같은 방식으로 은닉한다.

유형

은닉 대상

은닉 위치

TYPE 1

설정 데이터(4,204바이트)

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersionUSB_Keyboard_<3자리> 값(REG_BINARY)

TYPE 1

설정 데이터(모드 3)

%LOCALAPPDATA%\Microsoft\Internet Explorer\brndlog.txt:loginfo ADS

TYPE 1

추가 모듈

설정에 지정된 PNG 파일 내부

TYPE 2

다운로더 본체

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts\GiddyupStda Bold

TYPE 2

설정 데이터

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts\GiddyupStda

TYPE 3

페이로드

로더 자기 자신의 :dat ADS

TYPE 3

복호화 키·IV

로더 자기 자신의 :kgb ADS

PNG 은닉의 경우 실제 PNG 시그니처를 갖춘 정상 이미지 파일에 모듈 데이터를 청크 단위로 넣어 두고, 백도어가 이를 읽어 32바이트 블록 단위 치환과 XOR로 복호화한다. 이미지 뷰어에서는 정상적으로 열리므로 파일 형식 검사만으로는 판별되지 않는다.

복호화 키 분리

TYPE 1과 TYPE 3은 복호화 키를 실행 파일 안에 두지 않고 외부에 분리하여, 실행 파일만 확보해서는 다음 단계를 복원할 수 없도록 설계하였다.

유형

분리된 요소

획득 경로

TYPE 1 드로퍼

오버레이 복호화 키

실행 시 전달되는 34자 인자. 헤더 체크섬 검증을 통과해야만 추출 진행

TYPE 1 로더

백도어 복호화 키

레지스트리 설정 데이터의 +0x5C0 영역. 바이너리에는 존재하지 않음

TYPE 3 로더

페이로드 복호화 키·IV

자기 자신의 :kgb ADS

특히 TYPE 1 드로퍼는 34자 인자가 없으면 악성 로직 자체가 실행되지 않으므로, 상위 유포 단계를 함께 확보하지 못한 상태에서는 샌드박스 자동 분석으로도 내부 페이로드를 얻을 수 없다.

메모리 실행

로더는 복호화한 백도어를 파일로 생성하지 않고 자체 구현한 PE 로더로 메모리에서 실행한다. 또한 백도어는 C&C 명령에 따라 추가 페이로드를 현재 프로세스 내에서 리플렉티브 방식으로 실행하거나(0x2028), explorer.exe에 인젝션하여 실행한다(0x2032). 두 경로 모두 디스크에 실행 파일을 남기지 않는다.

3.4. 실행 환경 파악 및 조건부 활성화

TYPE 1 백도어는 자신이 어디에 로드되었는지, 지금이 활동할 시점인지를 실행 시점에 판단한다. 동일한 바이너리라도 실행 환경과 설정에 따라 다르게 동작하므로, 한 번의 실행을 관측하는 것만으로는 전체 행위를 파악할 수 없다.

호스트 프로세스 기반 동작 모드 결정

백도어는 DllMain 실행 시 현재 프로세스명과 로드된 DLL명 길이를 확인하여 6개 동작 모드 중 하나로 진입한다. 모드에 따라 설정 데이터의 저장 위치, 자가 보호 수행 여부, 종료 명령 수신 시의 종료 범위가 모두 달라진다.

판별 결과

모드

특징

lsass.exe

1

SSP로 로드된 상태. 종료 명령 수신 시 메모리 버퍼만 해제

svchost.exe, DLL명 10자 이하

2

서비스 하이재킹으로 로드된 일반 경로

svchost.exe, DLL명 10자 초과

5

모드 2와 동일하나 설정에 기록하는 파일명에서 첫 글자를 제외

그 외 프로세스

4

인젝션 등 다른 경로로 로드된 상태

외부 로더가 컨텍스트를 직접 구성

0, 3

모드 3은 설정을 NTFS ADS에 저장. 종료 명령 수신 시 프로세스 자체를 종료

지정 시각까지의 잠복

설정 데이터에는 활성화 대기 시각이 VARIANT time 형식으로 기록된다. 백도어는 시스템의 현재 시각을 같은 형식으로 변환하여 비교하고, 지정 시각 이전이면 30초 간격으로 시각을 재확인하며 대기한다. 분석된 설정의 값은 2025년 2월 21일 10시 48분으로, 감염 즉시 활동을 시작하지 않고 지정된 시점부터 통신을 개시하는 구조다.

네트워크 및 환경 변화 감시

백도어는 통신에 실패하면 네트워크 가용 여부를 확인하고, 사용할 수 없는 상태이면 60초 간격으로 재확인하며 대기한다. 무의미한 접속 시도를 반복하지 않아 네트워크 계층의 이상 징후 노출을 줄인다.

또한 설정 데이터의 플래그에 따라 두 종류의 감시 스레드를 기동한다.

감시 대상

동작

논리 드라이브 구성

2초 간격으로 드라이브 목록을 조회하여 변화를 감지

터미널 세션

활성 세션 목록을 조회하여 변화를 감지

이동식 저장매체 연결이나 원격 접속 시작처럼 사용자 활동이 발생하는 시점을 포착하여 재접속의 계기로 삼는 구조다.

원격 접속 환경 탐지

드라이브 정보 조회 명령은 로컬 드라이브뿐 아니라 \\tsclient\<드라이브 문자> 경로의 존재 여부까지 확인한다. 이는 RDP 접속 시 클라이언트 측 드라이브가 리디렉션되는 경로로, 감염 시스템에 원격 접속한 사용자의 로컬 저장소를 식별하기 위한 것이다. 망 분리나 원격 근무 환경에서 감염 시스템을 경유하여 접속 시스템 쪽으로 확산할 대상을 파악하는 데 활용될 수 있다.

3.5. C&C 통신 프로토콜

패킷 구조와 암호화 계층

TYPE 1 통신 데이터는 12바이트 헤더와 가변 길이 페이로드로 구성된다. 헤더와 페이로드는 각각 ChaCha20으로 암호화된 뒤 직전 바이트 값과 XOR하는 연산이 추가로 적용되고, Base64로 인코딩되어 파라미터 문자열에 연결된 후 POST 본문으로 전송된다.

오프셋

크기

항목

+0

2

랜덤 값

+2

2

명령 ID

+4

4

완료 플래그

+8

4

페이로드 크기

세션 개시와 서버 검증

백도어는 접속마다 1000~9999 범위의 난수를 생성하여 세션 식별자로 사용한다. 첫 요청으로 4바이트 난수를 보내면 서버는 이 식별자를 4자리 문자열로 응답해야 하며, 값이 일치하지 않으면 해당 서버를 사용하지 않는다.

클라이언트가 서버를 검증하는 구조이므로, 공격자가 심어 둔 스크립트가 동작하지 않는 서버에서는 후속 통신이 발생하지 않는다. 분석용으로 구성한 모의 서버로는 실제 명령 수신 단계까지 도달할 수 없다.

명령 수신 루프

세션이 성립하면 폴링과 명령 처리를 반복한다. 폴링 요청에는 세션 식별자에 10000을 더한 값과 전용 명령 ID를 사용하고, 명령 실행 결과는 원래 식별자로 전송한다. 요청 성격에 따라 식별자를 달리 사용하므로, 트래픽만으로는 폴링과 결과 전송을 구분하기 어렵다.

단계

사용 값

폴링 요청

세션 식별자 + 10000, 명령 ID 0x2047

명령 수신

원래 세션 식별자

결과 전송

원래 세션 식별자, 응답 ID 0x2040

세션 중 키 교체와 파라미터 제어

통신 중에도 다음과 같이 프로토콜 요소를 바꿀 수 있다.

명령

동작

0x2020

새 32바이트 키를 생성하여 서버에 알리고, 송신용과 수신용 ChaCha20 컨텍스트를 각각 교체

0x2019

설정 데이터 전체를 교체. 단 백도어 복호화 키 영역은 보존

0x2018 / 0x2024

재접속 대기 시간을 명령 인자 값 또는 설정 기본값으로 변경

키가 교체되면 세션 중간부터 수집한 트래픽은 이전 키로 복호화할 수 없다. 대기 시간 제어는 통신 빈도를 상황에 맞게 조절하여 트래픽 패턴 기반 탐지를 회피하는 데 쓰인다.

대용량 데이터 처리

크기가 큰 페이로드는 분할하여 주고받는다. 백도어는 헤더의 크기 정보를 기준으로 수신량이 전체에 도달할 때까지 요청을 반복하고, TYPE 2 다운로더 역시 종료 플래그와 누적 수신량을 대조하며 분할 수신한다. 한 번의 요청에 담기는 데이터가 작아 개별 요청만으로는 이상 징후로 판단하기 어렵다.

3.6. 기능 확장과 원격 제어

명령 체계

TYPE 1 백도어는 30개의 명령 핸들러를 갖추고 있으며, 기능은 다음 범주로 나뉜다.

범주

내용

정보 수집

시스템 정보, 로컬 및 RDP 리디렉션 드라이브 정보, 로더·백도어 식별 정보 조회

파일 조작

파일 및 디렉터리 조회·조작, 파일 송수신

명령 실행

설정에 지정된 셸을 통한 명령 실행 및 결과 회수

페이로드 실행

수신한 실행 파일을 현재 프로세스에서 실행, 은닉 모듈을 다른 프로세스에 인젝션

설정 관리

설정 전체 교체, 암호 키 교체, 재접속 대기 시간 변경, 활성화 대기 시각 설정

세션 제어

통신 루프 종료 및 모드별 정리

셸 명령은 설정 데이터에 기록된 셸 경로를 사용하여 /c "<명령> > <임시 파일> 2>&1" 형태로 실행하고, 임시 파일이 생성될 디렉터리 역시 설정으로 지정할 수 있다. 지정되지 않은 경우 시스템 임시 경로를 사용한다.

기능 확장 경로

본체에는 최소한의 기능만 두고, 실제 공격 기능은 필요한 시점에 외부에서 가져와 메모리에서 실행한다. 확인된 확장 경로는 세 가지다.

경로

획득 위치

실행 방식

추가 모듈

설정에 지정된 PNG 파일 내부

복호화 후 explorer.exe에 인젝션. 상시 반복 수행되며 명령으로도 실행 가능

수신 페이로드

C&C에서 분할 수신

현재 프로세스 내에서 리플렉티브 방식으로 실행

셸코드

C&C에서 분할 수신(TYPE 2)

파이프 이름과 설정 정보를 함께 전달받아 실행

이 구조로 인하여 로더나 백도어를 확보하더라도 최종적으로 어떤 행위가 수행되었는지는 알 수 없다. 확장 모듈은 디스크에 실행 파일로 남지 않으며, PNG 은닉 모듈의 경우 원본 파일이 정상 이미지로 열리므로 파일 형식 검사로도 판별되지 않는다.

수집 정보

C&C 접속 시 전송되는 시스템 정보에는 컴퓨터명, 사용자명, 네트워크 어댑터의 IP 주소, OS 제품명, 코드 페이지, 현재 동작 모드, 컴퓨터명과 CPU 모델명을 결합하여 산출한 CRC32 식별값이 포함된다. 식별값은 감염 시스템을 구분하는 용도로 쓰이며, 동작 모드가 함께 전송되므로 공격자는 해당 시스템에서 악성코드가 어느 경로로 로드되었는지도 파악할 수 있다.

3.7. 위장

정상 프로그램·라이브러리 위장

확인된 검체는 처음부터 악성 코드만으로 작성된 것이 아니라, 규모 있는 정상 코드 베이스 위에 악성 로직을 덧붙인 형태다. 정적 분석 시 대부분의 코드가 정상 라이브러리로 식별되어 악성 부분이 가려진다.

검체

기반 코드

악성 로직 진입점

smss.exe(드로퍼)

MFC 다이얼로그 애플리케이션(내부 프로젝트명 shayTamir)

34자 인자가 전달된 경우에만 동작. 그 외에는 정상 프로그램처럼 실행

edgsvc.dll(로더)

Wave Function Collapse 알고리즘 C++ 라이브러리

서비스 진입점

ipbootp.dll(로더)

SQLite 라이브러리(sqlite3dll.dll)

DllMain에서 스레드 생성

파일명과 경로

드롭되는 파일은 C:\Windows\System32 경로에 생성되며, 파일명은 자리별로 지정된 알파벳 집합에서 세 글자를 무작위로 선택하고 svc 또는 mgr를 결합하여 만든다. edgsvc.dll, gsosvc.dat처럼 정상 시스템 파일과 유사한 이름이 나오도록 문자 집합이 선정되어 있으며, 실행할 때마다 이름이 바뀌므로 파일명 기반 탐지 규칙으로는 대응할 수 없다. 드로퍼 자체도 정상 시스템 프로세스명인 smss.exe를 사용한다.

코드 서명

TYPE 2 로더에는 국내 업체인 ES-Computing 명의의 코드 서명이 적용되어 있다. 유효기간이 2020년 5월 15일로 만료된 인증서이지만, 서명 존재 자체가 파일 속성 확인 단계에서 신뢰를 유도한다.

레지스트리 값 이름

설정 데이터를 저장하는 값 이름은 주변 항목과 구분되지 않도록 없도록 선택된다. TYPE 1은 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion 아래에 USB_Keyboard_547처럼 하드웨어 관련 항목으로 보이는 이름을 사용하고, TYPE 2는 폰트 등록 정보가 모여 있는 Fonts 키에 GiddyupStda Bold라는 실제 서체명 형태의 값을 만든다.

네트워크 트래픽

C&C 통신은 검색 엔진 요청과 유사한 형태를 띤다. TYPE 1이 사용하는 ei, ie, oq 파라미터는 구글 검색 URL에서 쓰이는 이름과 동일하며, 여기에 hash, lang을 더하여 POST 본문을 구성한다. 요청 시 User-Agent도 일반 브라우저 문자열로 설정한다.

TYPE 2는 요청이 아니라 응답 쪽에서 위장한다. C&C 서버는 응답 본문을 <!DOCTYPE html>로 시작하도록 구성하고 다운로더는 이 문자열을 확인한 뒤 나머지를 복호화하므로, 응답만 관찰하면 평범한 HTML 페이지로 보인다.

상수 위장

TYPE 1 드로퍼와 로더의 API 이름 복호화에 사용되는 XOR 키 테이블 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05 00 03 8206 09 2A 86 48 86 F7 0D 01 01 01 구간은 DER로 인코딩된 rsaEncryption OID의 바이트열과 일치한다. 암호 관련 표준 상수를 본래 용도와 무관하게 키로 사용한 것으로, 상수 기반 시그니처 탐지를 어렵게 한다.

분석 방해

기법

내용

문자열 암호화

민감 문자열을 ChaCha20 또는 AES-CBC-128로 암호화. 문자열 기반 정적 분석과 시그니처 탐지 회피

API 이름 암호화 및 동적 해석

API 이름을 암호화하여 두고 실행 시점에 복호화·해석. Import 목록만으로 기능 추정 불가

순차 의존 복호화 루틴

TYPE 1 로더의 API 이름 복호화 함수는 분기와 호출 없이 약 8,960개 명령으로 구성되며, 이전 연산 결과가 다음 바이트 복호화에 영향을 준다. 부분 실행이나 중간부터 재현하는 것이 불가능

명령줄 게이트

34자 인자가 없으면 악성 로직 미실행

바이너리 패딩

로더에 64MiB ~ 80MiB의 정크 데이터를 추가. 해시 기반 탐지를 무력화하고 파일 크기 제한이 있는 자동 분석·전송 경로를 회피

3.8. 국내 정상 웹서버 침해

본 캠페인은 악성코드 유포와 C&C 운영 모두에 침해한 국내 정상 웹사이트를 활용한다. 공격자는 별도의 인프라를 구축하는 대신 이미 신뢰받는 국내 서버를 확보하여, 워터링홀 유포 지점과 명령 수신 지점으로 함께 사용한다.

4. 대응 방안

본 캠페인은 사용자 조작 없이 웹사이트 접속만으로 감염되고, 감염 이후에는 정상 시스템 구성요소로 위장한다. 따라서 대응은 취약 컴포넌트를 관리하여 진입 자체를 차단하는 것과 이미 감염된 시스템을 식별하는 방법으로 구성된다.

4.1. 소프트웨어 관리

보안 소프트웨어의 취약점을 악용하는 공격은 해당 보안 소프트웨어를 설치 및 사용 중인 상태로 침해된 정상 웹사이트에 접속하는 것만으로도 공격의 대상이 될 수 있다.

특정 웹 서비스를 이용할 때 요구되는 보안 프로그램은 최신 버전으로 주기적으로 업데이트하거나, 자주 방문하지 않는 웹 서비스라면 이용 시 잠시 설치하여 사용한 후 [제어판] - [프로그램] - [프로그램 및 기능] 메뉴를 통해 제거하는 것을 권장한다.

다만 0-day 취약점은 최신 버전에서도 악용될 수 있으므로, 상시 설치가 필요하지 않은 프로그램은 제거해 공격 표면을 줄이는 것이 근본적인 대책이다.

4.2. 호스트 점검 항목

레지스트리

점검 대상

판단 근거

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion 아래 USB_Keyboard_<숫자 3자리>

정상 윈도우 구성에 존재하지 않는 값이다. REG_BINARY 형식에 크기가 4,204바이트이면 TYPE 1 설정 데이터로 볼 수 있다.

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts에 수십 KB 이상의 바이너리 값

Fonts 키에는 통상 폰트 파일명 문자열만 저장된다. 수십 KB 이상의 바이너리 값이 있으면 TYPE 2 다운로더 또는 설정 데이터다.

HKLM\SYSTEM\CurrentControlSet\Control\LsaSecurity Packages

목록에 kerberos, msv1_0, schannel, wdigest, tspkg, pku2u, cloudap 등 기본 항목 외의 이름이 있으면 해당 DLL의 경로와 서명을 확인한다. 인증 관련 제품이 정상적으로 SSP를 추가하는 경우도 있으므로 이름만으로 단정하지 않는다.

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHostnetsvcs 목록과 실제 서비스 키 대조

드로퍼는 netsvcs 목록에 이름은 있으나 서비스 키가 없던 빈 슬롯에 서비스를 새로 생성한다. 따라서 원래 존재하지 않아야 할 서비스가 등록된 상태가 된다.

파일

점검 대상

판단 근거

C:\Windows\System32<3글자>svc.dll, <3글자>mgr.dll, 그리고 같은 규칙을 따르는 <3글자>svc.dat·<3글자>mgr.dat

드로퍼가 생성하는 파일명 규칙이다. 첫 글자는 [abcdefgmnpsw], 둘째는 [abcdefhlmnprs], 셋째는 [acefghinoprst] 집합에서 선택되며 한 파일 안에서 서로 겹치지 않는다. 파일명 생성 루틴이 로더와 백도어에 각각 호출되므로 두 파일의 세 글자는 서로 다르다.

System32 내 크기가 64MiB를 초과하는 DLL

이 크기의 정상 시스템 DLL은 사실상 없다. 로더에 추가되는 64MiB ~ 80MiB 정크 데이터로 인해 발생하며, 단독으로도 신뢰도가 높은 지표다.

%LOCALAPPDATA%\Microsoft\Internet Explorer\brndlog.txt의 "loginfo" ADS

TYPE 1 동작 모드 3의 설정 데이터 저장 위치다.

DLL의 :dat, :kgb ADS

TYPE 3의 페이로드와 복호화 키 저장 위치다. 로더가 배치되는 경로는 악성코드별로 다를 수 있으므로 특정 디렉터리로 한정하지 않는다.

ADS는 탐색기나 일반 파일 목록에 나타나지 않으므로 dir /r 또는 전용 도구로 별도 확인해야 한다.

프로세스 행위

점검 대상

판단 근거

lsass.exe의 외부 HTTP/HTTPS 통신

lsass.exe는 임의 웹 서버로 요청을 보내지 않는다.

svchost.exe의 외부 HTTP/HTTPS 통신 중 4.3절 본문 패턴과 일치하는 요청

svchost.exe는 윈도우 업데이트, BITS, 배달 최적화 등으로 정상적으로도 외부 통신을 대량 수행한다. 프로세스만으로는 판별할 수 없으므로 반드시 본문 패턴과 조합해 판단한다.

reg.exeSecurity Packages 값을 수정하는 행위

SSP 등록·해제 시 System32의 정상 reg.exe를 실행한다. 부모 프로세스가 svchost.exelsass.exe이면 특히 의심스럽다.

explorer.exe를 대상으로 한 OpenProcessVirtualAllocExWriteProcessMemoryRtlCreateUserThread 호출

추가 모듈 인젝션 시퀀스다.

svchost.execmd.exe /c "<명령> > <임시 파일> 2>&1"을 실행하는 행위

원격 명령 실행 기능의 동작 형태다.

서비스가 비정상 종료된 뒤 120초 간격으로 반복 재시작되는 현상

드로퍼가 설정한 복구 옵션의 동작이다.

\\.\pipe\ 아래 20자 이름의 네임드 파이프

TYPE 2 다운로더가 생성한다. 이름은 실행마다 달라지지만 문자열 D9hWnVEqdgzJ673B8euS의 문자 20개를 재배열한 것이므로 구성 문자 집합이 동일하다.

4.3. 네트워크 탐지 항목

유형

탐지 지점

TYPE 1

POST 본문에 고정 문자열 lang=T3F56E5UJH0JC3D4가 포함된다. 단일 지표로도 신뢰도가 높다.

TYPE 1

본문이 hash=<1000~9999>&lang=<고정값>&ei=<50~255>&ie=<Base64> 또는 hash=…&lang=…&oq=<Base64> 형태를 갖는다.

TYPE 1

최초 요청에 대한 응답이 4자리 숫자 문자열이다. 이후 트래픽은 모두 Base64 본문을 갖는 POST다.

TYPE 2

본문이 type=<16진수>&data=8Rvi4-UPMQvFgjMJ3cZF 형태다. data 값이 고정이므로 활성 확인 요청을 특정할 수 있다.

TYPE 2

본문이 type=cisco 또는 type=article&data=<Base64> 형태다.

TYPE 2

응답 본문이 <!DOCTYPE html>로 시작하지만 그 뒤가 HTML 태그가 아닌 Base64 문자열이다.

TYPE 1

User-Agent가 Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36으로 고정된다. Chrome 61은 2017년 버전이므로 현행 환경에서 이 문자열이 관측되면 그 자체로 이상 징후다.

공통

국내 정상 도메인의 .asp 또는 .php 경로로 장시간에 걸쳐 POST 요청이 반복된다. 정상 트래픽과 겹치는 범위가 넓어 단독 지표로는 적합하지 않으며 위 항목과 조합해 판단해야 한다.

위 항목이 확인된 시스템에서는 임의로 파일이나 레지스트리 항목을 삭제하지 않는다. 본 악성코드는 시스템이 정상 종료될 때 삭제된 로더·백도어 파일과 설정 데이터, Security Packages 항목을 스스로 복원하며, 하이재킹된 서비스에는 복구 옵션이 설정되어 있어 프로세스를 종료해도 120초 후 재기동된다. 따라서 일부 항목만 제거하면 조치가 무효화되고, 제거가 완료된 것으로 오판할 수 있다.

감염이 확인되면 해당 시스템을 네트워크에서 분리하고, 재부팅하기 전에 메모리 이미지를 확보한 뒤 관계 기관 또는 보안 담당자에게 통보한다.


5. 마치며

본 보고서는 국내 정상 웹사이트를 침해해 악성코드를 유포한 워터링홀 공격 사례를 분석하였다.

공격자는 레지스트리, ADS와 같은 정상 Windows 기능을 이용하여 악성코드의 지속성을 확보하고, 악성코드의 흔적을 지우는 전략을 사용하였다. 또한 정상 웹사이트를 침해하고 보안 프로그램의 취약점을 악용하여 워터링홀 공격을 시도하는 고도화된 공격 역량을 드러내었다.

무엇보다 본 사례는 취약한 보안 프로그램이 설치된 상태에서 악성 스크립트가 삽입된 웹사이트에 접속하기만 해도 감염이 성립할 수 있음을 보여준다. 이용자의 부주의를 전제하지 않는 공격이므로, 사용하지 않거나 사용 빈도가 낮은 소프트웨어를 제거해 공격 표면을 줄이고 설치된 소프트웨어를 최신 상태로 유지하는 것이 우선이다.

6. 부록

부록 A. MITRE ATT&CK

Tactic

ID

Name

Resource Development

T1584.004

Compromise Infrastructure: Server


T1588.003

Obtain Capabilities: Code Signing Certificates

Initial Access

T1189

Drive-by Compromise

Execution

T1203

Exploitation for Client Execution


T1059.003

Command and Scripting Interpreter: Windows Command Shell


T1569.002

System Services: Service Execution

Persistence

T1543.003

Create or Modify System Process: Windows Service


T1547.005

Boot or Logon Autostart Execution: Security Support Provider

Privilege Escalation

T1543.003

Create or Modify System Process: Windows Service


T1547.005

Boot or Logon Autostart Execution: Security Support Provider


T1134.002

Access Token Manipulation: Create Process with Token

Defense Evasion

T1027.001

Obfuscated Files or Information: Binary Padding


T1027.003

Obfuscated Files or Information: Steganography


T1027.013

Obfuscated Files or Information: Encrypted/Encoded File


T1140

Deobfuscate/Decode Files or Information


T1112

Modify Registry


T1480.001

Execution Guardrails: Environmental Keying


T1497.003

Virtualization/Sandbox Evasion: Time Based Evasion


T1564.004

Hide Artifacts: NTFS File Attributes


T1070.004

Indicator Removal: File Deletion


T1070.006

Indicator Removal: Timestomp


T1070.009

Indicator Removal: Clear Persistence


T1036.004

Masquerading: Masquerade Task or Service


T1036.005

Masquerading: Match Legitimate Resource Name or Location


T1036.008

Masquerading: Masquerade File Type


T1553.002

Subvert Trust Controls: Code Signing


T1055

Process Injection


T1620

Reflective Code Loading

Discovery

T1082

System Information Discovery


T1083

File and Directory Discovery


T1057

Process Discovery


T1033

System Owner/User Discovery


T1016

System Network Configuration Discovery


T1120

Peripheral Device Discovery


T1135

Network Share Discovery


T1046

Network Service Discovery

Collection

T1005

Data from Local System


T1560.002

Archive Collected Data: Archive via Library

Command and Control

T1071.001

Application Layer Protocol: Web Protocols


T1105

Ingress Tool Transfer


T1008

Fallback Channels


T1132.001

Data Encoding: Standard Encoding


T1573.001

Encrypted Channel: Symmetric Cryptography


T1001.003

Data Obfuscation: Protocol or Service Impersonation

Exfiltration

T1041

Exfiltration Over C2 Channel


부록 B. Yara Rule




부록 C. 명령 코드

명령 코드

행위

0x2003

시스템 정보 전송

0x2004

드라이브 정보 수집

0x2005

파일 목록 조회

0x2006

명령 실행

0x2007

파일·디렉터리 탈취

0x2008

파일 다운로드

0x2009

패딩 파일 다운로드

0x2010

프로세스 실행

0x2011

사용자 세션 프로세스 실행

0x2012

프로세스 정보 수집

0x2013

프로세스 종료

0x2014

파일 완전 삭제

0x2015

TCP 연결 검사

0x2016

타임스탬프 변조

0x2017

작업 디렉터리 변경

0x2018

재접속 대기 시간 변경

0x2019

설정 변경

0x2020

ChaCha20 키 교체

0x2021

디렉터리 통계 수집

0x2022

지정 드라이브 정보 조회

0x2023

활성화 시각 설정

0x2024

기본 재접속 시간 복원

0x2025

백도어 종료·정리

0x2026

악성 구성 정보 전송

0x2027

Heartbeat

0x2028

Reflective PE 실행

0x2029

파일 복사

0x2030

파일 이동

0x2031

일반 파일 삭제

0x2032

explorer.exe 인젝션

エンキホワイトハット

エンキホワイトハット

ENKI ホワイトハット
ENKI ホワイトハット

オフェンシブセキュリティの専門企業として、攻撃者の視点から次元の異なるセキュリティを提示します。

オフェンシブセキュリティの専門企業として、攻撃者の視点から次元の異なるセキュリティを提示します。

隙のないセキュリティ設計の始まり、NO.1ホワイトハッカーのノウハウから

インシデント発生前、
今すぐ備えましょう

隙のないセキュリティ設計の始まり、
No.1ホワイトハッカーのノウハウから

インシデント発生前、
今すぐ備えましょう

隙のないセキュリティ設計の始まり、
No.1ホワイトハッカーのノウハウから

インシデント発生前、
今すぐ備えましょう

購読する

コンテンツが役に立ったら?
エンキーレターを購読しましょう!

Copyright © 2025. ENKI WhiteHat Co., Ltd. All rights reserved.

Copyright © 2025. ENKI WhiteHat Co., Ltd. All rights reserved.

Copyright © 2025. ENKI WhiteHat Co., Ltd. All rights reserved.