Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
도구/GitHubGitHub/reecdeep/hivev5_keystream_decryptor
Encryption/Decryption ToolsReverse EngineeringData RecoveryMalware AnalysisDigital ForensicsCryptographyBinary Analysis
GitHubreecdeep/hivev5_keystream_decryptor

HiveV5_keystream_decryptor

나쁜 사람들이 만든 나쁜 것들

저장소 보기
49934년 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

HiveV5 키스트림 복호화 PoC

소개

이 문서에서 분석 및 참조된 Hive 샘플은 @rivitna님이 작성한 이 목록에서 무작위로 선택되었으며, 이 자리에서 가장 따뜻한 감사를 드립니다. 아티팩트는 VirusTotal 플랫폼에서 확인할 수 있습니다.

이 문서에서는 a0h2uih3d2.exe 파일을 참조로 사용했습니다.

MD5: 15CF5E0DA094ACDD751A513402A8C941
SHA-1: 72E15AC4473903C814E65E3C06F54EB0399580AA
SHA-256: 335D2E4A743D059955760ECF2EC25EE86D36AA60B096C9180E860C64EF78EE55

이 랜섬웨어의 복잡성을 파악하려면 Microsoft Threat Intelligence Center(MSTIC)가 발행한 이 분석을 살펴보시기 바랍니다.

코드를 사용하기 전에 문서 전체를 주의 깊게 읽으시기 바랍니다!

Hive v5 간략 개요

최근 몇 달 동안 저는 Hive v5 암호화 알고리즘의 연구와 리버스 엔지니어링에 대부분의 힘을 쏟았습니다. 과거에 Hive의 이전 버전을 분석하고 그 암호화 메커니즘에 관한 코드와 PoC를 공개한 훌륭한 악성코드 분석가이자 리버스 엔지니어인 @rivitna님과 협업할 수 있는 기쁨을 누렸습니다. 그분은 RUST로 작성되어 분석이 더욱 어려워진 Hive v5의 암호화 작업에 관여하는 구성 요소를 식별하는 데 (적지 않게) 기여했습니다. 저는 2021년 6월에 소스가 공개된 또 다른 매우 중요한 랜섬웨어인 Babuk과 공통점을 발견했습니다:

  • 키 교환 알고리즘;
  • 1256개의 암호화 스레드를 시작하기 전에 종료해야 할 프로세스 목록.

피해자 시스템에서 실행되는 Hive 랜섬웨어 v5는 아래 증거의 알고리즘을 사용하여 QueryPerformanceCounter 및 QueryPerformanceFrequency Windows API를 기반으로 두 개의 평문 키(cleartext key)를 생성합니다.

QueryPerformanceCounter API에 대한 자세한 내용은 이 Microsoft 페이지를, QueryPerformanceFrequency에 대한 내용은 여기를 참조하시기 바랍니다.

QueryPerformanceCounter는 매우 정확한 시간 카운터입니다. 호출되면 PC가 마지막으로 켜진 이후 경과된 시간을 반환합니다.

QueryPerformanceFrequency는 성능 카운터의 값(주파수)을 반환합니다. 고정 값은 0x989680입니다. 즉, QueryPerformanceCounter 값은 초당 0x989680회, 즉 10,000,000회 업데이트된다는 뜻입니다.

두 개의 평문 키는 크기가 0xCFFF00바이트이며 한 번에 한 바이트씩 생성됩니다. 아래는 Hive가 피해자 PC의 파일을 암호화하는 데 사용하는 소위 평문 키(cleartext key) 의 가장 큰 부분인 0xA00000바이트 배열을 생성하는 스니펫입니다.

snippetGenKeyCleartext

키의 각 바이트는 AL 레지스터의 값을 취하여 얻습니다. EAX 레지스터에는 createByte라는 라벨로 이름이 변경된 0044ADE0 함수의 결과가 포함되어 있으며, 이 함수는 call_to_QueryPerformanceCounter라는 라벨로 이름이 변경된 함수 0044A850의 첫 번째 호출 시 계산된 초기 시드 값과 현재 시점의 차이를 구현합니다.

다음은 평문 키를 생성하기 위해 C++로 작성된 코드입니다:

c++GenKeyCleartext

알고리즘은 매우 간단하지만, 0044ADE0 함수 내부에는 평문 키 생성 중 코드 실행 시간을 지연시키기 위해 중복 연산과 다양한 조건부 점프를 수행하는 명령어가 삽입되어 있습니다:

useless-conditions

HiveRansomwareV5_custom_keygen_PoC 폴더에는 분석된 Hive v5 샘플에서 리버스한 원시 코드가 있습니다. 컴파일된 버전의 코드 한 줄도 놓치지 않아야 했기 때문에 악성코드에서 발견되는 것과 같은 최적화된 코드가 아닙니다.

HiveRansomwareV5_custom_keygen_PoC-optimized 폴더에는 위에서 언급한 원시 코드에서 파생된 최적화된 코드가 있습니다. 이 버전에서는 구현된 기능을 이해할 수 있도록 코드가 원시 코드보다 훨씬 읽기 쉽습니다.

두 버전 모두 실행 전에 사용자 이름으로 커스터마이즈해야 생성된 평문 키를 바탕 화면에 저장할 수 있습니다.

두 평문 키 모두 동일한 알고리즘을 사용하여 생성됩니다.
평문 키는 0xA00000 안전하게 무작위 생성된 바이트로 구성됩니다. 그런 다음 처음 0x2FFF00바이트를 끝에 복사하여 최종 0xCFFF00바이트 평문 키를 생성합니다.

memcpy2FFF00

그런 다음 Hive는 생성된 두 개의 키를 사용하여 파일을 암호화하지만, 먼저 Hive 랜섬웨어 v5는 생성된 키를 사용자 지정 구조체(이하 키스트림(keystreams) 이라고 함)로 암호화하여 .key 확장자를 사용해 암호화하는 각 드라이브의 루트에 배치합니다. 예를 들어 시스템에 C와 D 드라이브가 모두 설치되어 있다면 암호화된 키스트림이 각 드라이브의 루트에 존재하게 됩니다.

keysAtRoot

Hive 랜섬웨어 v5는 생성된 평문 키를 사용하여 XOR 명령어로 파일을 암호화하므로, 최신 x86/x64 CPU에서 매우 빠른 대칭 암호화에 해당합니다.

Hive v5가 자신을 보호하는 방법, 평문 키가 키스트림이 되는 방법

Hive 랜섬웨어 v5는 생성된 평문 키를 두 번 암호화하여 보호해야 하며, 이후 이를 라운드(rounds) 라고 부르겠습니다. 최종 키스트림을 얻으려면 두 번의 암호화 라운드가 필요합니다.

이를 위해 각 라운드에서 다음 단계가 수행됩니다:

  1. 키의 각 바이트를 생성하는 것과 동일한 알고리즘을 사용하여 32바이트 개인 키 생성;
  2. Diffie-Hellman 키 교환을 위해 Curve25519 타원 곡선 알고리즘을 사용하여, Hive는 방금 생성된 개인 키에서 공개 키를 파생;
  3. Curve25519를 다시 사용하여, Hive는 방금 생성된 개인 키와 Hive 제휴 파트너(affiliate)의 공개 키(모든 Hive v5 아티팩트마다 변경됨)로부터 공유 키를 생성;
  4. 개인 키 및 평문 키와 동일한 알고리즘을 사용하여 일종의 IV와 같은 24바이트 논스(nonce) 생성;
  5. HChaCha20 알고리즘을 사용하여 생성된 평문 키를 암호화할 키를 파생;
  6. 5단계에서 생성된 키와 4단계에서 생성된 논스를 사용하여, Hive는 XChaCha20 알고리즘으로 평문 키를 암호화합니다. 이 작업은 암호화 프로세스의 무결성을 보장하기 위해 16바이트 MAC(Message Authentication Code)도 생성합니다.

3단계는 암호화 중 Hive가 생성한 개인 키 쌍과 Hive 제휴 파트너가 우리를 위해 랜섬웨어를 컴파일할 때 생성한 개인 키 쌍, 두 쌍의 개인 키로 열 수 있는 키스트림의 생성을 보장합니다.

keystreamCreation

브루트포스의 배경 아이디어

이 설명의 끝에서 한 가지 특정 지점이 분명해집니다: 두 라운드의 암호화에 사용되는 평문 키, 개인 키 및 논스는 모두 위의 동일한 함수(0044ADE0, 일명 createByte)에 의해 생성됩니다. 함수 0044ADE0은 CPU가 for 루프 내에서 호출되는 코드를 실행하는 데 걸리는 시간에 의해 조건이 결정됩니다.

