랜섬웨어 분석 보고서

Mallox 랜섬웨어 분석 보고서

geonwoo9643 2026. 2. 9. 04:07

1. 개요 (Overview)


1.1 분석 배경

Mallox 랜섬웨어는 2021년에 처음 등장한 RaaS(Ransomware-as-a-Service) 그룹으로, 초기에는 ChaCha20 기반 암호화를 사용했으나 최신 버전에서는 AES-256-GCM 기반 암호화 구조로 변경되었습니다. AES-128 키는 고정 하드코딩 값이 아니라 ECDH 결과에서 파생되는 세션 기반 키입니다. GCM Nonce 길이는 구현에 따라 달라질 수 있으며, 본 샘플에서는 8바이트를 사용했습니다. 암호화 체인은 다음과 같이 구성됩니다:

  • X25519(ECDH)를 통해 공유 비밀 생성
  • SHA-256을 통해 키 파생
  • 파생된 키를 기반으로 AES-128-CTR 키 래핑 수행
  • 파일 데이터 암호화에 사용되는 AES-256-GCM

1.2 핵심 요약

  • 암호화 체인 : X25519 (ECDH) → SHA-256 (Key Derivation) → AES-128-CTR (per-file key wrapping) → AES-256-GCM (파일 암호화)
  • 메모리 포렌식 : ECDH 결과 또는 SHA-256 파생 키를 메모리에서 확보해야 복호화 가능
  • 푸터 구조 :
    • 108 bytes 고정
    • 40 bytes: AES-256 key + GCM nonce (AES-128-CTR로 암호화됨)
    • 16 bytes: AES-CTR IV
    • 기타 상수 및 매직

 
암호화 워크플로우

// Step 0: ECDH 기반 세션 키 도출
shared_secret = X25519(private_key, peer_public_key);
session_key = SHA256(shared_secret);     // 32 bytes
aes128_ctr_key = session_key[0:16];      // CTR wrapping key

// Step 1: ISAAC PRNG에서 per-file 난수 생성
v56 = isaac_extract(16);      // AES-128-CTR IV (16B)
v60 = isaac_extract(40);      // 32B AES-256 key + 8B GCM nonce

// Step 2: per-file key 래핑 (AES-128-CTR)
encrypted_metadata = AES128_CTR_Encrypt(v60, aes128_ctr_key, v56);

// Step 3: 파일 데이터 암호화 (AES-256-GCM)
file_ciphertext = AES256_GCM_Encrypt(file_data, key=v60[0:32], nonce=v60[32:40]);

// Step 4: Footer 구성
footer = magic + size + encrypted_metadata + v56 + const + const + magic2;

 

2. 식별 정보 (Identification)


항목
Malware Family Mallox Ransom (TargetCompany)
Filetype PE32+ (Windows 64-bit Executable)
Hash (SHA256) 06699c98ed2ef759b2434ac5777a2886b966c0ffa1c96c046f5cde77fe833784
Extension .mallab
Target Windows 기반 시스템
First Seen June 2021
Ransom Note "HOW TO RECOVER !!.TXT"

 

3. 분석 환경 및 도구 (Tools)


구분 도구명 (Tool) 용도 (Purpose)
정적 분석 IDA Pro AES-GCM/GHASH 구현 루틴 및 암호화 로직 분석
동적 분석 WinDbg 메모리 덤프 및 암호화 키 추출
행위 분석 Process Monitor 파일 I/O 및 암호화 행위 추적
암호 분석 Python + Pycryptodome AES-256-GCM 복호화 스크립트 개발
메모리 분석 메모리 포렌식 AES-128-CTR 키 추출

 

4. 암호화 기술 분석 (Technical Analysis)


4.1 전체 암호화 워크플로우

[실행 단계] 
1. 초기화 - X25519 키쌍 생성 (개인 키 32바이트) - 베이스 포인트 연산 수행 - ECDH shared secret 생성 - SHA-256(shared_secret) → 세션 키 도출 - 해당 세션 키를 AES-128-CTR key로 사용
↓ 
2. 파일 탐색 및 암호화 - 재귀적 디렉터리 탐색 - 파일 필터링 (.exe, .dll, .mallab 제외) - 파일별 ISAAC PRNG에서 랜덤 데이터 생성
↓ 
3. 파일별 암호화 수행 [ISAAC PRNG 출력] - v56 = 16바이트 (AES-128-CTR IV) - v60 = 40바이트 (AES-256 key 32B + GCM nonce 8B)
↓ 
[Step 1: AES-128-CTR로 v60 암호화] encrypted_metadata = AES128_CTR(v60, aes128_ctr_key, v56)
↓  
[Step 2: AES-256-GCM로 파일 암호화] ciphertext = AES256_GCM(file_data, v60[:32], v60[32:40])
↓ 
[Step 3: 푸터 구성 및 저장] footer = magic1(8B) + original_size(8B) + encrypted_metadata(40B) + v56(16B) + const1(16B) + const2(16B) + magic2(4B)
↓ Original Size : 파일 데이터 원본 길이 저장, 복호화 후 원본 길이만큼 잘라줘야 함
↓ Const1/Const2 : 실제로는 고정 상수 (의미 없는 자리 채움일 수 있음)
4. 파일명 변경 및 랜섬 노트 생성 - 원본.확장자 → 원본.확장자.mallab - HOW TO RECOVER !!.TXT 생성

 


