1. 개요 (Overview)
1.1 분석 배경
2019년 처음 등장한 MedusaLocker 랜섬웨어는 지속적으로 변종을 생산하며 진화하고 있다. 최근 의료, 금융, 제조업 등 핵심 인프라를 대상으로 RDP(Remote Desktop Protocol) 취약점을 악용하여 침투하는 일명 'BabyLockerKZ' 변종이 활발히 유포되고 있어, 이에 대한 정밀 기술 분석을 수행하였다.
1.2 핵심 요약
- 위협 식별: 해당 샘플은 기존 Medusa RaaS(AES-256 사용)와 혼동되기 쉬우나, 정밀 분석 결과 ChaCha20 스트림 암호를 사용하는 MedusaLocker 계열의 독자적인 변종(BabyLockerKZ)으로 판명되었다.
- 고도화된 기법: 탐지 회피를 위해 안전 모드(Safe Mode) 강제 재부팅 기법을 사용하며, 레지스트리 키(PAIDMEMES)를 활용해 공격 지속성을 유지하는 치밀함을 보인다.
- 복구 가능성: 키 생성에 사용되는 난수(CSPRNG) 객체가 메모리에 평문으로 잔존하는 취약점을 발견하였다. 이를 통해 감염 직후 메모리 덤프를 확보할 경우 데이터의 100% 복구가 가능함을 입증하고 자체 복호화 도구(PoC)를 개발하였다.
2. 식별 정보 (Identification)
- Malware Family: MedusaLocker (Variant: BabyLockerKZ / v3)
- Attribution: PAIDMEMES 레지스트리 키 및 PDB 문자열(paid_memes)을 근거로 BabyLockerKZ 변종 식별
- Filetype: PE32 (Windows Executable)
- Hash (MD5): 8ba3a306f5550374490030ea472f2f92
- Hash (SHA256): d4919a7402d7ae02516589fbdfb3cc436749544052843a37b5d36ac4b7385b18
- Extension: .danger17 (※ 변종에 따라 .lock, .readinstruction, .babyk 등 다양)
- Ransom Note: HOW_TO_RECOVER_DATA.html
- Target: Windows Server (x86/x64) - RDP 활성화 및 취약 계정 시스템
3. 분석 환경 및 도구 (Tools)
| 구분 | 도구명 (Tool) | 용도 (Purpose) |
| 정적 분석 | IDA Pro | 바이너리 디스어셈블리, 암호화 알고리즘(ChaCha20) 식별 |
| 동적 분석 | x64dbg | 런타임 디버깅, 메모리 내 설정값 및 키 데이터 추출 |
| 행위 분석 | Process Monitor | 파일 시스템/레지스트리 변경 사항 및 프로세스 트리 추적 |
| 검증 도구 | Python | ChaCha20 스트라이프 복호화 로직 구현 및 검증 (PoC) |
4. 암호화 기술 분석 (Technical Analysis)
4.1 초기화 및 안티 포렌식
랜섬웨어는 실행 직후 시스템 제어권을 확보하고 분석을 방해하기 위해 다음과 같은 단계별 작업을 수행한다.
1. 실행 제어
- 중복 방지: CreateMutexA API를 호출하여 **“CheckMutex”**라는 이름의 뮤텍스를 생성한다. 이미 감염된 시스템에서의 중복 실행을 막아 리소스 충돌을 방지한다.
- 설정 로드: 바이너리 내부에 암호화된 설정(Config) 데이터를 메모리 상에서 XOR 연산 등으로 복호화하여 공격 설정을 로드한다.

[그림 4-1] 하드코딩된 설정 키워드 파싱
2. 보안 솔루션 무력화
- 시스템 명령어 강제 실행: 32비트 프로세스임에도 %windir%\sysnative 경로를 통해 64비트 시스템 도구(vssadmin, bcdedit)를 제약 없이 실행한다.

[그림 4-2] Sysnative 경로를 이용한 64비트 명령어 실행 우회
- 안전 모드 강제 재부팅: bcdedit /set {current} safeboot network 명으로 '네트워크 안전 모드' 부팅을 설정하여 보안 솔루션을 무력화한다.
- 서비스 강제 종료: Windows 재시작 관리자(Restart Manager)를 악용하여, 파일(엑셀, DB)을 점유 중인 프로세스를 커널 레벨에서 추적해 강제로 종료시킨다.

