랜섬웨어 분석 보고서

Cloak 랜섬웨어 분석 보고서

geonwoo9643 2026. 2. 6. 16:29

1. 개요 (Overview)


1.1 분석 배경

Cloak 랜섬웨어는 Mammona 랜섬웨어의 변종으로 추정되는 악성코드로, ECDH(Curve25519) 키 교환과 HC-128 스트림 암호화를 결합한 하이브리드 암호화 방식을 사용합니다. 프로세스 교체(Process Hollowing) 및 자가 삭제 메커니즘을 통해 분석을 회피하며, 안티디버깅 로직을 내장하고 있습니다. 본 보고서는 Cloak의 암호학적 구조를 정밀 분석하고, API 후킹을 통한 실시간 키 추출 및 복호화 전략을 제시합니다.


1.2 핵심 요약

암호화 메커니즘

  • ECDH(Curve25519) 키 교환 프로토콜을 통한 파일별 공유 비밀 생성
  • HC-128 스트림 암호를 사용한 고속 파일 암호화
  • SHA-512 기반 KDF(Key Derivation Function)로 HC-128 Key/IV 도출

 

회피 기법

  • 프로세스 교체 및 자가 삭제 메커니즘
  • 안티디버깅 로직 내장
  • 휴지통 비우기, VSS 삭제, 방화벽 무력화

 

복호화 가능성

  • CryptGenRandom API 호출 시점의 파일별 개인키를 API 후킹으로 실시간 캡처 시 완벽한 복호화 가능
  • 공격자 개인키 없이는 복호화 불가능
  • 본 분석에서 개발한 자동화 복호화 스크립트로 실증 검증 완료

 

2. 식별 정보 (Identification)


Malware Family: Cloak (Mammona 변종)

Filetype: PE32 (Windows Executable)

Hash (SHA256): d6af700fb86d3a3a832ba49273453b9c35c89978e4855ce9033b9770d938881c

Extension: .crYpt

Target: Windows 기반 시스템

 

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


구분 도구명 (Tool) 용도 (Purpose)
정적 분석 IDA Pro ECDH/HC-128 구현 루틴 및 암호화 로직 분석
동적 분석 CryptGenRandom API Hooking 실시간 개인키 추출
행위 분석 Process Monitor 파일 I/O 및 암호화 행위 추적
암호 분석 Python ECDH 연산 및 HC-128 복호화 스크립트 개발

 

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


4.1 전체 암호화 워크플로우

[실행 단계]
1. WinMain 초기화
   - 안티디버깅 로직 실행
   - 프로세스 교체 (Process Hollowing)
   - 자가 삭제 메커니즘 활성화
   ↓
2. 시스템 무력화
   - 휴지통 비우기
   - VSS(Volume Shadow Copy) 삭제
   - 방화벽 비활성화
   - CryptAcquireContext로 암호화 공급자 획득
   ↓
3. 암호화 스레드 생성
   - reateThread 호출
   - StartAddress로 암호화 워커 스레드 실행
   ↓
4. 파일별 암호화 수행
   - 파일 탐색 및 필터링
   - 암호화 함수 호출
   - 파일명 변경 (원본.확장자 → 원본.확장자.crYpt)

4.2 키 생성 및 관리 (Key Generation)

4.2.1 ECDH 키 교환 프로토콜

Curve25519 기반 키 교환

정의:
- G = BasePoint (Curve25519 → 9)
- a = 파일별 피해자 개인키 (CryptGenRandom으로 생성, 32바이트)
- A = 파일별 피해자 공개키
- b = 공격자 개인키 (미공개)
- B = 공격자 공개키 (하드코딩)
- s = 공유 비밀 (암호화 키 도출용)

키 교환 과정:
1. A = Curve25519(a, G)  // 피해자 공개키 생성
2. s = Curve25519(a, B)  // 공유 비밀 생성
3. A를 파일 메타데이터에 저장 (복호화 시 사용)

 

공격자 공개키 (하드코딩)

ATTACKER_PUBKEY_CRYPT = bytes.fromhex(
    "3B4C31C6857B5C176EE766CDC3CE7DF291E76373926E9801B1D73F61F5D77B07"
)

 

4.2.2 SHA-512 KDF (Key Derivation Function)

/ ECDH 공유 비밀 생성
shared_secret = Curve25519(victim_privkey, attacker_pubkey);

// SHA-512 해싱
master_key = SHA512(shared_secret);  // 64바이트

// 키 분할
hc128_key = master_key[0:32];   // HC-128 Key (32바이트)
hc128_iv  = master_key[32:64];  // HC-128 IV (32바이트)

4.3 HC-128 스트림 암호화 알고리즘

4.3.1 HC-128 초기화

State 구조

