Search

Conti 기반 Gunra 랜섬웨어 리눅스 변종의 암호화 취약점 분석 보고서

태그
PurpleHound
Linux
Ransomware
Property
1.png
작성자
PurpleHound 팀 오승진 주임연구원

1. 개요

본 보고서는 악명 높은 Conti 랜섬웨어의 소스 코드를 기반으로 파생된 Gunra 랜섬웨어의 리눅스 변종을 분석한 기술 보고서이다. 랜섬웨어는 끊임없이 진화하며 기업과 개인에게 막대한 피해를 주고 있으며 특히 Conti와 같은 RaaS(Ransomware-as-a-Service) 조직의 유산은 다양한 변종의 출현으로 이어지며 그 위협의 수위를 높이고 있다. 그러나 가장 정교해 보이는 공격조차도 때로는 기본적인 구현상의 허점으로 인해 무력화될 수 있다.
78ResearchLab PurpleHound 팀의 분석 결과, 해당 Gunra 랜섬웨어 변종은 암호화의 근간이 되는 키(Key)와 Nonce 생성 과정에서 C 표준 라이브러리의 srand(time(0))rand() 함수를 치명적인 방식으로 오용하고 있음을 발견했다.
이 결정적인 취약점을 활용하여 암호화된 파일의 일부 원본을 확보했을 때 전체 파일을 복원할 수 있는 '알려진 평문 공격(Known-Plaintext Attack)' 기반의 복호화 PoC(Proof of Concept) 개발에 성공하였다. 이를 통해 특정 조건에서 Gunra 랜섬웨어에 의해 암호화된 파일의 완벽한 복구가 가능함을 입증하였다. 본 보고서는 해당 취약점의 기술적 내용과 구체적인 복호화 방법론을 공유하여 유사 변종 랜섬웨어에 대한 방어 및 대응 전략 수립에 이바지하는 것을 궁극적인 목적으로 한다.

2. 분석 배경

2.1. 복구 불가능 예측을 뒤엎은 Gunra 랜섬웨어

2025년 7월경, 국내 주요 금융기관 중 한 곳이 Gunra 랜섬웨어에 의해 대규모 침해사고를 당한 사건은 보안 업계에 큰 파장을 일으켰다. 공격에 사용된 Gunra 랜섬웨어는 Conti의 코드를 계승하여 강력한 ChaCha20 암호화와 RSA 공개키 암호화를 결합한 하이브리드 암호화 방식을 사용하는 것으로 알려졌다. 이에 따라 사고 초기 업계의 대다수 전문가는 암호학적 관점에서 사실상 복구가 불가능할 것이라는 비관적인 예측을 내놓았다.
그러나 신속한 기술 지원을 통해 결과적으로 데이터 복구가 완료되었다는 사실이 알려지면서 이러한 예측은 완전히 뒤집혔다. 이는 해당 랜섬웨어에 이론적인 암호 알고리즘의 문제가 아닌, 실제 공격 코드 내에 공략할 수 있는 실질적인 약점이 존재할 수 있음을 강력하게 시사하는 사건이었다.

2.2. Gunra 분석 프로젝트 착수

해당 사고는 PurpleHound 팀에게 중요한 연구 과제를 제시했다. '어떻게 강력한 암호화 구조를 가진 랜섬웨어가 복구될 수 있었는가?' 라는 의문에서 출발하여 공개된 Gunra 랜섬웨어의 리눅스 변종 샘플을 확보하고 자체적인 취약점 분석 프로젝트에 착수했다. 본 분석은 외부 정보에 의존하지 않고 리버스 엔지니어링과 코드 분석을 통해 랜섬웨어의 동작 원리를 처음부터 끝까지 파헤치는 방식으로 진행되었다.
분석 샘플: Gunra Ransomware (Linux Variant, 64-bit ELF)
SHA256: 22c47ec98718ab243f2f474170366a1780368e084d1bf6adcd60450a9289e4be

3. 암호화 프로세스 분석