두 라운드의 암호화 이후 키스트림 구조를 강조한 위 그림을 살펴보면, 우리가 자유롭게 접근할 수 있는 것은 논스뿐이라는 것이 분명합니다 (그렇지 않으면 Hive 제휴 파트너는 파일을 해독하는 방법을 알 수 없을 것입니다).

그러니 24바이트 길이의 논스에 초점을 맞춰 보겠습니다:

NONCE: 40 A4 08 6C D0 D0 34 98 FC 60 C4 28 8C F0 F0 54 B8 1C 80 E4 48 AC AC 10

논스의 한 바이트와 다음 바이트 사이의 차이(절대값)는 한 반복과 다음 반복 사이에 경과된 시간을 나타냅니다. 이 정의로 핑거프린트(fingerprint)라는 개념을 소개합니다.

NONCE FINGERPRINT: 64 9c 64 64 00 9c 64 64 9c 64 9c 64 64 00 9c 64 9c 64 64 9c 64 00 9c

얻은 값을 분석하면 코드의 실행 시간이 거의 동일하며, 특히 사용 중인 프로세서의 기술로 인한 약간의 변동만 있음을 알 수 있습니다. (제 테스트에서는 10세대 i7 프로세서와 5세대 i5를 사용했으며, 다른 시스템에서는 이 핑거프린트가 다를 수 있습니다.)

논스가 평문 키, 그리고 무엇보다 개인 키를 생성하는 동일한 함수에 의해 생성된다는 점을 고려하면 이 발견은 매우 중요합니다. 언급된 이러한 값들도 이 원칙을 따르기 때문에, 즉 논스의 개별 바이트 간 차이는 예측 가능하므로 개인 키와 평문 키 값도 예측 가능할 것입니다.

그러나 분석 결과 Hive가 계산한 원래 평문 키와 동일한 바이트를 얻기 위해 0xA00000 문자 배열을 생성하는 것은 매우 어렵다는 것이 입증되었습니다: CPU 및 메모리 부하의 변동은 코드 실행 속도에 영향을 미치며, Hive PE가 계산한 원래 평문 키는 우리가 계산한 키와 (단 몇 바이트라도) 다른 경우가 많습니다.

우리는 이 논스 핑거프린트를 0xA00000바이트 길이의 가능한 사전 생성에서 얻은 핑거프린트와 비교하는 데 사용합니다(이 숫자는 경험적으로 고정되었으며, 일련의 테스트 후 통계적으로 이 바이트 수 안에 두 라운드의 암호화에 필요한 각각 32바이트인 두 개의 개인 키가 있다는 것이 확인되었습니다). 논스 핑거프린트가 사전 핑거프린트에 포함되어 있다면 두 개인 키를 모두 브루트포스하기 위한 올바른 사전을 찾은 것입니다.

여기서 끝나지 않습니다. 논스, 평문 키 및 개인 키의 생성에 대해 수행된 동적 분석에서 첫 번째 바이트는 거의 균일한 값을 가진 다른 모든 바이트와 비교하여 두 번째 바이트와 평균 거리가 다르다는 것이 검증되었기 때문입니다. 자세히 살펴보겠습니다:

hivePrivateKeyFingerprint

보시다시피 첫 번째 이후의 핑거프린트 값은 최소한의 변동을 겪습니다. 즉, 개인 키의 첫 번째 바이트와 두 번째 바이트 사이의 절대값 거리는 대부분의 경우 나머지 핑거프린트에 존재하는 값 범위를 벗어납니다.

아마도 이는 CPU에 존재하는 일부 최적화 알고리즘 때문이며, for 루프의 첫 번째 반복 이후 코드 실행 속도를 높이는 것과 관련이 있습니다.

가능한 해결책

제안된 코드는 각 키스트림 암호화 라운드의 논스를 읽고 핑거프린트를 결정하며 가능한 개인 키를 포함하는 가능한 키 사전 목록을 생성합니다.

항상 키의 나머지 부분과 다른 핑거프린트의 첫 번째 바이트와 관련된 문제를 해결하기 위해 다음과 같은 방법을 생각했습니다:

  1. 생성된 사전의 첫 0x110바이트의 고유 값을 취하여 가능한 선행 바이트 사전을 생성합니다;
  2. 생성된 사전의 두 번째 바이트부터 시작하는 모든 가능한 조합을 취하여 31바이트 목록을 생성합니다;
  3. 첫 번째 바이트와 나머지 생성된 31바이트의 조합을 만들어 가능한 32바이트 개인 키 조합을 생성하고, 여기서 공개 키를 파생하여 키스트림에 존재하는 우리가 보유한 공개 키와 비교합니다.