HC-128 State (2560비트):
- P[512]: 32비트 워드 배열 (2048비트)
- Q[512]: 32비트 워드 배열 (2048비트)
- Key: 32바이트 (256비트)
- IV: 32바이트 (256비트)

 

초기화 과정

// 1. Key/IV로 State 초기화
init_state(state, key_words, 256, 256);

// 2. IV 적용
apply_iv(state, iv_words);

// 3. 키스트림 생성 준비
prepare_keystream(state);

 

4.3.2 키스트림 생성 및 XOR 암호화

// 키스트림 생성 및 XOR 연산
ReadFile(hFile, lpBuffer, FileSize.LowPart, &NumberOfBytesRead, 0);
hc128_xor_encrypt(state, lpBuffer, lpBuffer, NumberOfBytesRead);
WriteFile(hFile, lpBuffer, NumberOfBytesRead, &NumberOfBytesWritten, 0);

 

암호화 수식

Ciphertext[i] = Plaintext[i] ⊕ HC128_Keystream[i]

4.4 파일 처리 아키텍처

[파일 암호화 프로세스]
1. 파일 열기 (CreateFile)
   ↓
2. CryptGenRandom 호출
   - 32바이트 개인키 생성 (a)
   ★ API 후킹 지점 ★
   ↓
3. ECDH 키 교환
   - A = Curve25519(a, G)
   - s = Curve25519(a, B)
   ↓
4. KDF 수행
   - master = SHA512(s)
   - key = master[0:32]
   - iv = master[32:64]
   ↓
5. HC-128 초기화
   - State 초기화 (key, iv)
   ↓
6. 파일 암호화
   - HC-128 키스트림 생성
   - XOR 연산
   - 암호화 데이터 쓰기
   ↓
7. 파일명 변경
   원본.확장자 → 원본.확장자.crYpt

4.5 정적 분석

WinMain

  • CSP(Cryptographic Service Provider) 컨텍스트 획득

 

  • Mutex 생성 (중복 실행 방지)

 

  • 각 드라이브 별 파일 암호화 수행 (시스템 내 논리 드라이브)

 

  • 드라이브 암호화 시작

 

  • 디렉터리 재귀 탐색

 

  • 파일/폴더 필터링 및 제외

 

  • 파일 큐 관리 함수

 

  • 암호화 스레드 생성 (CPU 코어 수)

 

암호화 워커 스레드

 

암호화 함수

  • 파일 속성 변경

 

  • 파일 확장자 변경

 

  • 파일 열기 (읽기/쓰기 권한)

 

  • 공개키 로드

 

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

 

  • Curve25519 스칼라 곱셈 (공개 키 생성)

 

  • Curve25519 ECDH (공유 비밀 생성)

 

  • SHA-512 KDF (64바이트 마스터 키 생성)

 

  • HC-128 State 초기화

 

  • 파일 크기 별 분기

 

  • 파일 암호화

 

  • 파일 끝 메타데이터 추가

 

Curve25519 스칼라 곱셈 함수

 

SHA-512 해싱 함수

 

HC-128 State 초기화 함수

 

HC-128 키스트림 XOR 함수

 

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


5.1 복호화 가능성 분석

ECDH 복호화 불가능 원리

공유 비밀 복원 조건:
s = Curve25519(a, B) = Curve25519(b, A)

복호화를 위해 필요:
- 피해자 개인키(a) 또는 공격자 개인키(b)

문제점:
- 피해자는 a를 모름 (CryptGenRandom 후 메모리에서 소멸)
- 공격자만 b를 보유
- A만으로는 a를 역산 불가능 (이산로그 문제)

5.2 CryptGenRandom 키 복구 메커니즘

취약점 구조

CryptGenRandom API 호출
         ↓
   평문 개인키 생성 (32B)
         ↓
  ★ API 후킹 지점 ★  ← 키 캡처!
         ↓
  ECDH 공유 비밀 계산
         ↓
   SHA-512 KDF
         ↓
  HC-128 암호화 수행

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

5.3.1 핵심 복호화 로직

 

1. 개인키 후보 도출

def derive_candidates_from_json(json_path, attacker_pubkey):
    """JSON에서 CryptGenRandom(32바이트) 이벤트 추출"""
    candidates = []
    
    for ev in events:
        if (ev.get("api") == "CryptGenRandom" and 
            ev.get("length_bytes") == 32):
            
            priv = bytes.fromhex(ev["payload_hex"])
            
            # ECDH 공유 비밀 계산
            shared = x25519(priv, attacker_pubkey)
            
            # SHA-512 KDF
            master = hashlib.sha512(shared).digest()
            key = master[:32]
            iv = master[32:64]
            
            candidates.append({
                "source_priv": ev["payload_hex"],
                "key_hex": key.hex(),
                "iv_hex": iv.hex()
            })
    
    return candidates

 