Gunra 랜섬웨어의 암호화는 파일 시스템을 순회하며 대상을 감염시키는 전형적인 랜섬웨어의 행태를 따른다. 그러나 각 단계의 세부적인 구현 방식을 분석함으로써 그 안에 숨겨진 결함을 발견할 수 있었다. 전체적인 암호화 흐름은 다음과 같은 5단계로 요약된다.
1.
파일 탐색 사전에 정의된 특정 디렉터리(예: /home, /var/www) 및 파일 확장자 목록을 기준으로 암호화 대상을 재귀적으로 탐색한다. 이는 시스템 운영에 필수적인 파일을 제외하고 사용자의 중요 데이터에 최대한의 피해를 주기 위한 전략이다.
2.
Key/Nonce 생성 파일 암호화에 사용할 32바이트 Key12바이트 Nonce를 생성한다. 이 단계는 전체 암호화 프로세스의 성패를 좌우하는 가장 중요한 부분이지만 역설적으로 이 랜섬웨어의 유일한 '아킬레스건'이 존재하는 핵심 취약점 발생 구간이다.
3.
파일 암호화 앞서 생성된 Key와 Nonce를 사용하여 현대적인 스트림 암호 알고리즘인 ChaCha20으로 파일 데이터를 XOR 연산하여 암호화한다. ChaCha20 알고리즘 자체는 현재까지 깨지지 않은 매우 안전한 암호화 방식이며 이에 따라 공격자는 자신의 랜섬웨어가 강력한 보안성을 갖추었다고 착각하게 된다.
4.
파일 정보 기록 암호화된 원본 파일의 끝에 512바이트 크기의 정보 블록을 추가한다. 이 블록에는 공격자의 RSA 공개키로 암호화된 ChaCha20 Key와 Nonce 정보가 포함된다. 이는 전형적인 하이브리드 암호화 방식으로 공격자만이 자신의 RSA 개인키로 이 정보를 복호화하여 파일 복구를 수행할 수 있도록 설계된 장치이다.
5.
파일명 변경 암호화가 완료된 파일의 원래 확장자 뒤에 .ENCRT 확장자를 추가한다. (예: document.pdf -> document.pdf.ENCRT) 이는 사용자에게 파일이 감염되었음을 시각적으로 알리고 피해 범위를 명확히 하는 역할을 한다.
이처럼 Gunra 랜섬웨어는 겉보기에는 견고한 하이브리드 암호화 구조를 갖추고 있다. 그러나 모든 암호화의 시작점이자 가장 중요한 ‘Key/Nonce 생성' 과정에 존재하는 돌이킬 수 없는 결함으로 인해 이 모든 구조는 사상누각에 불과했다.

4. 취약점 상세 분석: rand()의 고질적 취약점

Gunra 랜섬웨어의 암호 체계를 근본적으로 붕괴시키는 핵심 취약점은 암호화 Key와 Nonce를 생성하는 내부 함수 generate_rand에 존재한다. 해당 함수는 암호학적으로 안전성이 보장된 난수 생성기(CSPRNG)를 사용하는 대신, 예측 가능성과 상태 관리 측면에서 명백한 한계를 지닌 C 표준 라이브러리의 srand()rand() 함수에 전적으로 의존한다.

4.1. 정적 분석: 코드 수준의 논리적 결함

