1. 개요

[그림 1] Qilin 랜섬웨어
Qilin 랜섬웨어는 2022년 7월 ‘Agenda’라는 이름의
서비스형 랜섬웨어(Ransomware-as-a-Service, RaaS)로 처음 발견되었으며,
2022년 9월경 Agenda는 Qilin이라는 명칭으로 리브랜딩되었다.
Qilin은 중국 및 독립국가연합(CIS) 국가를 공격 대상에서 제외하는 경향이 있는 것으로 보고되었다.
이러한 지리적 비타격 패턴은
러시아어권 사이버범죄 조직에서 흔히 관찰되는 운영 방식과 일치하며,
이에 따라 Qilin은 러시아 기반의 RaaS 그룹에 의해 운영되는 랜섬웨어로 평가되고 있다.
Qilin은 대기업과 의료기관 등을 주요 표적으로 삼아 공격을 전개한다.
이들은 데이터 암호화와 정보 탈취를 병행하는 이중 갈취(Double Extortion) 전략을 사용하며,
피싱, 취약점 악용, 초기 접근 브로커(IAB) 활용 등 다양한 경로를 통해 침투하는 것이 확인되었다.
또한 자체 데이터 유출 사이트를 운영하며 협상 압박 수단으로 활용하는 등
조직화된 사이버범죄 생태계의 특징을 뚜렷하게 보여준다.

[그림 2] Rust로 제작된 Qilin
초기에 Go(Golang) 언어를 기반으로 개발된 것으로 알려졌으나,
이후 Windows뿐 아니라 Linux 및 ESXi 환경까지 지원하는 교차 플랫폼 구조의 변종들이 등장했다.
최근에는 Rust 기반으로 제작된 변종 또한 확인되어,
개발 언어의 다양화가 진행된 것으로 평가된다.
금번 분석 샘플 역시 Rust 기반으로 제작되었음을 PE 파일의 .rdata 영역에서 확인할 수 있었다.

[그림 3] 2025년 랜섬웨어 피해자 통계

[그림 4] 2025년 국내 랜섬웨어 피해자 통계
위협 인텔리전스 플랫폼 ransomware.live의 통계에 따르면
2025년 Qilin 랜섬웨어는 전 세계에서 가장 많은 피해 기업을 발생시킨 랜섬웨어 그룹으로 집계되었다.
국내 통계에서도 동일한 경향이 나타나
Qilin은 2025년 한국 내에서 가장 많은 랜섬웨어 피해를 야기한 그룹으로 확인되었다.

[그림 5] Qilin DLS(Data Leak Site)
실제로 2025년 4월 국내 제조업체 A사가 Qilin 랜섬웨어 공격을 받아
내부 데이터가 Qilin의 데이터 유출 사이트(DLS)에 게시된 사례가 확인되었으며,
같은 해 9월에는 국내 금융권 B사가 감염되어 내부 자료가 유출된 것으로 알려졌다.
이처럼 제조업·금융·IT 서비스 등 광범위한 산업군에서 피해 사례가 보고되고 있으며,
피해 규모와 데이터 유출량도 지속적으로 증가하는 추세이다.
──────────────────────────────────────────────
2. 정보
2.1 침해 지표
ㆍ EXE 실행파일 (SHA-256):
af10b3666750d3a48f8be743585423b699cd48bb102a44d41771ea1750bebb2a
2.2 MITRE ATT&CK
ㆍ Boot or Logon Autostart Execution: (T1547.001) Registry Run Keys / Startup Folder
ㆍ Defense Evasion: (T1497.001) System Checks
ㆍ Discovery: (T1007) System Service Discovery
ㆍ Impact:
(T1486) Data Encrypted for Impact
(T1490) Inhibit System Recovery
──────────────────────────────────────────────
3. 분석
3.1 랜섬웨어 로그 파일 생성
![]()

[그림 6] GetTempPathW
GetTempPathW API를 호출하여 Temp 디렉터리의 경로를 가져온다.

![]()
[그림 7] CreateDirectoryW
이후 CreateDirectoryW API를 사용하여 Temp 경로 하위에 QLOG 디렉터리를 생성한다.


[그림 8] CreateFileW