[그림 4-2] Windows 재시작 관리자를 이용한 파일 점유 프로세스 강제 종료
3. 탐지 우회 및 네트워크 자원 확보
- 실행 주체 위장 (Spoofing): 보안 솔루션(EDR)의 추적을 피하기 위해, 악성코드가 스스로 실행된 것이 아니라 신뢰할 수 있는 Windows 탐색기(explorer.exe)가 실행한 것처럼 부모 프로세스 정보를 조작한다.


[그림 4-4] 탐색기(explorer.exe) 위장 및 실행(Spoofing)
- 네트워크 드라이브 암호화: 위장 기법을 통해 사용자 권한을 획득하여, 관리자(SYSTEM) 권한에서는 접근할 수 없는 NAS 및 네트워크 공유 폴더까지 식별하고 암호화 범위를 확장한다.
4. 지속성 및 전파
- 레지스트리 등록: HKCU\Software\Microsoft\Windows\CurrentVersion\Run 경로에 자신을 등록하여 재부팅 후에도 자동 실행되도록 설정한다.



[그림 4-5] 레지스트리 자동 실행(Run) 등록 및 변종 식별 문자열 확인
- 공개키 저장: PAIDMEMES 레지스트리 키에 RSA 공개키 정보를 백업한다.



[그림 4-6] PAIDMEMES 레지스트리 키 생성 및 RSA 키 백업 루틴
- RSA 키 복원 및 재사용: 레지스트리에 저장된 RSA 공개키와 개인키 문자열을 읽어온 뒤, Base64 디코딩을 수행하여 메모리에 로드한다.

[그림 4-7] 레지스트리 내 RSA 키 로드 및 Base64 디코딩 로직
5. 감염 시스템 식별 및 정보 수집
- 공인 IP 확인 (외부): api.ipify.org 서비스에 접속하여 외부 IP 주소를 확인한다. 이는 피해 시스템의 위치를 파악하거나, 특정 국가(CIS 등)를 공격 대상에서 제외하기 위함이다.

[그림 4-8] ipify.org 접속을 통한 공인 IP 확인 코드
- 시스템 정보 수집 (내부): 호스트명, 사용자 계정 등 PC 고유 정보를 수집한 뒤 Base64로 인코딩한다. 이 데이터는 **[IDENTIFIER]**라는 특정 키값에 담겨, 공격자가 피해자를 구분하는 고유 식별자로 사용된다.


[그림 4-9] 시스템 정보 Base64 인코딩 및 [IDENTIFIER] 키 생성
6. 데이터 복구 방해
- 파일 암호화 전, 시스템에 남아있는 잠재적인 백업 데이터나 사용자가 복구할 가능성이 있는 파일을 제거한다. 플래그 값으로 7 (NOCONFIRMATION | NOPROGRESSUI | NOSOUND)을 설정하여, 사용자에게 삭제 확인 창이나 진행률, 효과음을 전혀 노출하지 않고 은밀하게 휴지통을 비운다.

[그림 4-10] 확인 절차 없는 휴지통 강제 삭제 코드
4.2 키 생성 및 관리
1. 난수 생성 (Key Generation)
- 윈도우 보안 API(CryptGenRandom)를 호출하여 예측 불가능한 고강도 난수를 생성한다. 이를 암호화 키로 사용하여, 외부의 키 유추 및 자체 복구 가능성을 원천적으로 차단한다.


[그림 4-11] CryptGenRandom API를 이용한 암호화 키 생성
2. 키 구조 (Key Structure)
생성된 40 Bytes 난수는 가공 없이 다음과 같이 분할되어 ChaCha20 알고리즘에 투입된다.
| Offset | Size | Role |
| 0x00 ~ 0x1F | 32 Bytes | ChaCha20 Key |
| 0x20 ~ 0x27 | 8 Bytes | Nonce |
[표 4-1] MedusaLocker 키 데이터 구조 (40 Bytes)
3. 세션 키 보호
- 하이브리드 암호화: 파일 데이터는 속도가 빠른 ChaCha20으로 암호화하고, 그 키는 보안성이 높은 RSA로 암호화하는 방식을 사용한다.
- PKCS#1 패딩 적용: CryptEncrypt 호출 시 블록 크기를 KeySize - 11로 계산하는 로직이 확인되는데, 이는 표준 PKCS#1 v1.5 패딩을 사용하고 있음을 의미한다. 암호화된 세션 키 정보는 레지스트리나 파일의 끝부분(Footer)에 저장된다.