4.2 키 생성 및 관리 (Key Generation)

4.2.1 하이브리드 암호화 구조

ISAAC PRNG 기반 per-file 키 생성

ISAAC PRNG (Indirection, Shift, Accumulate, Add, Count)

• 내부 상태: 2KB (256 × 32-bit words)
• 출력: 32-bit 정수 스트림
• 파일별 독립적인 난수 시퀀스 생성에 사용

Mallox는 ISAAC을 per-file AES-256 key 및
GCM nonce 생성에 사용한다.

※ ISAAC은 고속 PRNG이지만,
현대 CSPRNG(Cryptographically Secure PRNG)와
동일한 수준의 안전성이 보장되는 것은 아니다.
AES-128-CTR 키

용도: 푸터의 40바이트 메타데이터 암호화

특징: AES-128-CTR 키는 ECDH 결과에서 파생되며, 동일 감염 인스턴스에서 생성된 파일들에 대해 공통으로 사용될 수 있다.

 
중요: AES-128-CTR 키는 X25519(ECDH) 결과를 SHA-256으로 해시하여 동적으로 생성됩니다. 따라서 고정 마스터 키는 존재하지 않으며, 감염 인스턴스마다 키가 달라집니다.

 
4.2.2 키 체인 구조

원본 파일 
↓ 
[AES-256-GCM 암호화] 암호화된 파일 
↓ 
AES-256 키 (32바이트) + GCM nonce (8바이트) 
↓ 
[AES-128-CTR 암호화, master_key 사용] 암호화된 메타데이터 (40바이트, 푸터에 저장) 
↓ 
AES-128-CTR 키 (16바이트)

4.3 AES 암호화 알고리즘

4.3.1 AES-256-GCM 구조

알고리즘 특성
모드: GCM (Galois/Counter Mode)

키 길이: 32바이트 (256비트)

Nonce: 8바이트 (64비트)

인증: GHASH (Galois Hash)
GCM 모드 특징
CTR 암호화: 병렬 처리 가능

GHASH 인증: 데이터 무결성 보장

AEAD: Authenticated Encryption with Associated Data

 
4.3.2 AES-128-CTR 키 래핑

// AES-128-CTR
// 16바이트 IV: isaac_extract(16) 
// 16바이트, 파일별 독립 Mode: CTR (Counter Mode) 
// CTR 모드 동작 Counter = IV + 0 C[i] = P[i] ⊕ AES_Encrypt(Counter + i, Key) 
// 메타데이터 암호화 plaintext = AES_256_key (32B) + GCM_nonce (8B) 
// 40바이트 ciphertext = AES128_CTR_Encrypt(plaintext, master_key, IV)

4.4 파일 처리 아키텍처

4.4.1 암호화된 파일 구조

Mallox는 파일 끝에 108바이트 고정 크기 푸터를 추가합니다.

영역 크기 설명
암호화된 데이터 원본 크기 AES-256-GCM으로 암호화된 파일 내용
Footer (108 bytes)    
└─ Offset 0-7 8 bytes Magic: 0201020100000000
└─ Offset 8-15 8 bytes 원본 파일 크기 (Little-endian)
└─ Offset 16-55 40 bytes 암호화된 메타데이터 (AES-128-CTR)- AES-256 key (32B) + GCM nonce (8B)
└─ Offset 56-71 16 bytes AES-128-CTR IV
└─ Offset 72-87 16 bytes Const1 (고정값)
└─ Offset 88-103 16 bytes Const2 (고정값)
└─ Offset 104-107 4 bytes Magic: 00000000


4.4.2 실제 푸터 예시

Size: 49152 bytes (0x0000000000c00000) 
Encrypted Metadata: 
6047e0e6ed1e5281b41f855c68888f2e... // 40 bytes AES-CTR IV: 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // 16 bytes Const1: 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // 16 bytes Const2: 
00000000000000000000000000000000 // 16 bytes Magic2: 00000000