코드의 정적 분석을 통해 두 가지의 결정적인 결함을 내포하고 있음을 식별하였다.
// Gunra 랜섬웨어의 generate_rand 함수 로직 __int64 __fastcall generate_rand(__int64 a1, unsigned int i) { __int64 v2; // rdi unsigned int j; // [rsp+1Ch] [rbp-4h] for ( j = 0; j < i; ++j ) { v2 = (unsigned int)time(0); // 1. 매 반복마다 현재 시간을 시드로 가져옴 srand(v2); // 2. 난수 생성기를 동일한 시드로 계속 초기화 *(_BYTE *)(j + a1) = rand(); // 3. 초기화된 후 첫 번째 난수만 반복적으로 사용 // BYTE로 받기 때문에 0 ~ 255로 축소 } return i; } // 실제 Key/Nonce 생성 과정 generate_rand((__int64)key_buffer, 0x20u); // 32바이트 ChaCha20 Key 생성 generate_rand((__int64)nonce_buffer, 0xCu); // 12바이트 ChaCha20 Nonce 생성
C
복사
반복문 내 srand() 호출로 인한 시드(Seed) 고정: time(0) 함수는 초(second) 단위의 정수 값을 반환한다. 현대적인 컴퓨팅 환경에서 for 반복문은 수십, 수백 회를 반복하더라도 1초가 지나지 않는 경우가 대부분이다. 따라서 루프가 실행되는 동안 time(0)의 반환값은 사실상 상수로 취급되며 이는 난수 생성기가 매번 동일한 시드 값으로 초기화되는 결과를 초래한다.
예측 가능한 난수열과 키 공간의 붕괴: 유사 난수 생성기(PRNG)인 rand() 함수는 시드 값이 동일할 경우, 언제나 동일한 순서의 난수열을 생성한다. 상기 코드는 매 반복마다 동일한 시드로 난수 생성기를 초기화한 직후 rand()를 1회 호출한다. 결과적으로, 32바이트의 Key 버퍼와 12바이트의 Nonce 버퍼는 난수열의 첫 번째 값의 최하위 1바이트로만 반복적으로 채워지게 된다.
이러한 논리적 결함은 256비트의 키 공간이 단 8비트로 축소될 것이라는 가설로 이어진다.

4.2. 동적 분석: 실제 메모리 값으로 결함 증명