2. HC-128 복호화

def decrypt_bytes_hc128(cipher: bytes, key_hex: str, iv_hex: str) -> bytes:
    """HC-128 스트림 암호 복호화 (XOR 기반)"""
    key = bytes.fromhex(key_hex)
    iv = bytes.fromhex(iv_hex)
    
    # State 초기화
    state = alloc_state()
    init_state(state, key_words, 256, 256)
    apply_iv(state, iv_words)
    
    # 키스트림 생성 및 XOR
    out = bytearray(cipher)
    generate_keystream_xor(state, cipher[:dec_len], out, dec_len)
    
    return bytes(out)

 

3. 매직 바이트 검증

def looks_valid_magic(output_path, data: bytes) -> bool:
    """복호화 결과 시그니처 검증"""
    ext = os.path.splitext(output_path)[1].lower()
    
    if ext in (".jpg", ".jpeg"):
        return data.startswith(b"\xFF\xD8\xFF")  # JPEG SOI
    if ext == ".png":
        return data.startswith(b"\x89PNG\r\n\x1a\n")
    if ext == ".pdf":
        return data.startswith(b"%PDF")
    # ...

5.4 무결성 검증

파일 유형 매직 넘버 (Hex) 설명
JPG FF D8 FF E0/E1/DB JPEG 이미지
PNG 89 50 4E 47 0D 0A 1A 0A PNG 이미지
PDF 25 50 44 46 PDF 문서
ZIP/DOCX 50 4B 03 04 압축 파일
EXE/DLL 4D 5A Windows 실행 파일

 

6. 요약 및 결론 (Conclusion)


6.1 최종 평가

Cloak 랜섬웨어는 암호학적으로 안전한 ECDH + HC-128 하이브리드 방식을 채택하여, 공격자 개인키 없이는 복호화가 불가능한 구조를 가지고 있습니다. 그러나 CryptGenRandom API 호출 시점에 평문 개인키가 메모리에 존재하는 구조적 취약점으로 인해, API 후킹을 통한 실시간 키 캡처가 가능하며, 이를 활용한 완벽한 복호화가 실증되었습니다.

[취약점 요약]
CryptGenRandom(32바이트)
         ↓
   평문 개인키 생성
         ↓
  ★ API 후킹 지점 ★
         ↓
ECDH + SHA-512 + HC-128
         ↓
  파일 암호화 완료

6.2 대응 가이드

6.2.1 예방적 조치

  1. API 모니터링 강화
    • CryptGenRandom 호출 패턴 실시간 탐지
    • 의심스러운 대량 난수 생성 차단
  2. 행위 기반 탐지
    • 대량 파일 접근 패턴 탐지
    • .crYpt 확장자 추가 행위 차단
    • 프로세스 교체(Process Hollowing) 탐지
  3. 파일 시스템 보호
    • 실시간 백업 시스템 구축
    • VSS 삭제 시도 탐지 및 차단

 

6.2.2 사후 대응

  1. 초동 조치
    • 감염 발견 즉시 시스템 격리
    • 메모리 덤프 수행 (시스템 종료 금지)
    • 프로세스 메모리에서 CryptGenRandom 키 추출
  2. 키 복구
    • API 후킹 도구로 CryptGenRandom 로그 확보
    • 메모리 포렌식으로 32바이트 개인키 패턴 추출
    • JSON 로그 파일에서 키 후보 도출
  3. 복호화 수행
    • 추출한 개인키로 ECDH 공유 비밀 재계산
    • HC-128 복호화 및 매직 바이트 검증

6.3 기술적 특징 요약

항목 세부 내용
암호화 알고리즘 ECDH(Curve25519) + HC-128 Stream Cipher
키 관리 파일별 독립 32바이트 개인키 (CryptGenRandom)
KDF SHA-512 (64바이트 출력 → 32B Key + 32B IV)
확장자 .crYpt
공격자 공개키 하드코딩 (3B4C31C6857B5C...)
복호화 가능성 API 후킹으로 개인키 확보 시 100% 복구 가능
회피 기법 프로세스 교체, 자가 삭제, 안티디버깅

6.4 결론

Cloak 랜섬웨어는 ECDH 키 교환과 HC-128 스트림 암호화를 결합한 강력한 암호학적 구조를 가지고 있지만, 키 생성 과정에서 CryptGenRandom API를 직접 호출하는 설계상 취약점으로 인해 API 후킹을 통한 복호화가 가능합니다. 본 분석에서 개발한 자동화 복호화 도구는 Cloak 감염 피해 복구에 직접 활용될 수 있으며, 향후 유사 랜섬웨어 대응을 위해서는 암호화 API 실시간 모니터링 체계 구축메모리 포렌식 역량 강화가 필수적입니다.