4.5 정적 분석

WinMain 함수

  • 러시아/CIS 국가 언어 검사 (실행 제외)

 

  • 뮤텍스 생성 (중복 실행 방지)

 

  • 고성능 전원 모드 설정 (암호화 속도 최적화)

 

  • 권한 상승

 

  • 첫 번째 작업 스레드 생성 (복구 방지/섀도우 카피 삭제)

 

  • 랜섬노트 내용

 

  • 두 번째 작업 스레드 생성 (방어 도구 제거)

 

  • NtQueryObject API 동적 로딩

 

  • 시스템 종료 차단


암호화 초기화 및 시작

 

  • 명령줄 인자 파싱

옵션 의미 예시
-l 파일 잠금 목록 파일 리스트
-d 복호화 모드 복호화 실행
-p 경로 리스트 파일 paths.txt
-path 특정 경로 지정 C:\Users
-queue 숫자 파라미터 4 (스레드 개수)

 

  • 난수 소스 수집 (QPC, ThreadID, PID, TSC)

 

  • 난수 생성기 초기화 (CryptGenRandom)

 

  • Mersenne Twister 시드 설정 및 상태 배열 초기화

 

  • 초기 상수 배열 초기화 (X25519 ECDH 2단계 파라미터용)

 

  • X25519 베이스포인트 및 추가 상수 초기화 (ECDH 키 파생용)

 

  • 컴퓨터 이름 수집 (ID 생성용)

 

  • Windows 디렉터리 생성 시간 수집

 

  • 볼륨 시리얼 번호 수집

 

  • 시스템 정보 결합

 

  • CPU ID 수집

 

  • SHA-256 초기 해시값 설정

 

  • SHA-256 해시 (시스템 정보)

 

  • 개인 키 생성 (32바이트)

 

  • X25519 ECDH 3단계 연산 (개인 키, 베이스 포인트)

 

  • SHA-256 초기 상수 재설정

 

  • SHA-256 (ECDH 결과) → 최종 마스터 키 생성 (32바이트)

 

  • 최종 키 생성

 

  • 볼륨 열거 및 마운트

 

  • FindFirstFileExW 지원 여부 테스트

 

  • 고유 ID 생성 (랜섬노트용)


파일 암호화

 

  • I/O Completion 포트 생성 (멀티스레드 암호화)

 

  • 워커 스레드 생성 (파일 암호화 처리)

 

  • 모든 볼륨 열거

 

  • 숨겨진 볼륨 마운트 (복구 방지)

 

  • 모든 논리 드라이브 스캔


드라이브별 암호화 스레드 생성

 

  • 디렉터리 재귀 탐색 및 암호화 대상 큐 추가

 

  • 드라이브 타입 확인 (로컬/네트워크)

 

  • 제외 디렉터리 검사

제외 디렉터리 목록

msocache, $windows.~ws, system volume information, intel, appdata, perflogs, programdata, 
google, application data, tor browser, boot, $windows.~bt, mozilla, boot, windows.old,
Windows Microsoft.NET, WindowsPowerShell, Windows NT, Windows, Common Files,
Microsoft Security Client, Internet Explorer, Reference, Assemblies, Windows Defender,
Microsoft ASP.NET, Core Runtime, Package, Store, Microsoft Help Viewer, Microsoft MPI,
Windows Kits, Microsoft.NET, Windows Mail, Microsoft Security Client, Package Store,
Microsoft Analysis Services, Windows Portable Devices, Windows Photo Viewer, Windows Sidebar

 

  • 화이트리스트 확장자 검사

암호화 대상 확장자 목록

.msstyles, .icl, .idx, .avast, .rtp, .mallox, .sys, .nomedia, .dll, .hta, .cur, .lock, .cpl,
.Globeimposter-Alpha865qqz, .ics, .hlp, .com, .spl, .msi, .key, .mpa, .rom, .drv, .bat, .386,
.adv, .diangcab, .mod, .scr, .theme, .ocx, .prf, .cab, .diagcfg, .msu, .cmd, .ico, .msc, .ani,
.icns, .diagpkg, .deskthemepackm, .wpx, .msp, .bin, .themepack, .shs, .nls, .exe, .lnk, .ps1, 
.mallab

 

  • 블랙리스트 파일명 검사

제외 파일 목록