정적 분석에서 제기된 가설을 실증적으로 검증하고자, 리눅스용 디버거인 EDB(Evan's Debugger)를 활용한 동적 분석을 수행했다. 분석은 generate_rand 함수 내부의 rand() 호출 직후에 중단점(Breakpoint)을 설정하여 반복문이 실행되는 동안 시드(Seed) 값과 Key/Nonce 버퍼의 메모리 상태 변화를 추적하는 방식으로 진행되었다.
분석 결과, 정적 분석의 예측과 정확히 일치하는 현상이 관찰되었다.
시드 값의 불변성 32바이트 Key와 12바이트 Nonce가 생성되는 전 과정에서 srand() 함수에 전달되는 시드 값은 특정 Unix 타임스탬프(예: 1755811200)로 고정되어, 단 한 차례도 변경되지 않는 현상이 관찰되었다.
Key/Nonce 단일 값 반복 고정된 시드의 직접적인 영향으로 rand() 함수는 매번 동일한 정수 값을 반환했다. 이로 인해 키와 Nonce 버퍼는 아래 그림의 메모리 덤프와 같이 예측된 대로 단일 바이트 값으로 완전히 채워지는 현상이 실제로 확인되었다.
[그림 1] 단일 값(0xCC)으로 채워진 32바이트 Key 버퍼
[그림 2] 단일 값(0xCC)으로 채워진 12바이트 Nonce 버퍼
이 동적 분석을 통해 generate_rand 함수가 생성하는 Key와 Nonce는 무작위 값이 아닌 예측 가능한 단일 바이트 값의 반복에 불과함이 명백히 증명되었다.

4.3. 256가지 경우의 수로 축소된 암호 체계

정적 및 동적 분석 결과를 종합하면, Gunra 랜섬웨어의 ChaCha20 암호화 Key와 Nonce는 무작위 256비트 값이 아닌 단일 8비트 값(0~255)을 반복한 것에 불과함이 명백히 증명된다.
따라서 암호 해독에 필요한 전체 키 공간(Key Space)은 256가지 경우의 수로 축소된다. 이는 전수조사 공격(Brute-force attack)을 통해 수 초 내에 암호화 키를 특정할 수 있음을 의미하며 다음 장에서 기술할 복호화 PoC(Proof of Concept) 개발의 핵심적인 이론적 토대를 제공한다.

5. 복호화 방법론 및 검증

앞서 4장에서 증명된 Gunra 랜섬웨어의 암호학적 결함은 이론적 분석을 넘어 실제 데이터 복구를 가능하게 하는 실질적인 경로를 제공한다. 본 장에서는 해당 취약점을 이용하여 암호화된 파일을 완벽하게 복원하는 구체적인 방법론을 제시하고 그 유효성을 실증적으로 검증한 PoC(Proof of Concept)의 개발 과정을 단계별로 상세히 기술한다.

5.1. 복호화 원리: 알려진 평문 공격

복호화의 핵심 원리는 알려진 평문 공격(Known-Plaintext Attack)이다. 이 방법은 암호화된 데이터의 원본 내용 일부를 이미 알고 있는 경우 이를 이용해 암호화 키를 찾아내는 기법이다.
Gunra 랜섬웨어는 다음 두 가지 조건 때문에 이 공격에 매우 취약하다.
1.
제한된 키 후보: 암호화에 사용된 키는 0x00부터 0xFF까지 단 256개 중 하나의 바이트를 반복하여 만들어진다.
2.
예측할 수 있는 원본 데이터: PDF, PNG, ZIP 파일 등은 종류를 식별하기 위해 파일의 가장 앞부분에 항상 동일한 데이터 값(파일 시그니처)을 가진다. 이것이 '알려진 평문'이 된다.
따라서, 이 두 조건을 이용해 256개의 키 후보를 모두 테스트하여 실제 키를 찾아내는 것이 이번 복호화의 기본 전략이다.

5.2. 복호화 과정 상세 분석

복호화 작업은 1단계: 암호화 키 바이트 식별2단계: 전체 파일 일괄 복호화로 나뉘며, 전체 과정은 아래 플로우차트와 같이 요약할 수 있다.
[그림 3] 전체 복호화 프로세스 플로우차트

5.2.1. 1단계: 키 바이트 식별

이 단계의 목표는 256개의 가능한 바이트 중 실제 암호화에 사용된 단 하나의 정확한 바이트 값을 찾아내는 것이다. 전체 과정은 아래 플로우차트와 같이 진행된다.
[그림 4] 키 바이트 식별 상세 과정
가. 분석 준비
1.
파일 선택: 감염된 파일 중 원본의 시작 부분을 아는 파일 하나를 선택한다. 이 보고서에서는 .pdf.ENCRT 파일을 기준으로 삼는다.
2.
데이터 정의:
알려진 평문: PDF 파일의 첫 4바이트 데이터인 %PDF (Hex: 25 50 44 46)를 목푯값으로 설정한다.
암호문: 선택한 .pdf.ENCRT 파일에서 실제 암호화된 데이터의 첫 4바이트를 읽어온다.
나. 키 후보 순차 검증
0x00부터 0xFF까지의 모든 바이트에 대해 다음의 검증 절차를 반복 수행한다.
1.
임시 Key/Nonce 생성: 현재 검증할 바이트를 32번 반복하여 32바이트 크기의 임시 Key를 12번 반복하여 12바이트 크기의 임시 Nonce를 메모리에 생성한다.
2.
키스트림(Keystream) 생성: ChaCha20 알고리즘은 암호화 시 암호문과 직접 연산할 암호화 비트열을 만드는데 이를 키스트림이라 한다. 1번에서 생성한 임시 Key와 Nonce를 ChaCha20 함수에 입력값으로 넣어 64바이트 크기의 키스트림 블록을 생성한다.
3.
부분 복호화 수행 (XOR 연산): 2번에서 생성된 키스트림의 첫 4바이트와 준비 단계에서 읽어온 암호문의 첫 4바이트를 서로 XOR 연산한다. XOR 연산은 암호화된 데이터를 원본으로 되돌리는 과정이다.
[그림 5] XOR 연산 개념도
4.
결과 비교: 3번 연산의 결과로 나온 4바이트 데이터가 준비 단계에서 정의한 '알려진 평문'(%PDF)과 완전히 일치하는지 비교한다.
다. 키 바이트 확정 만약 비교 결과가 일치한다면 현재 테스트한 바이트가 실제 암호화에 사용된 유일한 '키 바이트'임이 확정된다. 즉시 반복을 중단하고 다음 단계로 넘어간다. 만약 일치하지 않는다면 다음 바이트로 위의 과정을 계속 반복한다.
라. 구현 정확성 확보 복호화 PoC의 모든 ChaCha20 관련 함수는 Gunra 랜섬웨어 실행 파일 리버스 엔지니어링하여 실제 암호화 코드와 100% 동일하게 구현했다. 이는 어떠한 구현상의 차이도 없이 정확한 복호화를 보장한다.

5.2.2. 2단계: 전체 파일 일괄 복호화

1단계에서 정확한 키 바이트를 찾아낸 후에는 감염된 모든 파일을 복원하는 작업에 들어간다.
최종 Key/Nonce 생성: 1단계에서 확정한 키 바이트를 이용해 최종적으로 사용할 32바이트 Key와 12바이트 Nonce를 생성한다.
파일 복호화 (키스트림 생성 및 XOR 연산): 감염된 모든 .ENCRT 파일을 대상으로 복호화를 수행한다. 전체 파일의 복호화 원리는 1단계의 부분 복호화와 동일하다. 최종 키와 Nonce를 ChaCha20 함수에 입력하여 암호문 데이터 전체 길이만큼의 키스트림(Keystream)을 생성한다. 이 키스트림과 암호문 전체를 바이트 단위로 XOR 연산하면 원본 평문 데이터가 복원된다.
원본 파일 저장: 복호화된 데이터는 원래의 파일명으로 저장하여 복원을 완료한다.

5.3. 검증 결과 및 시연

개발된 복호화 PoC는 Gunra 랜섬웨어 샘플에 의해 암호화된 가상 환경에서 테스트되었다. 그 결과, 단일 PDF 파일을 통해 수 초 내에 정확한 키 바이트(0xCC)를 식별했으며, 이를 통해 감염된 모든 파일이 데이터 손상 없이 100% 완벽하게 복원됨을 확인했다.
이는 본 보고서에서 제시한 이론적 취약점과 복호화 방법론이 실질적으로 유효함을 명백히 검증한 결과이다.
[동영상 1] 복호화 성공 시연 영상

6. 결론 및 대응 방안

6.1. 결론

본 보고서에서 분석한 Gunra 랜섬웨어 리눅스 변종은 악명 높은 Conti의 소스 코드를 계승하고 강력한 스트림 암호인 ChaCha20을 채택했음에도 불구하고 암호학의 가장 기초적인 원칙을 간과한 구현 오류로 인해 전체 암호 체계가 무력화될 수 있음을 명백히 보여주었다.
이 사례는 아무리 강력하고 검증된 암호 알고리즘을 사용하더라도 그것을 구현하는 과정에서의 사소한 실수가 전체 시스템의 보안을 어떻게 와해시킬 수 있는지 보여주는 중요한 실증적 증거이다. 이는 현대 사이버 보안에서 '알고리즘의 강점'만큼이나 '구현의 안전성'이 무엇보다 중요함을 다시 한번 시사한다.

6.2. 대응 방안

6.2.1. 피해 발생 시 복구 방안

본 보고서에서 증명된 취약점은 데이터 복구의 직접적인 단초를 제공한다.
알려진 평문 공격 기반 복구: 피해 시스템 내 암호화된 파일 중 PDF, ZIP, PNG, JPEG 등 명확하고 고정된 헤더 시그니처를 가진 파일이 단 하나라도 존재할 경우 본 보고서 5장에서 기술한 알려진 평문 공격 방법론을 적용하여 전체 암호화 키를 특정하고 데이터를 복원할 수 있다.

6.2.2. 사전 예방 및 방어 전략

유사 변종 랜섬웨어 및 잠재적 위협으로부터 시스템을 보호하기 위해 다음과 같은 다층적 방어 전략의 수립이 필수적이다.
데이터 복원력 확보를 위한 백업 정책 강화: 데이터 유실에 대비하는 최후의 보루는 백업이다. 중요 데이터는 백업 전략에 따라 주기적으로 백업을 수행하여 랜섬웨어의 영향권에서 벗어난 복구 능력을 확보해야 한다.
리눅스 서버 시스템 강화: 리눅스 서버에 대한 비인가 접근을 원천적으로 차단하고 공격 표면을 최소화해야 한다. 최소 권한 원칙에 따른 사용자 계정 관리, 다중 인증(MFA) 적용, 방화벽 규칙 강화 등을 적용한다. 또한, 비정상적인 프로세스의 대량 파일 입출력(I/O) 행위와 같은 랜섬웨어의 특징적 활동을 실시간으로 탐지하고 차단할 수 있는 솔루션의 도입을 적극적으로 고려해야 한다.
침해 탐지 및 분석 역량 강화: 시스템 및 파일 접근, 사용자 활동에 대한 상세한 로그를 수집하고 중앙에서 통합 관리하여 잠재적 위협 행위를 상시 모니터링한다. 이는 침해 사고 발생 시 감염 경로와 피해 범위를 신속하게 파악하고, 재발 방지 대책을 수립하는 데 핵심적인 역할을 수행한다.
방어 체계의 실효성 검증 및 고도화 (BAS 도입) 백업, 시스템 강화, EDR/XDR 도입과 같은 방어 전략이 실제 공격 상황에서 과연 효과적으로 작동하는지 검증하는 것은 기존의 수동적인 방식으로는 한계가 명확하다. 바로 이 지점에서 BAS(Breach and Attack Simulation, 공격 시뮬레이션) 솔루션이 필수적인 역할을 수행한다. BAS 솔루션은 Conti와 같은 실제 공격 그룹이 사용하는 최신 TTPs(전술, 기술, 절차)를 기반으로 자동화된 공격 시나리오를 내부망에서 안전하게 수행한다. 이를 통해 다음과 같은 효과를 얻을 수 있다.
보안 공백 식별: 현재 운영 중인 보안 솔루션(EDR, 방화벽 등)의 탐지/차단 누락, 설정 오류, 정책 미비점 등 우리가 미처 인지하지 못했던 실질적인 보안의 허점을 선제적으로 식별한다.
데이터 기반 방어 최적화: 어떤 공격 경로가 유효하고 어떤 방어 체계가 효과적인지에 대한 객관적인 데이터를 확보하여, 추측이 아닌 증거에 기반한 보안 투자 및 정책 개선을 가능하게 한다.
보안 태세의 상시 검증: 일회성 모의 해킹과 달리, 지속적이고 자동화된 검증을 통해 상시적인 위협 대응 능력을 최고 수준으로 유지하고 관리할 수 있다. Gunra 랜섬웨어의 파일 암호화 행위를 BAS가 미리 시뮬레이션했다면 EDR이 이를 제대로 탐지하는지 사전에 검증하고 방어 체계를 보강할 수 있었을 것이다.

7. 복호화 도구 공개

본 보고서에서 기술한 분석 내용과 복호화 방법론의 실효성을 증명하기 위해 개발된 PoC(Proof of Concept) 코드를 공개한다. 이 도구는 Gunra 랜섬웨어의 특정 변종에 의해 암호화된 파일을 복구하는 데 사용할 수 있다.

7.1. 도구 개요

공개된 C 코드는 다음의 두 가지 핵심 기능을 수행한다.
1.
키 바이트 식별: 감염된 디렉터리 내 .pdf.ENCRT 파일을 대상으로 '알려진 평문 공격'을 수행하여 256가지 경우의 수 중 실제 암호화에 사용된 단일 키 바이트를 식별한다.
2.
일괄 복호화: 식별된 키 바이트를 이용해 디렉터리 내 모든 .ENCRT 파일을 자동으로 복호화한다.

7.2. 소스 코드

전체 소스 코드는 아래의 GitHub 저장소에 공개되어 있다.

7.3. 주의사항

본 도구는 Gunra 랜섬웨어의 특정 취약점을 연구하고 그 위험성을 알리기 위한 목적으로 개발되었다. 따라서 교육 및 연구 목적으로만 사용해야 하며 악의적인 용도로 사용하는 것을 엄격히 금한다. 모든 사용자는 본 도구를 사용함에 있어 관련 법규를 준수할 책임이 있다.