[그림 4-12] RSA 공개키를 이용한 세션 키 암호화 루틴
4.3 암호화 알고리즘
1. ChaCha20 알고리즘
본 변종은 암호화 속도를 극대화하기 위해, 기존 AES보다 처리 속도가 훨씬 빠른 ChaCha20 스트림 암호 방식을 채택했다.
- 확인된 증거: 코드 분석 결과, ChaCha20 알고리즘의 고유한 식별자인 "expand 32-byte k" 문자열이 암호화 초기화 루틴에서 명확히 확인되었다.
- 초기화 구조: 32바이트(256비트)의 키와 **8바이트의 Nonce(난수)**를 사용하여 암호화 상태를 설정하며, 대용량 파일 처리를 위해 전체가 아닌 일부분만 암호화(Partial Encryption)한다.

[그림 4-13] ChaCha20 매직 넘버("expand 32-byte k") 및 초기 상태 설정 코드
2. 설정값 파싱
- bytesForEncrypt: 암호화 대상 구간 크기 (0x280000 = 약 2.5 MB)
- bytesCryptAndSkip: 스트라이핑 블록 단위 (0x2000 = 8 KB)

[그림 4-14] 설정 값 파싱 코드
- 메모리 상에서 확인된 설정 값은 리틀 엔디안(Little-Endian) 방식으로 저장되어 있어 0x280000과 0x2000 값이 명확히 식별된다.

[그림 4-15] 메모리에 로드된 암호화 설정 값 (Hex View)
3. 스트라이프 암호화
파일의 Head(시작)와 Tail(끝) 영역에 대해 다음과 같은 규칙으로 암호화를 수행한다.
- Head 영역: 파일 시작(Offset 0)부터 2.5MB 구간.
- Tail 영역: 파일 끝(EOF)에서 역순으로 2.5MB 구간. (파일 크기가 충분히 클 경우)
- 반복 루프: 해당 구간 내에서 8KB 암호화(XOR) -> 8KB 건너뛰기(Skip) 패턴을 반복한다.

[그림 4-16] 스트라이프(Stripe) 암호화 루프 로직 흐름도
4. 데이터 암호화 수행
- XOR 연산: 생성된 ChaCha20 키 스트림과 파일 데이터를 XOR 연산하여 암호화한다.
- 고속 처리: 별도의 임시 파일을 만들지 않고, 원본 파일 내용을 직접 덮어쓰는 In-Place 방식을 적용해 암호화 속도를 극대화했다.

[그림 4-17] ChaCha20 키 스트림 생성 및 XOR 암호화 연산 코드
5. 암호화 마무리 및 파일 변조
파일 암호화가 완료되면, 복구에 필요한 정보를 파일에 심고 이름을 변경하여 작업을 마무리한다.
- 키 저장 (Footer): 암호화에 사용된 키를 RSA로 잠가 파일의 맨 끝부분에 기록한다. 공격자의 개인키가 없으면 이 정보를 풀 수 없어 파일 복구가 불가능하다.

[그림 4-18] 암호화 키 저장(Footer)
- 확장자 변경: MoveFileW 함수를 호출하여 파일 확장자를 변경함으로써, 해당 파일이 암호화되었음을 시각적으로 표시한다.

[그림 4-19] 파일 확장자 변경 코드
4.4 암호화 제외 정책 (Whitelisting)
1. 윈도우 부팅 보장을 위한 암호화 제외
컴퓨터가 켜져야 피해자가 랜섬노트를 보고 돈을 보낼 수 있다. 따라서 부팅에 꼭 필요한 Windows 폴더나 프로그램 실행 파일(.exe, .dll)은 암호화하지 않고 건너뛰도록 설정되어 있다.