두 공개 키가 일치하면 두 번째(마지막) 암호화 라운드가 암호화된 개인 키를 찾은 것입니다. 지금까지 설명한 작업을 다시 반복하면 첫 번째 라운드의 암호화된 키스트림을 해독할 개인 키를 얻을 수 있으며, 마지막으로 원래 평문 키를 추출할 수 있습니다.

사용법

HiveRansomwareV5-keystream_decryptor 폴더에는 VS 2017 sln과 monocypher 맞춤형 라이브러리가 있습니다. 프로그램에서 수행할 작업을 선택할 수 있습니다.

programOptions

옵션 "1"은 PC 프로세서에 맞춤화된 바이트 사전을 만들 수 있으므로 가장 먼저 선택해야 합니다. 따라서 암호화된 머신에서 수행해야 합니다. 해당 키스트림에 존재하는 값과 동일한 값을 얻을 가능성이 훨씬 높기 때문입니다.

programOption1

또는 첫 번째 옵션이 작동하지 않으면 (이미 감염된 동일한 PC에서) 디버거에서 악성코드를 평문 키 생성이 끝날 때까지(for 루프 바로 밖) 실행하여 평문 키가 포함된 메모리 내용을 저장하여 자신만의 사전을 생성하십시오. 이 경우 옵션 "3"을 사용하여 사전을 검증할 수 있습니다:

programOption3

키스트림에 대한 올바른 사전을 확보하면 옵션 "2"는 개인 키 바이트 값에 어떤 식으로든 영향을 주지 않으면서 바이트 조합을 브루트포스하는 데 필요한 시간을 줄일 수 있는 더 강력한 컴퓨터에서도 수행할 수 있습니다.

programOption2_1 programOption2_2 programOption2_3

옵션 2의 기능을 제대로 수행하려면 공개 키를 추출해야 합니다. 모든 Hive 샘플이 동일하게 생성되는 것은 아니므로 범용 공개 키 추출기를 만드는 것은 그리 쉽지 않습니다. 그러나 작동하는 것으로 알려진 한 가지 방법은 논스 생성 후 디스어셈블된 이 부분에 중단점(breakpoint)을 설정하는 것입니다. 아래 증거에서 공개 키는 curve25519를 사용하여 공유 키를 파생하기 위해 함수 44E3D8에 전달됩니다. 악성코드 실행 전체에서 공개 키가 노출되는 유일한 곳입니다.

wherePublicKeyIsUsed

Visual Studio 옵션을 다룰 때 주의하시기 바랍니다. 디버그에서 릴리스로 또는 그 반대로 전환하면 사전 생성 바이트와 같은 프로그램 출력이 변경될 수 있습니다.

브루트포스 절차의 속도를 높이려면 코드에서 dictionary_dimension 값을 편집할 수 있지만, 사전 크기를 줄이면 개인 키를 찾을 확률도 낮아질 수 있다는 점에 유의하시기 바랍니다.

또한 Hive를 실행하고 메모리에서 덤프하여 생성된 평문 바이트 배열을 사용하기로 결정한 경우 dictionary_dimension 변수에 덤프 크기를 설정하는 것을 잊지 마십시오.

복호화 도구를 테스트하기 위해 dummy_data_PoC 폴더에 사용할 파일 몇 개를 제공했습니다:

  • BumAU1Ky.key (첫 번째 키스트림)
  • UMvObens.key (두 번째 키스트림)
  • a0h2uih3d2_01058000.bin (사전으로 사용할 Hive 실행 중 덤프된 평문 키)
  • dictionary.bin (샘플 사전)
  • public_key.txt (Hive 제휴 파트너의 공개 키 포함)

행운을 빕니다!

참고 자료

https://github.com/rivitna/Malware/blob/main/Hive/Hive_samples.txt

https://www.virustotal.com/gui/file/335d2e4a743d059955760ecf2ec25ee86d36aa60b096c9180e860c64ef78ee55

https://www.microsoft.com/security/blog/2022/07/05/hive-ransomware-gets-upgrades-in-rust/

https://docs.microsoft.com/en-us/windows/win32/sysinfo/acquiring-high-resolution-time-stamps

https://monocypher.org/manual/x25519

https://monocypher.org/manual/advanced/poly1305

https://monocypher.org/manual/advanced/chacha20

https://monocypher.org/manual/aead

도구 다운로드