[그림 9] ThreadId(1).LOG
마지막으로 CreateFileW API를 통해 ThreadId(1).LOG 파일을 생성하고
Qilin 랜섬웨어의 동작 로그를 기록한다.
──────────────────────────────────────────────
3.2 실행 키 입력

[그림 10] 실행 키 입력
Qilin 랜섬웨어는 실행을 위해 암호가 요구된다.
단독 실행 시 “–password” 인자를 통해 실행 키를 요구하며, 입력된 암호의 유효성을 검증한다.
![]()
[그림 11] 유효한 실행 암호
유효한 실행 암호를 입력하면 “Password is correct” 메시지가 출력되며
랜섬웨어가 정상적으로 동작한다.
──────────────────────────────────────────────
3.3 관리자 권한 확인


[그림 12] GetCurrentProcess & OpenProcessToken
현재 실행 중인 프로세스(Qilin 랜섬웨어)의 핸들을 얻어온 뒤
OpenProcessToken API를 통해 토큰을 확인한다.
이때 두 번째 인자로 0x8(TOKEN_QUERY)을 전달하여
현재 실행 중인 프로세스의 액세스 토큰을 쿼리한다.

![]()

[그림 13] GetTokenInformation
이후 GetTokenInformation API에 두 번째 인자로 0x14(TokenElevation)를 사용하여
현재 접속 중인 계정의 토큰이 UAC 기준으로 권한이 상승된 토큰인지 여부를 조회한다.
즉, 관리자 권한 실행 여부를 확인함으로써
암호화 수행 시 더 많은 시스템 및 사용자 파일에 접근하려는 의도이다.

[그림 14] 일반 권한으로 실행된 Qilin 랜섬웨어
관리자 권한이 아닌 일반 권한으로 실행될 경우 에러 메시지를 출력하고 종료한다.
──────────────────────────────────────────────
3.4 옵션 로드
21E69B(암호화 확장자 및 블랙리스트 화이트리스트 지정)
![]()

[그림 15] 하드코딩 된 암호화 대상
0x0021E69B 번지에서 함수를 호출하면 하드코딩된 암호화 대상 및 예외 대상 목록이 로드된다.

[표 1] 암호화 제외 확장자

[표 2] 암호화 대상 특정 확장자

[표 3] 암호화 제외 파일

[표 4] 암호화 제외 디렉터리

[표 5] 암호화 대상 심볼릭 링크

[표 6] 종료 대상 프로세스

[표 7] 종료 대상 서비스
──────────────────────────────────────────────
3.5 뮤텍스 형성

![]()
![]()
[그림 16] CreateMutexW
랜섬웨어의 중복 실행으로 인한 이중 암호화를 방지하기 위해
CreateMutexW API를 호출하여 뮤텍스를 생성한다.
──────────────────────────────────────────────
3.6 콘솔 숨기기
![]()
[그림 17] FreeConsole
공격자에게 옵션 적용 여부를 확인시켜 준 뒤,
FreeConsole API를 호출하여 콘솔 창을 숨김으로써 백그라운드에서 동작하는 것처럼 보이게 한다.
──────────────────────────────────────────────
3.7 자동 실행 등록


[그림 18] RegSetValueExW
Qilin 랜섬웨어는 지속성을 확보하기 위해
자동 실행 등록 관련 레지스트리인
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run 경로에
자기 자신을 등록한다.
──────────────────────────────────────────────
3.8 프로세스 종료


[그림 19] OpenProcess
특정 프로세스가 동작 중일 경우 해당 프로세스가 점유한 파일의 암호화가 실패할 수 있으므로,
이를 방지하기 위해 프로세스를 강제 종료한다.

![]()
[그림 20] TerminateProcess
OpenProcess API로 종료시킬 프로세스의 핸들을 가져온 후
TerminateProcess API를 이용하여 종료시킨다.
──────────────────────────────────────────────
3.9 익명 파이프 생성



[그림 21] CreateNamedPipeW
자식 프로세스를 생성하기 전
CreateNamedPipeW API로 익명 파이프를 생성하여 자식 프로세스와의 통신을 준비한다.
──────────────────────────────────────────────
3.10 암호화 범위 확대