[그림 4-20] 시스템 파일 및 실행 파일 건너뛰기(Skip) 코드
2. 파일 보호 설정(읽기 전용) 강제 해제
중요한 파일은 수정되지 않도록 '읽기 전용'으로 잠겨 있는 경우가 많다. 이 상태에서는 암호화가 불가능하므로, 악성코드는 파일의 모든 잠금 설정을 강제로 해제한 뒤 암호화를 진행한다.


[그림 4-21] 읽기 전용 속성 강제 해제 및 암호화 준비 코드
4.5 랜섬 노트 및 감염 징후 (Indicators)
암호화된 폴더에는 HOW_TO_RECOVER_DATA.html 파일이 생성된다.
- 기만 전술: 노트에는 "RSA+AES"를 사용했다고 명시되어 있으나, 실제로는 ChaCha20을 사용한다. 이는 분석가의 혼동을 유도하기 위한 기만(Deception) 전술이다.
- 공격자 연락처: recovery2@salamati.vip, recovery2@amniyat.xyz

[그림 4-22] MedusaLocker 랜섬 노트 (HOW_TO_RECOVER_DATA.html)
5. 복호화 기술 분석 (Decryption Strategy)
본 분석에서는 역공학을 통해 키 생성 시점의 데이터가 메모리에 잔존할 수 있음을 확인하였고, 이를 이용한 복구 방안을 수립하였다.
5.1 복구 키 확보 방안 (Memory Forensics)
랜섬웨어 프로세스가 종료되지 않았거나 메모리 덤프를 확보한 경우, CryptGenRandom으로 생성된 40 Bytes 난수 객체(Key + Nonce)를 추출할 수 있다.
def find_40b_blobs(text):
# 정규표현식을 이용해 40바이트(Hex 80자) 키 데이터 패턴 추출
found = re.findall(r'\b([0-9a-fA-F]{80})\b', text)
used = []
seen = set()
for h in found:
key = h.lower()
if key in seen: continue
seen.add(key)
used.append(bytes.fromhex(key)) # Key(32B) + Nonce(8B)
return used
[코드 1] 메모리 덤프 내 키 식별 및 추출 로직
5.2 스트라이프 복호화 알고리즘 (Decryption Logic)
확보된 키를 이용하여 MedusaLocker의 고유한 스트라이프 규칙(8KB Encrypt / 8KB Skip)을 역산하는 복호화 로직을 구현하였다.
from Crypto.Cipher import ChaCha20
def decrypt_interleaved_bytes(ct_bytes, key, nonce, bfe, stripe):
out = bytearray(ct_bytes)
head_len = min(len(out), bfe) # 기본 2.5MB
cipher = ChaCha20.new(key=key, nonce=nonce)
def process(start, length):
off = 0
while off < length:
# 1. 암호화된 스트라이프(8KB) 복호화
take = min(stripe, length - off)
seg = out[start+off : start+off+take]
out[start+off : start+off+take] = cipher.encrypt(bytes(seg))
# 2. Skip 블록 처리 (암호화 안 됨)
off += 2 * stripe
process(0, head_len) # Head 영역 복호화
return bytes(out)
[코드 2] ChaCha20 기반 스트라이프 복호화 로직 (PoC)
5.3 무결성 검증 (Integrity Check)
추출된 키가 유효한지 검증하기 위해, 복호화된 파일 헤더의 매직 넘버(MZ, PK, %PDF 등)를 대조하는 로직을 적용한다.
MAGICS = {
"PNG": b"\x89PNG", "JPG": b"\xff\xd8\xff",
"PDF": b"%PDF-", "MZ": b"MZ"
}
def looks_like_plain(b):
for name, m in MAGICS.items():
if b.startswith(m): return True, name
return False, None
[코드 3] 파일 시그니처 기반 무결성 검증
6. 요약 및 결론 (Conclusion)
6.1 암호화 워크플로우 (Workflow)
- 초기화: CreateMutex, 설정값(0x280000, 0x2000) 로드, 시스템 경로 제외.
- 준비: RDP 스캔, vssadmin 섀도 복사본 삭제, 서비스 강제 종료.
- 키 생성: CryptGenRandom (40 Bytes).
- 암호화: ChaCha20 알고리즘으로 Head/Tail 영역 스트라이프 암호화.
- 완료: RSA로 키 암호화 저장, PAIDMEMES 레지스트리 기록, 랜섬 노트 생성.