desktop.ini, ntuser.dat, thumbs.db, iconcache.db, ntuser.ini, ntldr, bootfont.bin, 
ntuser.dat.log, bootsect.bak, boot.ini, autorun.inf, debugLog.txt, TargetInfo.txt

 

  • 암호화 작업 큐에 추가

 

  • 랜섬노트 생성


  • 암호화 작업 큐 추가


  • 랜섬노트 생성

 

  • 마스터 키 메모리 삭제

 

  • 네트워크 공유 스레드 강제 종료


  • 감염 정보 수집 (HDD 사용 용량, 시스템 정보) 및 C2 전송 후, 로컬 백업

 

  • Http Request 함수


  • 파일/디렉터리 존재 여부 확인

 

  • 관리자 권한 체크

 

  • 명령줄 재구성 (UAC 재실행 준비)

 

  • UAC 재실행 (권한 없을 경우)

 

  • 에러 메시지 (”File not found OR Invalid argument”)

 

  • 잘못된 인자 팝업으로 표시

 

5. 복호화 기술 분석 (Decryption Strategy)


5.1 복호화 가능성 분석

5.1.1 하이브리드 암호화 복호화 가능 원리

복호화를 위한 키 체인: 
1. ECDH shared secret
2. SHA-256 파생 세션 키 (AES-128-CTR 키)
3. AES-128-CTR로 푸터 복호화
4. per-file AES-256 key + nonce 획득
5. AES-256-GCM 복호화
추출 성공 요인: 
- AES-128-CTR 키는 모든 파일에 공통 사용
- 메모리 덤프에서 키 획득 가능 
- ISAAC PRNG 상태 복구 불필요 (푸터에 암호화된 형태로 저장)


5.1.2 복호화 가능 시나리오

시나리오 1: 메모리 포렌식
방법: 암호화 진행 중 메모리 덤프

대상: AES-128-CTR 키 (16바이트)

성공 확률: 높음 (랜섬웨어 프로세스 메모리에 상주)

시나리오 2: 바이너리 추출
방법: 랜섬웨어 바이너리 정적 분석

대상: ECDH 유도 값

성공 확률: 중간 (난독화 또는 동적 생성 가능)

5.2 AES-128 마스터 키 복구 메커니즘

5.2.1 메모리 포렌식 키 추출

// 메모리 덤프 파일 
// 키 검증 방법 
1. 테스트 파일의 푸터에서 암호화된 메타데이터 추출 
2. 추출한 키로 AES-128-CTR 복호화 시도 
3. 결과가 32바이트 + 8바이트 구조인지 확인 
4. 추출한 AES-256 키로 파일 복호화 
5. 매직 바이트 검증

5.3 자동화 복호화 스크립트 개발

5.3.1 복호화 체인

[ key.json ] 
↓ 
AES-128-CTR key 
↓ 
┌──────────────────────────────┐ 
│  footer encrypted_metadata   │ 
│         (40 bytes)           │ 
└──────────────────────────────┘ 
↓ 
AES-128-CTR 복호화 
↓ 
┌──────────────────────────────┐ 
│  AES-256 file key (32 bytes) │ 
│      GCM nonce (8 bytes)     │ 
└──────────────────────────────┘ 
↓ 
AES-256-GCM 
↓ 
[     원본 파일 데이터 복원      ]

 
5.3.2 핵심 복호화 로직

 

1. 키 로드

def load_keys(json_path): 
"""Load decryption keys from JSON file""" 
	with open(json_path, 'r') as f: 
keys = json.load(f) 
aes128_key = bytes.fromhex(keys['aes128_ctr_key']) 
if len(aes128_key) != 16: 
	raise ValueError(f"Invalid AES-128 key length") 
return aes128_key

 
2. 푸터 파싱

# 파일 끝 108바이트 읽기 
footer = data[-108:] 
ciphertext = data[:-108] 
# 푸터 구조 파싱 
magic1 = footer[0:8] 
original_size = struct.unpack('<Q', footer[8:16])[0] 
encrypted_metadata = footer[16:56] 
# 40 bytes 
aes_ctr_iv = footer[56:72] 
# 16 bytes 
const1 = footer[72:88] 
const2 = footer[88:104] 
magic2 = footer[104:108]


3. AES-128-CTR 복호화 (메타데이터 언래핑)

# AES-128-CTR 초기화 
ctr = Counter.new(128, initial_value=int.from_bytes(aes_ctr_iv, 'big')) 
cipher = AES.new(aes128_key, AES.MODE_CTR, counter=ctr) 
# 메타데이터 복호화 
decrypted_metadata = cipher.decrypt(encrypted_metadata) 
# AES-256 키와 GCM nonce 추출 
aes256_key = decrypted_metadata[:32] gcm_nonce = decrypted_metadata[32:40]


4. AES-256-GCM 복호화 (파일 데이터)