[그림 22] 원격-원격 심볼릭 링크 활성화
CreateProcessW API로 cmd 프로세스를 생성한다.
이때 인자로 /c fsutil behavior set SymlinkEvaluation R2R:1을 전달하여
원격-원격 간 심볼릭 링크를 활성화함으로써,
백업 스토리지 등 다른 공유 폴더에 접근할 수 있도록 설정한다.

[그림 23] 원격-로컬 심볼릭 링크 활성화
또한 /c fsutil behavior set SymlinkEvaluation R2L:1 명령어로
원격-로컬 간 심볼릭 링크를 활성화하여 로컬 PC에 대한 접근 권한을 확보한다.
CreateProcess 호출 시 dwCreationFlag에 0x8000000 값을 주어
윈도우 콘솔 없이 백그라운드에서 해당 명령어를 실행한다.
──────────────────────────────────────────────
3.11 네트워크 공유 목록 조회


[그림 24] net use
심볼릭 링크 활성화 후 /c net use 인자로 cmd 프로세스를 실행시켜
현재 연결된 네트워크 공유 폴더 목록을 조회한다.
──────────────────────────────────────────────
3.12 파일 복구 방해
Qilin 랜섬웨어는 암호화된 파일의 복구를 방해하기 위해
VSS 서비스를 조작하고 볼륨 섀도 복사본(Volume Shadow Copy)을 삭제한다.


[그림 25] vss 서비스 상태 변경
우선 서비스 wmic를 이용해서 실행 상태를 수동 실행으로 바꾼다.
이는 vss 서비스를 수동 실행으로 동작시켜 자동으로 백업 스냅샷을 생성하는 것을 막기 위함이다.

[그림 26] vss 서비스 시작
VSS 서비스가 활성화되어 있어야 섀도 복사본 삭제가 정상적으로 수행되므로,
삭제 전 VSS 서비스를 시작하여 동작을 보장한다.

[그림 27] volume shadowcopy 삭제
Qilin 랜섬웨어의 파일 암호화가 끝나면
파일 복구를 방해하기 위해 volume shadow copy를 삭제한다.


[그림 28] vss 서비스 중지 및 비활성화
volume shadows copy를 삭제한 후
추가적인 스냅샷 생성을 막기 위해 vss 서비스를 종료시키고 비활성화 시킨다.
──────────────────────────────────────────────
3.13 이벤트 삭제


[그림 29] 이벤트 로그 삭제

[표 8] powershell 실행 커맨드
CreateProcessW API로 PowerShell을 실행하여 윈도우 이벤트 로그를 삭제한다.
이는 초기 침투 흔적 및 래터럴 무브먼트 실행 흔적 등 공격 행위를 은폐하기 위함이다.
사용된 커맨드는 다음과 같다.
ㆍ Get-WinEvent -ListLog *: 모든 윈도우 이벤트 로그 조회
ㆍ Where-Object {$_.RecordCount}: 이벤트가 기록된 로그만 필터링
ㆍ Select-Object -ExpandProperty LogName: 로그 이름만 추출
ㆍ {[System.Diagnostics.Eventing.Reader.EventLogSession]::GlobalSession.ClearLog($l)}: 이벤트 삭제
──────────────────────────────────────────────
3.14 암호화

[그림 30] CreateThread
Qilin 랜섬웨어는 워커 스레드를 다수 생성하여 병렬적으로 암호화한다.
![]()
![]()
[그림 31] GetDriveTypeW & GetLogicalDrives
랜섬웨어는 파일을 암호화 하기 위해 드라이브 스캐닝을 하는데
이는 물리 디스크 뿐만 아니라 네트워크 드라이브, 이동식 디스크 등 여러 드라이브를 암호화 하기 위해서이다.
GetDriveTypeW API로 각 루트 드라이브의 유형을 확인하고
GetLogicalDrives API로 사용가능한 드라이브인지 확인한다.


[그림 32] GetVolumePathNamesForVolumeNameW
Qilin 랜섬웨어는 암호화를 확실하게 하기위해
DOS Drive Letter Path(C:\, D:\) 뿐만 아니라 볼륨 GUID 기반으로도 파일을 탐색한다.
FindFirstFileW의 핸들로 사용하기 위해
GetVolumePathNamesForVolumeNameW API로 볼륨 GUID를 가져온다.

