랜섬웨어 분석 보고서

Nitrogen 랜섬웨어 분석 보고서

geonwoo9643 2025. 12. 31. 04:14

1. 개요 (Overview)


1.1 분석 배경

2024년 이후 등장한 Nitrogen 랜섬웨어는 Curve25519 타원곡선 기반 키 교환을 통해 세션 키를 안전하게 유도하고, ChaCha8 스트림 암호를 통해 파일을 빠르게 암호화한다. 특히 파일 크기별로 암호화 범위를 줄이는 ‘부분 암호화(partial encryption)’ 설정으로 대용량 환경에서도 빠른 무력화가 가능하다.


1.2 핵심 요약

  • 하이브리드 암호 체계: Curve25519로 암호화 키를 보호하고, 고속 ChaCha8 알고리즘으로 데이터를 암호화한다.
  • 지능적 부분 암호화: 파일 크기별로 암호화 비중을 10%~100%로 가변 적용하여 암호화 효율을 극대화한다.
  • 데이터 복구 가능성: 분석 결과, 암호화 키 유도를 위한 세션 정보가 파일 하단(Footer)에 구조화되어 있으며, 특정 조건 하에 키 추출이 가능하다.

 

2. 식별 정보 (Identification)


  • Malware Family: Nitrogen
  • Filetype: PE32+ (64-bit Windows Executable)
  • Hash (SHA256): 04e768174636f0a5be42e9cee5974a8b9db2832d4e79cc973ad617185ab80595
  • Extension: .NITROGEN
  • Encryption Core: Curve25519 (ECDH) + ChaCha8

 

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


구분 도구명 (Tool) 용도 (Purpose)
정적 분석 IDA Pro 주요 함수 분석 및 알고리즘 식별
동적 분석 x64dbg CryptGenRandom 기반 난수 생성 및 타원 곡선 연산 추적
검증 도구 Python ChaCha8/Curve25519 복호화 로직 구현 및 데이터 복구 PoC

 

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


4.1 키 생성 및 교환 (Curve25519)

Nitrogen은 보안 수준을 높이기 위해 표준 Curve25519를 사용하여 세션 키를 합의한다.

  • 개인키 생성 및 클램핑 : CryptGenRandom으로 생성된 32바이트 난수에 대해 하위 3비트 제거(&= 248) 및 상위 비트 조정(& 127 | 64)을 거치는 표준 클램핑 작업을 수행한다.
  • 세션 공개키 도출 : 가공된 난수를 스칼라값으로 사용하여 BasePoint=9와 연산(X25519)한다.
  • 공격자 공개키 : 하드코딩된 공개키(fd556aa0...)를 사용하여 세션마다 고유한 ChaCha8 마스터 키를 유도한다.

4.2 파일 크기별 차등 암호화 정책

Nitrogen은 파일 크기를 기준으로 암호화 범위를 결정하는 세밀한 정책을 갖추고 있다.

파일 크기 모드 (Profile) 암호화 방식 암호화 비중
1MB 이하 Full (0x00) 파일 전체를 처음부터 끝까지 암호화 100%
1MB ~ 1GB Partial (0x32) 10% 단위 5개 구간 암호화 50%
1GB 초과 Partial (0x0A) 4% 단위 3개 구간 암호화 10%

4.3 ChaCha8 스트림 암호 엔진

  • 라운드 최적화 : 표준 ChaCha20의 라운드를 8회로 줄여 암호화 속도를 극대화하였다.
  • 상태 구성 : 4x4 행렬에 상수(expand 32-byte k), 유도된 32바이트 키, 8바이트 Nonce, 8바이트 카운터를 배치한다.