# AES-256-GCM 초기화 
cipher_text = AES.new(aes256_key, AES.MODE_GCM, nonce=gcm_nonce) 
# 태그 추출
ciphertext, tag = ciphertext[:-16], ciphertext[-16:]
# 파일 데이터 복호화 
plaintext = cipher.decrypt_and_verify(ciphertext, tag)
# 원본 크기로 자르기 
plaintext = plaintext[:original_size]

5.4 무결성 검증

5.4.1 매직 바이트 테이블

파일 유형 매직 넘버 (Hex) 설명
PNG 89 50 4E 47 0D 0A 1A 0A PNG 이미지
JPG/JPEG FF D8 FF E0/E1/DB JPEG 이미지
PDF 25 50 44 46 PDF 문서
ZIP 50 4B 03 04 ZIP 압축 파일
DOCX/XLSX 50 4B 03 04 Office Open XML (ZIP 기반)

 

6. 요약 및 결론 (Conclusion)


6.1 최종 평가

Mallox 랜섬웨어 최신 버전은 AES-256-GCM + AES-128-CTR 하이브리드 암호화 구조를 가지고 있으며, ISAAC PRNG 기반 파일별 독립 키 생성을 통한 암호화를 구현합니다. 메모리 포렌식을 통해 ECDH 연산 결과 또는 SHA-256 파생 세션 키를 확보하여 AES-128-CTR 레이어를 해제하고, per-file AES-256-GCM 키를 추출하여 복호화에 성공했습니다. 4개 테스트 파일 모두 매직 바이트가 검증되었으며, 4개 테스트 파일 모두 매직 바이트/파일 포맷이 정상 복원됨을 확인하였다.


6.2 대응 가이드

6.2.1 예방적 조치

메모리 보호

  • AES-128-CTR 키 메모리 상주 차단
  • 프로세스 메모리 실시간 모니터링
  • 의심 프로세스 즉시 덤프

 
행위 기반 탐지

  • 대량 파일 접근 패턴 탐지
  • .mallab 확장자 추가 차단
  • ISAAC PRNG 호출 패턴 탐지

 
네트워크 방어

  • RDP 접근 제한 및 MFA 적용
  • 의심 PowerShell 실행 차단
  • C&C 통신 탐지

 
백업 전략

  • 실시간 오프라인 백업
  • VSS 보호 솔루션
  • immutable 백업 스토리지

 
6.2.2 사후 대응

  1. 초동 조치 : 감염 발견 즉시 시스템 격리, 메모리 덤프 수행 (시스템 종료 금지!)
  2. 키 복구 : 메모리 포렌식으로 AES-128-CTR 키 추출 (패턴: 16바이트 높은 엔트로피)
  3. 복호화 수행 : 추출한 키로 자동화 스크립트 실행, 매직 바이트 검증
  4. 시스템 복구 : 복호화 성공 후 시스템 재구축, 초기 침투 경로 분석 및 패치

6.3 탐지 시그니처

탐지 요소 값 / 패턴
확장자 .mallab
푸터 Magic1 0x0201020100000000
메타데이터 길이 40 bytes
AES-CTR IV 길이 16 bytes
GCM Nonce 길이 8 bytes

6.4 초기 vs 최신 Mallox 차이

Mallox 랜섬웨어는 버전별로 암호화 구조가 진화해 왔다.

[초기 버전 (2021~2022)]
• 파일 암호화: ChaCha20
• 키 보호: ECDH + SHA-256
• 일부 버전은 AES-128-CTR을 key wrapping에 사용

[중기 버전]
• ChaCha20 유지
• AES-CTR 기반 키 래핑 구조 강화

[최신 버전 (v12 이후)]
• 파일 암호화: AES-256-GCM
• 키 보호: ECDH (X25519) + SHA-256
• per-file 키 생성: ISAAC PRNG
• AES-128-CTR 레이어로 파일 키 래핑

즉, Mallox는 단순 ChaCha 기반 랜섬웨어에서
AEAD(AES-GCM) 기반 고급 하이브리드 구조로
진화하였다.

6.4 결론

Mallox 랜섬웨어는 AES-256-GCM과 AES-128-CTR을 결합한 정교한 하이브리드 암호화 구조를 가지고 있으며, ISAAC PRNG를 통한 파일별 독립 키 생성을 구현합니다. 2021년 등장 이후 지속적으로 업그레이드되어 Mallox 최신 버전은 ECDH 기반 세션 키 파생 구조와 AES-256-GCM AEAD 암호화를 결합하여 기밀성(confidentiality)과 무결성(integrity)을 동시에 보장하는 구조를 채택하였다.