![]()
![]()

[그림 33] FindFirstFileW & FindNextFileW
암호화에 필요한 파일을 찾기 위해 FindFirstFileW와 FindNextFileW API로 파일을 탐색한다.


[그림 34] 랜섬노트 생성
CreateFileW API의 5번째 인자인 dwCreationDisposition의 값에
1(CREATE_NEW)을 주어 랜섬노트를 생성한다.
랜섬노트 파일의 이름은 “README-RECOVER-고유식별 랜덤값”이고
해당 샘플의 랜덤값은 zTw1R7SFlb 이다.


[그림 35] 랜섬노트 쓰기
Qilin 랜섬웨어에 하드코딩 되어있는 랜섬노트를 파일에 쓴다.



[그림 36] 암호화 대상 핸들 획득
랜섬웨어가 파일을 암호화 하기 위해서는 해당 파일의 핸들을 획득해야한다.
CreateFile API의 5번째 인자인 dw Creation Disposition의 값에
3(OPEN_EXISTING)을 주어 해당 파일이 있는 경우 파일을 열어서 핸들을 획득한다.

![]()
[그림 37] 파일 이름 변경
랜섬웨어가 파일을 암호화 하기전
MoveFileEx API로 고유식별 랜덤값 형식으로 확장자를 변경하는데
파일 암호화 여부를 식별하기 위한 것으로 추정된다.


[그림 38] 재배치 반복문

[그림 39] 키 재배치
Qilin 랜섬웨어는 파일 전체 암호화 하기전 원본 파일의 마지막 부분에 패딩을 한다.
[그림 39]의 빨간 박스는 BCryptGenRandom으로 생성된 난수를 XOR 연산으로 재배치한 값이고
파란 박스는 SHA-256 해시값을 XOR 연산으로 재배치한 값이다.


[그림 40] 재배치 키 값 바이트 뒤집기
[그림 39]의 값은 이후 바이트를 역순으로 뒤집는 로직을 거쳐,
[그림 40]과 같은 최종 값이 생성된다.

[그림 41] NtWriteFIle

![]()
[그림 42] 패딩

[그림 43] 패딩된 원본 파일
NtWriteFile API로 원본 파일의 마지막 부분에 재배치된 값과 공백 문자열
그리고 파일의 끝을 나타내는 시그니처를 쓴다.


[그림 44] ZwReadFile
파일을 암호화 하기 위해 ZwReadFile API로 데이터를 읽어 온다.


[그림 45] AES-CTR 암호화

[그림 46] 암호화된 파일
Qilin 랜섬웨어는 AES-NI를 지원하는 CPU면 AES-CTR 알고리즘으로 암호화하고
지원하지 않는 CPU면 chacha20 알고리즘으로 암호화한다.
분석 환경의 CPU는 AES-NI를 지원하여 파일이 AES-CTR로 암호화 된다.


[그림 47] NtWriteFile
암호화된 데이터를 쓰기 위해 WriteFile API로 암호화된 데이터를 원본 파일에 쓴다.

[그림 48] 암호화된 파일
위 암호화 과정을 지나면 [그림 48]처럼 파일이 암호화되는 것을 알 수 있다.

![]()
![]()
[그림 49] 확장자 리네임
암호화가 끝나면 파일 확장자를 고유식별 랜덤값만 남기기 위해 MoveFileExW로 확장자를 변경한다.

[그림 50] 바탕화면 변경
암호화가 모두 끝나면 [그림 50]처럼 바탕화면 사진이 변경되며,
피해자가 피해사실을 파악할 수 있게 된다.
──────────────────────────────────────────────
4. Privacy-i EDR 탐지 및 대응


[그림 51] EDRCenter 탐지 정보

[그림 52] 에이전트 로그
Privacy-i EDR는 Qilin 랜섬웨어 탐지 후 프로세스 차단과 실시간 백업/복구 기능으로 대응 가능하다.
또한 레지스트리 등록을 통한 시작 프로그램 등록 행위와
볼륨 섀도 복사본 삭제를 통한 시스템 복구를 방해하는 행위도 탐지/차단 가능하다.