4.4 정적 분석

  • Curve25519 개인 키 생성

  • Curve25519 공유 키 계산
  1. 역원 계산 함수

  2. 필드 곱셈 함수
  3. 필드 원소 정규화 함수
  • 파일 열기 (쓰기 권한 추가)

 

  • 파일 암호화 여부 확인

 

  • 파일 크기에 따른 암호화

 

  • 파일 크기 <= 1 MB (0x100000) (작은 파일 전체 암호화)
    • 스트림 암호화 : ChaCha8 (36바이트 키)
    • 인플레이스 암호화(in-place encryption) : 원본 파일을 직접 덮어씀
    • 청크 단위 처리 : 메모리 효율성을 위해 버퍼 크기만큼 씩 처리
    • 파일 전체를 64바이트씩 암호화
    • 카운터가 0부터 순차적으로 증가

 

  • 파일 크기 > 1 MB (0x100000) (큰 파일 일부 암호화)
    • 스트림 암호화 : ChaCha8 (37바이트 키)
    • 인플레이스 암호화(in-place encryption) : 원본 파일을 직접 덮어씀
    • 청크 단위 처리 : 메모리 효율성을 위해 버퍼 크기만큼 씩 처리
    • 추가 분기
      • 파일 크기 > 1 GB (0x40000000)
        • 모드 0x0A (10%, 빠른 처리)
        • 청크 크기: 4 * (파일 크기 / 100) → 파일 크기의 4% (마지막 구간은 2%)
        • 스킵 구간 크기: 44 * (파일 크기 / 100) → 파일 크기의 44%
        • 구간 수: 3
      • 파일 크기 <= 1 GB (0x40000000)
        • 모드 0x32 (50%, 가장 많이)
        • 청크 크기: 10 * (파일 크기 / 100) → 파일 크기의 10%
        • 스킵 구간 크기: 10 * (파일 크기 / 100) → 파일 크기의 10%
        • 구간 수: 5
    • 카운터가 0부터 암호화 블록에서만 순차적으로 증가
    • 암호화/평문/암호화/평문/…/Footer 구조

 

  • ChaCha8 스트림 암호화 함수

 

  • 파일 푸터(Footer)에 메타데이터 저장
데이터 영역 크기 내용
공유 키 (Shared Key) 32 Bytes Curve25519로 생성된 공개키/공유키 데이터
넌스 (Nonce) 8 Bytes 암호화 시 매번 다르게 사용되는 일회용 숫자
메타데이터 (Config) 32 Bytes 키 오프셋, 암호화 비율, 원본 파일 크기 등
암호화 마커 (Marker) 16 Bytes 이 파일이 암호화되었음을 나타내는 고유 시그니처

 

  • 암호화된 파일 확장자(.NITROGEN) 추가

 

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


5.1 Footer 메타데이터 구조

암호화된 파일의 최하단(EOF) 88바이트 영역에는 복구에 필요한 모든 핵심 정보가 포함되어 있다.

오프셋 크기 필드명 설명
+00 32B Session Key Curve25519 기반 세션 키
+32 8B Nonce ChaCha8 암호화용 8바이트 Nonce
+64 8B Original Size 원본 파일의 크기 (QWORD)
+72 16B Signature 암호화 식별 마커 (NitroGen)

5.2 복호화 알고리즘: 가변 모드 대응

파일 크기에 따라 전체 복호화(Full)간헐적 복호화(Partial)로 나뉘며, 복호화 코드는 이를 자동으로 판별하여 수행한다.

  • Full Mode (≤ 1MB) : 파일 전체를 처음부터 순차적으로 복호화.
  • Partial Mode (> 1MB) : a4 값(0x0A ~ 0x32)에 따라 암호화된 블록만 골라내어 복호화.

5.3 핵심 복호화 PoC

아래 코드는 복호화 코드의 실제 파라미터 계산 방식과 섹션 점프 로직을 통합한 핵심 구현체이다.

def decrypt_logic(filepath, footer):
    # 1. Footer 파싱 및 키 유도
    session_key, nonce, file_size = parse_footer(footer)
    a4_mode = footer[1]  # 메타데이터 내 암호화 비율 결정자

    with open(filepath, 'r+b') as f:
        # 2. 파일 크기별 파라미터(v9: 크기, v27: 횟수, skip: 거리) 설정
        if file_size <= 1048576:
            v9, v27, skip = file_size, 1, 0
        else:
            v9, v27, skip = calculate_partial_params(file_size, a4_mode)

        # 3. 인플레이스(In-place) 구간 복호화
        counter = 0
        for i in range(v27):
            chunk = f.read(v9)
            if not chunk: break
            
            # ChaCha8 역산: counter는 블록(64바이트) 단위로 증가
            decrypted = chacha8_xor(session_key, nonce, counter, chunk)

            # 수정: 'Rewind & Overwrite' 기법 적용
            f.seek(-len(chunk), 1) 
            f.write(decrypted)
            
            # 다음 구간을 위해 카운터 갱신 및 대량 점프(Skip)
            counter += len(chunk) // 64
            if i < v27 - 1:
                f.seek(skip, 1) # 암호화되지 않은 영역 통과