[그림 6-1] MedusaLocker 암호화 워크플로우
6.2 최종 평가 (Final Assessment)
MedusaLocker(BabyLockerKZ)는 ChaCha20과 스트라이핑 기법을 결합하여 대용량 파일을 매우 빠르게 암호화하며, 안전 모드 부팅을 통해 탐지를 우회하는 지능적인 위협이다. 그러나 분석 결과, CSPRNG로 생성된 대칭키가 메모리에 평문으로 노출되는 취약점이 존재하며, 암호화 규칙이 고정되어 있어 메모리 포렌식을 통해 데이터의 완전한 복구가 가능함을 입증하였다.
7. 대응 및 예방 가이드 (Mitigation)
- RDP 보안 강화 (핵심): 주 침투 경로인 RDP 포트(3389)를 외부에 노출하지 않도록 VPN을 사용하고, 계정에 대한 MFA(다중 인증)를 필수로 적용한다.
- 행위 기반 탐지: vssadmin으로 섀도 복사본을 삭제하거나 bcdedit으로 안전 모드 부팅을 시도하는 프로세스를 즉시 차단하도록 EDR 정책을 설정한다.
- 메모리 덤프 확보 절차: 침해 사고 발생 시 시스템을 끄거나 재부팅하지 말고, 즉시 메모리 덤프를 확보해야 본 보고서의 복호화 방안을 적용할 수 있다.
부록: 침해 지표 (Appendix: IOC & Rules)
| 구분 | Type | Value (Indicator) | 비고 |
| Hash | MD5 | 8ba3a306f5550374490030ea472f2f92 | Sample Hash |
| Registry | Key | HKCU\Software\PAIDMEMES | BabyLockerKZ 고유 식별자 |
| Registry | Value | BabyLockerKZ, MSFEEditor | 자동 실행 등록명 |
| File | Note | HOW_TO_RECOVER_DATA.html | 랜섬 노트 |
| Mutex | String | CheckMutex | 중복 실행 방지 |
| Command | String | bcdedit /set {current} safeboot network | 안전 모드 부팅 |
[표 7-1] MedusaLocker 주요 침해 지표 (IOC)
| Tactic | ID | Name | Description |
| Defense Evasion | T1027 | Obfuscated Files or Information | 내부 설정(Config) 블록을 난독화하고 런타임에 복호화함 |
| Defense Evasion | T1562.009 | Safe Mode Boot | 보안 솔루션 우회를 위해 bcdedit로 안전 모드 강제 재부팅 |
| Impact | T1486 | Data Encrypted for Impact | ChaCha20 알고리즘을 사용하여 파일을 암호화하고 금전을 요구함 |
| Impact | T1490 | Inhibit System Recovery | vssadmin 및 wmic 명령어로 섀도 복사본 삭제 |
| Discovery | T1012 | Query Registry | 레지스트리 쿼리를 통해 시스템 정보를 수집하고 지속성 설정 |
[표 7-2] MITRE ATT&CK TTPs 매핑
rule Windows_Ransomware_MedusaLocker_BabyLockerKZ {
meta:
author = "Analysis Team"
description = "Detects MedusaLocker (BabyLockerKZ) via Config & Mutex"
severity = "High"
strings:
$mutex = "CheckMutex" ascii wide
$conf_chunk = { 00 00 28 00 } // 2.5MB
$conf_skip = { 00 20 00 00 } // 8KB
$cmd_safe = "bcdedit" ascii wide
condition:
uint16(0) == 0x5A4D and
($mutex or ($conf_chunk and $conf_skip) or $cmd_safe)
}
[코드 4] 탐지 시그니처 (YARA Rule)
'랜섬웨어 분석 보고서' 카테고리의 다른 글
| Donut 랜섬웨어 분석 보고서 (0) | 2025.12.29 |
|---|---|
| Babuk 랜섬웨어 분석 보고서 (0) | 2025.12.26 |
| DoNex 랜섬웨어 분석 보고서 (1) | 2025.12.20 |
| Beast 랜섬웨어 암호 및 복호화 기술 분석 보고서 (0) | 2025.12.19 |
| SINOBI 랜섬웨어 암호화 및 복호화 기술 분석 보고서 (0) | 2025.12.11 |