def calculate_partial_params(file_size, a4):
    """a4 비율에 따른 정밀 점프 거리 계산"""
    unit = file_size // 100
    # 예: 0x0A (10%) 모드는 4%씩 3구간 암호화, 44%씩 2번 점프
    if a4 == 0x0A:
        return (4 * unit, 3, (file_size - 12 * unit) // 2)
    # 예: 0x32 (50%) 모드는 10%씩 5구간 암호화, 10%씩 4번 점프
    elif a4 == 0x32:
        return (10 * unit, 5, 10 * unit)
    return (0, 0, 0)

5.4 기술적 분석 결론

  • 데이터 무결성 : 복호화 시, f.seek를 이용한 정밀한 위치 제어가 필수적이며, 1바이트의 오차만 발생해도 전체 파일 구조가 파괴될 수 있다.
  • 알고리즘 효율성 : 대용량 파일(1GB 초과)의 경우 단 10% 미만(4% * 2 + 2%)의 구역만 복구함으로써 복구 속도를 비약적으로 향상시킨 구조이다.

 

6. 결론 (Conclusion)


6.1 암호화 워크플로우

  1. 초기화: CheckMutex 생성 및 시스템 환경 확인.
  2. 키 생성 : Curve25519 기반의 ECDH 과정을 통해 세션 키 생성 및 클램핑 적용.
  3. 모드 결정 : 파일 크기를 0x100000(1MB) 및 0x40000000(1GB) 기준으로 비교하여 암호화 전략 선택.
  4. 암호화 수행 : 선택된 모드에 따라 ChaCha8 엔진 가동 (Full 또는 Striping).
  5. Footer 작성 : 파일 끝에 복구용 메타데이터 기록 및 .NITROGEN 확장자 추가.


6.2 최종 평가

Nitrogen 랜섬웨어는 표준 암호 알고리즘을 정확하게 구현하고 있으며, 특히 파일 크기별 가변적 파라미터 계산을 통해 대형 서버의 데이터베이스나 영상 파일 등을 순식간에 무력화할 수 있도록 설계되었다. 하지만 암호화 과정에서 사용된 모든 메타데이터가 파일 Footer에 구조화되어 저장되므로, 개인키만 확보된다면 위 분석된 파라미터 공식을 역산하여 완벽한 복구가 가능하다.
 

7. 대응 및 예방 가이드 (Mitigation)


  • 초동 조치 : 감염 확인 시 즉시 네트워크를 격리하되, 시스템 전원을 끄지 않는다. Nitrogen은 키 생성을 위해 메모리를 빈번히 사용하므로 메모리 덤프 확보가 최우선이다.
  • EDR 탐지 강화 : 단시간 내에 다수의 파일에 대해 MapViewOfFile을 호출하거나 파일 하단에 88바이트 데이터를 반복적으로 쓰기 하는 행위를 차단한다.
  • 접근 통제 : SMB(445), RDP(3389) 포트의 외부 노출을 차단하고 계정 보안(MFA)을 강화한다.

 

부록: 침해 지표 (Appendix: IOC & Rules)

구분 Type Value (Indicator) 비고
Hash SHA256 04e768174636f0a5be42e9cee5974a8b9db2832d4e79cc973ad617185ab80595 분석 샘플 해시
Mutex String CheckMutex 중복 실행 방지용 뮤텍스
File Extension .NITROGEN 암호화된 파일의 확장자
Key Public Key fd556aa075a816d288c2d54fef7b70c6e5ded6ac6db3f772188e14a5fa1cc31f 하드코딩된 공격자 공개키

[표 1] Nitrogen 주요 침해 지표 (IOC)

 

Tactic ID Name Description
Impact T1486 Data Encrypted for Impact ChaCha8 및 Curve25519를 이용한 파일 암호화
Impact T1490 Inhibit System Recovery 섀도 복사본 삭제 및 복구 지점 무력화
Defense Evasion T1027 Obfuscated Files or Information 암호화 파라미터(a4)를 통한 암호화 영역 은닉

[표 2] MITRE ATT&CK TTPs 매핑

 

rule Nitrogen_Ransomware_Detection {
    meta:
        description = "Detects Nitrogen ransomware based on ChaCha8 and Curve25519 constants"
    strings:
        $const = "expand 32-byte k" ascii
        $mutex = "CheckMutex" ascii wide
        $hex_chacha = { 61 70 78 65 33 20 64 6e 79 62 2d 32 6b 20 65 74 }
    condition:
        uint16(0) == 0x5A4D and all of them
}

[코드] 탐지 시그니처 (YARA Rule)