위협분석보고서-genians

MS 사칭 피싱과 Dead-drop C2 기반 APT37 NarwhalRAT 분석

작성자: Genians | Jun 14, 2026 1:00:00 PM

◈ 주요 결과 (Key Findings)

  • Microsoft 계정 팀과 사이버 보안 안내문으로 위장한 스피어피싱 통해 초기 침투 수행
  • 악성 LNK 파일을 이용해 Compiled Python Script 기반 NarwhalRAT 설치 유도
  • 키로깅, 화면 캡처, USB 수집, 원격 명령 실행 등 다양한 정보탈취 행위 수행
  • 한국 경유지와 pCloud API를 Dead-drop Resolver로 활용하는 이중 C2 구조 운영
  • LNK, PowerShell 기반 연쇄 악용 행위를 탐지할 수 있는 EDR 정책 강화 필요



1. 개요 (Overview)

지니언스 시큐리티 센터(Genians Security Center)는 최근 Compiled Python 기반 악성코드가 지속적으로 유포되고 있는 사실을 확인했습니다. 본 위협은 2026년 5월 11일 공개된 「AI 딥페이크 사칭 캠페인 후속 Python 백도어 위협 분석」 보고서에서 확인된 공격 시나리오 및 TTPs와 높은 유사성을 보입니다.

이번 공격은 「[긴급] 일회용 인증코드(OTP) 반복 발생에 따른 보안 점검 안내」라는 제목의 스피어피싱 메일을 통해 수행되었습니다. 발신자는 'Microsoft 계정 팀'으로 표시되어 공식 계정 보안팀에서 발송한 것처럼 사칭하고 있으나, 실제 발신 도메인은 MS의 공식 소유 도메인이 아닌 것으로 확인되었습니다.

공격 메일은 MS 계정 보안 경고를 사칭한 본문을 포함하고 있으며, 수신자에게 계정 탈취 및 OTP 악용 가능성에 대한 불안감을 조성해 첨부파일 실행을 유도하는 방식으로 구성되었습니다. 메일 본문에서는 첨부된 안내문을 참고하도록 안내하지만, 실제 첨부파일은 HWP 문서가 아닌 ZIP 압축파일이며, 내부에는 악성 LNK 파일이 포함되어 있었습니다.

메일 본문은 최근 MS 계정에서 일회용 인증코드가 반복 생성되는 비정상 행위가 감지되었다고 안내하며, 이를 타인의 로그인 시도 또는 피싱 공격과 연관된 보안 위협으로 설명합니다. 또한 사용자가 요청하지 않은 인증코드를 입력하지 말고 비밀번호를 즉시 변경할 것을 권고하면서, 자세한 보안 위협 유형과 대응 방법은 첨부된 보안 안내문을 참고하도록 유도합니다.

이러한 구성은 수신자가 실제 보안 경고로 오인하도록 설계된 사회공학적 기법입니다. 위협 행위자는 보안 안내문으로 위장한 ZIP 파일을 통해 악성 LNK 실행을 유도하고, 이후 PowerShell 및 Batch 명령을 거쳐 Compiled Python 기반 NarwhalRAT 설치로 이어지는 다단계 감염 흐름을 구성한 것으로 분석됩니다.

[그림 1-1] 공격 흐름도

본 보고서에서는 한국 사용자를 주요 표적으로 하는 것으로 판단되는 NarwhalRAT 악성코드에 대한 심층 분석 결과를 다룹니다. 해당 악성코드는 내부에 키로깅, 화면 캡처, USB 수집, 원격 명령 실행 등 다양한 정보수집 기능을 통합하고 있습니다. 또한 위협 행위자가 C2 명령을 통해 각 기능을 선택적으로 활성화하는 수동 운영형 구조를 갖추고 있습니다.

악성코드는 작업 디렉터리 이름으로 naverwhale을 사용하고, 생성된 폴더에 Hidden 및 System 속성을 부여해 은닉성을 강화합니다. 이는 한국에서 널리 사용되는 네이버 웨일(Naver Whale) 브라우저로 위장하려는 의도로 해석되며, 한국 사용자를 주요 공격 대상으로 삼고 있음을 시사합니다.

이러한 특징을 근거로 지니언스 시큐리티 센터의 위협 분석 연구원은 해당 악성코드를 NarwhalRAT으로 명명했습니다. 이는 naverwhale 문자열과 북극해에 서식하며 긴 엄니를 지닌 고래 종류인 'Narwhal(일각고래)'을 결합한 이름입니다. 특히 '북극'이라는 상징성은 국가 배후 위협 행위자와의 연관성을 고려한 요소이며, 일각고래의 뿔처럼 보이는 뾰족한 엄니는 이번 공격의 스피어피싱, 즉 작살낚시형 표적 공격 특성과도 자연스럽게 연결됩니다.

또한 NarwhalRAT은 은닉 방식과 한국 사용자 표적성을 코드 내부의 문자열 및 동작 구조에 직접 반영하고 있다는 점에서, 기존 APT37 그룹의 대표 악성코드인 RokRAT과는 차별화된 특징을 보입니다.

C2 인프라 측면에서는 한국 내 웹사이트인 daehoat[.]com 및 novel21[.]co.kr을 주요 통신 경유지로 활용하는 동시에, pCloud 클라우드 스토리지 API 기반 통신 기능을 함께 구현하고 있습니다. 특히 코드 내부에서 folderid 및 auth 파라미터를 처리하는 pCloud 전용 루틴이 확인되었으며, 이를 통해 정상 클라우드 서비스를 Dead-drop Resolver 형태의 보조 C2 채널로 활용하도록 설계된 것으로 분석됩니다.

Dead-drop Resolver는 과거 첩보 활동에서 사용되던 'Dead-drop(비밀 전달 장소)' 개념에서 유래한 용어로, 위협 행위자가 실제 C2 서버 주소를 악성코드에 직접 포함하지 않고 경유지나 클라우드 저장소 등에 은닉해 둔 정보를 통해 전달하는 기법을 의미합니다. 즉 악성코드는 먼저 daehoat[.]com과 같은 중간 경유지에 접속하여 실제 C2 서버 또는 추가 통신 정보(액세스 토큰)를 조회한 후, 이를 바탕으로 pCloud와 같은 합법적인 클라우드 서비스와 통신을 합니다. 이러한 방식은 정상 웹 트래픽으로 위장할 수 있을 뿐만 아니라, 실제 C2 정보를 유연하게 변경할 수 있어 악성코드 수정 없이도 인프라 운영이 가능합니다. 또한 분석 과정에서 최종 C2 서버가 즉시 노출되지 않기 때문에 탐지 및 차단을 더욱 어렵게 만드는 특징이 있습니다.

이러한 구조는 주 통신 채널이 차단되더라도 클라우드 기반 경로를 통해 명령 전달과 데이터 교환을 지속하기 위한 것으로 보입니다. 또한 pCloud 접근 정보의 직접 노출을 줄여 위협 인프라의 은닉성과 운영 안정성을 높이려는 의도도 포함된 것으로 추정됩니다.

이에 따라 본 보고서에서는 실행 흐름, 환경 조건, 암호화 체계, C2 통신 구조, 명령 처리 및 정보수집 기능 순으로 기술적 분석 결과를 상세히 다루며, 함께 식별된 IoC 정보를 제공합니다.

 

2. 상세 분석 (Detailed Analysis)


2-1. 초기 유입 (Initial Access)

초기 유입은 스피어피싱 메일의 첨부파일 클릭을 통해 시작됩니다. 수신자가 메일 내 첨부파일을 실행하면 fe01.co[.]kr 경유지를 통해 '사이버 보안 주의 안내문(일회용 인증코드 악용 관련).zip' 파일이 다운로드됩니다.

다운로드된 ZIP 압축파일 내부에는 동일한 보안 안내문으로 위장한 '사이버 보안 주의 안내문(일회용 인증코드 악용 관련).lnk' 파일이 포함되어 있습니다.

[그림 2-1] 스피어피싱 이메일 화면

이는 정상 문서처럼 보이도록 파일명을 구성해 사용자의 실행을 유도하는 방식이며, 이후 단계에서 PowerShell 및 Batch 명령 실행을 통해 추가 악성코드 설치로 이어지는 초기 실행 매개체 역할을 수행합니다.

 

2-2. 실행 및 난독화 기법 (Execution & Obfuscation)

해당 LNK 파일의 내부 명령행은 CMD 환경변수 substring 치환을 이용해 실제 실행 명령을 은닉하는 형태로 구성되어 있습니다.

먼저 a805aae라는 임의의 문자열 변수를 설정한 뒤, %a805aae:~위치,1% 형식으로 특정 문자만 추출해 powershell, ExecutionPolicy, Bypass, Command, Start-Process, curl.exe 등의 명령어를 동적으로 복원합니다. 이는 정적 탐지와 단순 문자열 기반 분석을 회피하기 위한 난독화 기법입니다.

난독화를 해제하면 LNK 파일은 cmd.exe /k를 통해 PowerShell을 실행하며, -ExecutionPolicy Bypass 옵션으로 PowerShell 실행 정책을 우회합니다. 이후 C:\Windows\System32\curl.exe를 복사해 추가 다운로드에 사용하지만, 복사 대상 경로를 $env:TEMP+'uARKK20.exe' 형태로 단순 연결합니다.

이 과정에서 경로 구분자(\)가 포함되지 않아 실제 파일은 %TEMP%\uARKK20.exe가 아니라 C:\Users\<USER>\AppData\Local\TempuARKK20.exe 형태로 생성됩니다. 이 패턴은 「AI 딥페이크 사칭 캠페인 후속 Python 백도어 위협 분석」 보고서 때와 유사합니다.

정상 Windows 기본 도구인 curl.exe를 복사해 사용하는 방식은 보안 장비의 명령행 탐지를 우회하거나 실행 흔적을 흐리기 위한 목적으로 해석됩니다. curl.exe를 복사해 추가 파일 다운로드에 사용하는 방식은 시스템에 기본 탑재된 정상 도구를 악용하는 Living Off The Land Binaries(LoLBins) 형태의 기법으로 분류할 수 있습니다.

[그림 2-2] LNK 파일 내부 인자값

LNK 파일은 webhostingkorea[.]com 경유지에 contents 및 board 파라미터를 포함한 요청을 전송해 두 개의 파일을 순차적으로 다운로드합니다.

첫 번째 다운로드 파일은 %TEMP%\사이버 보안 주의 안내문(일회용 인증코드 악용 관련).hwp로 저장됩니다. 이 파일은 사용자가 기대한 보안 안내문처럼 보이도록 실행되는 미끼 문서 역할을 수행하는 것으로 판단됩니다.

두 번째 다운로드 파일은 %TEMP%\KHjWFcsE.bat로 저장됩니다. 이후 PowerShell은 해당 BAT 파일을 숨김 창 방식으로 실행합니다. 따라서 이 BAT 파일은 후속 악성코드 설치와 실행을 담당하는 실질적인 다음 단계 실행 스크립트로 판단됩니다.

 

2-3. 2차 페이로드 실행 (Secondary Payload Execution)

LNK 실행으로 다운로드된 KHjWFcsE.bat 역시 CMD 환경변수 substring 치환을 이용해 명령어를 난독화하고 있습니다. 배치파일은 먼저 a1373ro라는 문자열 변수를 선언한 뒤, %a1373ro:~위치,1% 방식으로 필요한 문자를 조합해 실제 명령을 복원합니다.

난독화 해제 결과, 해당 BAT 파일은 curl을 이용해 Python 공식 사이트에서 python-3.10.0-embed-amd64.zip 파일을 C:\Users\Public\temp012.zip 경로로 다운로드합니다. 이후 C:\Users\Public\AccountPictures\UserInerfacePicture 디렉터리를 생성하고, tar -xf 명령으로 다운로드한 Python Embedded 패키지를 해당 경로에 압축 해제합니다.

압축 해제 후에는 기존 python.exe를 삭제하고 pythonw.exe를 userscreen.exe로 변경합니다. 이는 Python 실행 시 콘솔 창이 노출되지 않도록 하기 위한 의도로 해석됩니다. 이후 임시 파일인 temp012.zip은 삭제됩니다.

다음 단계에서는 curl을 다시 사용해 webhostingkorea[.]com 경유지에서 추가 파일을 다운로드합니다. 다운로드된 파일은 UserInerfacePicture 경로에 config.cat이라는 이름으로 저장됩니다. 확장자는 .cat으로 위장되어 있으나, 분석 결과 정상적인 Windows 보안 카탈로그 파일이 아니라 Python 바이트코드(.pyc) 형식의 컴파일 파일로 확인되었습니다.

[그림 2-3] 복호화된 배치 파일 명령어

이러한 감염 흐름은 위협 행위자가 악성 실행 환경을 직접 포함하지 않고, 공식 Python Embedded 패키지를 외부에서 동적으로 내려받아 정상 소프트웨어 설치 행위처럼 위장하려는 전략으로 해석됩니다.

특히 Python 공식 배포 서버를 이용함으로써 네트워크 보안 장비에서 정상 트래픽으로 인식될 가능성을 높이고, 실제 악성 페이로드는 이후 단계에서 별도로 전달함으로써 초기 유입 단계의 탐지 가능성을 최소화합니다.

또한 공격 과정 전반에서 curl, tar, schtasks와 같은 정상 Windows 도구를 적극 활용하고, PowerShell 실행 정책 우회 및 CMD substring 치환 난독화 기법을 결합함으로써 정적 분석과 명령행 기반 탐지를 동시에 회피하려는 특징이 확인됩니다.

특히 최종 페이로드를 .cat 확장자로 위장한 점은 정상 Windows 카탈로그 파일처럼 보이도록 하기 위한 의도로 해석되며, 실제로는 Python 바이트코드 기반의 Compiled Python Script를 실행하도록 구성되어 있습니다.

지속성 확보 방식 역시 일반적인 악성 서비스 등록이나 Run 키 등록 대신 예약 작업(schtasks)을 이용하고 있으며, 실행 파일명을 userscreen.exe로 변경해 정상 사용자 인터페이스 구성요소처럼 위장하고 있습니다. 이러한 설계는 보안 담당자나 사용자가 프로세스 목록과 파일 경로를 확인하더라도 즉시 악성 여부를 인지하기 어렵게 만드는 효과를 가집니다.

결과적으로 위협 행위자는 정상 시스템 도구, 공식 배포 서버, 정상 파일 확장자 및 Windows 예약 작업 기능을 조합해 전체 공격 체인을 최대한 합법적인 시스템 동작처럼 보이도록 구성하고 있습니다. 이를 통해 초기 침투 이후 장기간 은닉 상태를 유지하면서도, 필요 시 추가 Python 기반 페이로드를 유연하게 교체하거나 업데이트할 수 있는 운영상의 이점까지 확보하려는 것으로 분석됩니다.

 

2-4. 지속성 확보 (Persistence)

KHjWFcsE.bat는 후속 페이로드인 config.cat의 지속 실행을 위해 Windows 작업 스케줄러를 등록합니다. 생성되는 작업명은 MicrosoftUserInterfacePicturesUpdateTackMachine으로, 정상 Microsoft 사용자 인터페이스 또는 계정 이미지 관련 작업처럼 보이도록 위장한 형태입니다.

해당 예약 작업은 1분 간격으로 반복 실행되도록 설정되며, C:\Users\Public\AccountPictures\UserInerfacePicture\userscreen.exe를 이용해 동일 경로의 config.cat 파일을 실행합니다.

여기서 userscreen.exe는 Python Embedded 패키지의 pythonw.exe의 이름을 변경한 파일이며, config.cat은 정상 Windows 보안 카탈로그 파일처럼 보이도록 확장자를 위장한 Python 바이트코드 파일입니다.

이 구조를 통해 위협 행위자는 사용자가 직접 파일을 실행하지 않더라도 config.cat 기반 후속 Python 페이로드가 주기적으로 실행되도록 지속성을 확보합니다.

또한 실행 경로와 파일명이 Windows 계정 이미지 및 사용자 인터페이스 구성요소처럼 보이도록 구성되어 있어, 일반 사용자는 물론 관리자의 수동 점검 과정에서도 악성 여부를 즉시 식별하기 어렵게 만듭니다.

C:\Users\Public\AccountPictures\UserInerfacePicture\userscreen.exe

C:\Users\Public\AccountPictures\UserInerfacePicture\config.cat

[표 2-1] 예약 작업 실행 명령

 

2-5. config.cat 분석 (config.cat Analysis)

config.cat 파일의 헤더에는 Python 바이트코드 파일에서 사용되는 매직 바이트(Magic Byte)가 확인되었습니다. 파일 시작 부분에는 아래와 같은 헤더(6F 0D 0D 0A) 값이 존재합니다.

[그림 2-4] config.cat 파일 헤더 구조

이는 Python 인터프리터가 .pyc 형태의 컴파일된 Python 바이트코드를 식별할 때 사용하는 헤더 구조와 일치합니다.

또한 헤더 이후에는 Python 코드 객체(Code Object)를 의미하는 0xE3 값이 이어서 확인되어, 해당 파일이 단순 데이터 파일이나 정상 Windows 보안 카탈로그(.cat) 파일이 아니라 Python 바이트코드 기반의 Compiled Python Script임을 보여줍니다.

즉, 위협 행위자는 실제 Python 기반 악성 페이로드를 .cat 확장자로 위장함으로써 사용자가 정상 시스템 파일로 오인하도록 유도하고, 보안 분석 과정에서도 즉각적인 식별을 어렵게 하려는 의도를 가진 것으로 분석됩니다.

해당 파일을 디컴파일한 결과, 파일 내부에는 추가 페이로드 로드, 실행 환경 구성, C2 통신 준비 등 후속 악성 행위로 이어지는 Python 기반 로직이 포함된 것으로 확인되었습니다. 따라서 config.cat은 단순 설정 파일이 아니라, 예약 작업을 통해 주기적으로 실행되는 후속 Python 페이로드 역할을 수행합니다.

config.cat은 실행 시 webhostingkorea[.]com C2로 접속해 명령 코드를 수신하고 이를 메모리상에서 실행하는 백도어 로더로 동작합니다. 이후 C2가 전달하는 명령에 따라 추가 BAT 파일을 다운로드하고 실행합니다.

이를 통해 위협 행위자는 감염 이후에도 기능을 동적으로 확장하거나 새로운 악성 모듈을 유연하게 배포할 수 있는 운영 구조를 확보합니다.

[그림 2-5] 디컴파일된 Python 코드

디컴파일 결과, config.cat 내부 코드는 주요 문자열을 그대로 노출하지 않도록 여러 단계의 문자열 난독화를 적용하고 있었습니다. 일반적인 Python 코드라면 모듈명, C2 주소, HTTP 헤더명 등이 평문으로 확인되지만, 이 파일은 chr() 함수를 이용해 문자를 하나씩 조합하거나, 문자열을 거꾸로 배치한 뒤 [::-1] 연산으로 다시 복원하는 방식을 사용합니다. 이를 통해 정적 분석 도구나 단순 문자열 검색만으로는 주요 기능과 통신 정보를 쉽게 파악하기 어렵게 구성되어 있습니다.

또한 필요한 모듈을 불러올 때도 일반적인 import os, import base64 형태를 사용하지 않고, getattr(__builtins__, "__import__") 방식으로 __import__ 함수에 간접 접근합니다. 이 방식은 코드상에서 명시적인 import 구문을 줄여 위협 분석가가 한눈에 사용 모듈을 파악하기 어렵게 만들며, 악성코드의 실제 기능을 숨기기 위한 의도적인 난독화 기법으로 해석됩니다.

분석 결과 코드 내부에서는 os, base64, urllib.request, urllib.parse, sys, io 모듈이 사용됩니다. 이 모듈들은 각각 사용자명 수집, Base64 인코딩·디코딩, C2 통신, POST 데이터 생성, 표준 출력 제어 및 실행 결과 수집에 활용됩니다. 특히 C2 URL, Cookie, User-Agent, data, utf-8과 같은 핵심 문자열도 동일한 방식으로 은닉되어 있어, 해당 파일이 단순 설정 파일이 아니라 원격 명령 수신과 결과 전송 기능을 갖춘 Python 기반 백도어 로더임을 보여줍니다.

 

2-6. AccountConfig.cat 분석 (AccountConfig.cat Analysis)

config.cat 실행 이후 후속 파일이 C:\ProgramData\GoogleDriveUpdateCheck 경로에 AccountConfig.cat 파일로 생성되는 것을 확인하고 채증하는데 성공했습니다.

해당 경로와 파일명은 Google Drive 업데이트 또는 계정 설정 파일처럼 보이도록 구성되어 있으며, 정상 소프트웨어 구성요소로 위장해 사용자의 의심을 줄이고 보안 점검 과정에서 식별을 어렵게 하려는 의도로 판단됩니다.

지니언스 시큐리티 센터의 위협 분석가는 특히 파일 크기 변화에 주목했습니다. 초기 단계의 config.cat 파일 크기가 7,318바이트인 반면, 후속 생성된 AccountConfig.cat 파일은 7,467,018바이트로 확인되었습니다. 이는 단순 설정 파일 수준을 넘어, 추가 악성 기능이나 대용량 페이로드가 포함된 후속 컴포넌트일 가능성을 시사합니다.

동일한 .cat 확장자로 위장하고 있지만, 해당 파일 역시 실제로는 Python 바이트코드 기반의 Compiled Python Script 형태로 구성된 것으로 확인되었습니다. 특히 내부에는 약 3만 3천 줄 이상의 대규모 난독화 코드가 포함되어 있습니다.

내부에는 Base64로 인코딩된 Payload와 SHA-256 기반 키 파생 루틴이 포함되어 있습니다. 여기서 Key Derivation Function(KDF)은 하나의 고정 문자열이나 비밀값을 그대로 사용하는 대신, Salt와 카운터 값을 조합해 필요한 길이의 키스트림을 생성하는 방식입니다. 즉 짧은 Seed 값을 Payload 복원에 사용할 수 있는 충분한 길이의 바이트열로 확장하는 역할을 수행합니다.

분석 결과, Base64 디코딩 데이터의 앞 16바이트는 Salt로 사용되며, 하드코딩된 aHAnLLtQrP8Ce 문자열은 Seed 또는 Key Material 역할을 합니다. 해당 루틴은 Seed, Salt, 4바이트 빅엔디언 카운터를 순차적으로 연결한 뒤 SHA-256 해시를 반복 적용해 암호화된 Payload 길이만큼 키스트림을 생성합니다. 이후 생성된 키스트림과 암호화된 Payload를 바이트 단위로 XOR 연산하여 원본 Payload를 복원합니다.

이는 카운터 기반 KDF와 유사한 커스텀 XOR 복호화 구조로 판단됩니다.

[그림 2-6] XOR 복호화 과정

XOR 복호화 이후 복원된 데이터의 시작 바이트에서 MZ 시그니처가 확인되어, 최종적으로 PE 기반 Payload가 메모리상에서 복원되는 구조임을 확인할 수 있습니다.

또한 해당 PE EXE의 컴파일 타임스탬프는 한국 표준시 기준 2026-04-30 18:07:49(KST)로 확인됩니다. 이는 저녁 시간대에 악성코드 빌드가 수행된 정황을 보여주며, 위협 행위자가 일반 업무시간 이후에도 개발과 테스트를 지속했을 가능성을 시사합니다.

 

2-7. NarwhalRAT 분석 (NarwhalRAT Analysis)

복호화가 완료되면 악성코드는 Python의 ctypes 모듈을 이용해 Windows 기능을 직접 호출합니다. 쉽게 말해, Python 코드 내부에서 Windows API를 실행해 복호화된 Payload를 별도의 파일로 저장하지 않고 메모리에서 바로 실행하는 방식입니다. 이러한 기법은 일반적으로 Fileless 실행 또는 인메모리(In-Memory) 실행 방식으로 분류됩니다.

ctypes는 Python 기본 라이브러리 중 하나로, Python 코드에서 DLL에 포함된 C 언어 기반 함수를 직접 호출할 수 있도록 지원하는 모듈입니다.

즉 단순한 Python 스크립트 기능을 넘어, Windows 운영체제의 저수준 기능까지 직접 제어할 수 있게 해주는 역할을 수행합니다. 일반적인 Python 프로그램은 파일 처리, 문자열 연산, 네트워크 통신 같은 고수준 기능 위주로 동작하지만, ctypes를 사용할 경우 kernel32.dll과 같은 시스템 DLL 내부 함수를 직접 호출해 메모리 조작이나 프로세스 제어 같은 저수준 동작도 수행할 수 있습니다.

먼저 악성코드는 VirtualAlloc() API를 호출해 새로운 메모리 공간을 확보합니다. 이 과정은 단순히 데이터를 저장할 공간을 만드는 것이 아니라, 해당 메모리에 읽기(Read), 쓰기(Write), 실행(Execute) 권한을 동시에 부여하는 단계입니다. 흔히 이를 RWX 메모리라고 부르며, 복호화된 코드를 메모리에 적재한 뒤 즉시 실행하기 위한 준비 과정에 해당합니다.

정상 프로그램 역시 메모리를 할당할 수는 있지만, 쓰기와 실행 권한을 동시에 가진 메모리를 생성하는 경우는 일반적인 애플리케이션에서는 흔하지 않습니다. 따라서 PAGE_EXECUTE_READWRITE 속성을 사용하는 메모리 할당은 셸코드 실행이나 인메모리 악성코드 로딩 과정에서 자주 관찰되는 대표적인 행위 중 하나로 알려져 있습니다.

이후 악성코드는 RtlMoveMemory() API를 이용해 복호화된 Payload를 앞서 확보한 메모리 영역으로 그대로 복사합니다. 즉 실행 파일을 디스크에 생성한 뒤 실행하는 방식이 아니라, 메모리 내부에 직접 실행 코드를 올리는 구조입니다. 이 때문에 보안 제품이 파일 생성 이벤트나 디스크 기반 실행 흔적만을 중심으로 탐지할 경우, 실제 악성 Payload가 탐지되지 않을 가능성이 존재합니다.

마지막 단계에서는 ctypes.CFUNCTYPE()를 사용해 Payload가 저장된 메모리 주소를 실행 가능한 함수 형태로 변환한 뒤 직접 호출합니다. 쉽게 말해, 특정 메모리 주소를 함수 시작 지점처럼 취급하고 실행 흐름을 해당 위치로 넘기는 방식입니다.

결과적으로 최종 Payload는 새로운 실행 파일 형태로 저장되거나 별도의 프로세스로 실행되지 않고, 현재 실행 중인 Python 프로세스 내부 메모리에서 그대로 동작하게 됩니다. 따라서 외형상으로는 정상적인 Python 기반 프로그램처럼 보일 수 있지만, 실제 악성 행위는 메모리 내부에서 수행됩니다.

[그림 2-7] Python ctypes 기반 인메모리 Payload 실행 흐름(Fileless)

이러한 구조는 파일 기반 탐지를 어렵게 만들 뿐 아니라, 분석 과정에서도 디스크 상의 최종 Payload 확보를 어렵게 만들어 위협 행위자에게 유리하게 작용할 수 있습니다.

이제부터는 메모리상에서 실행된 최종 PE Payload, 즉 NarwhalRAT 본체에 대한 내부 동작을 분석하겠습니다. 해당 Payload는 단순한 다운로더 수준을 넘어, 다수의 정보수집 기능과 원격 제어 기능을 통합한 다기능 RAT(Remote Access Trojan) 구조로 구현되어 있었습니다.

초기 실행 단계에서는 환경 검사, Mutex 생성, 작업 디렉터리 구성, 전역 설정 초기화 등의 준비 과정이 수행됩니다. 먼저 악성코드는 CPUID 기반 Hypervisor Vendor ID 문자열을 검사해 VMware, VirtualBox 및 기타 가상화 환경 여부를 판별합니다.

코드 내부에서는 "VMwareVMware" 및 "VBoxVBoxVBox" 문자열과 함께 " lrpepyh vr" 문자열 비교가 확인됩니다.

특히 " lrpepyh vr" 값은 Parallels 환경 식별용 대체 Vendor String으로 언급되는 값으로, Parallels가 "prl hyperv" 문자열을 엔디언 처리 불일치로 인해 " lrpepyh vr" 형태로 반환하는 경우를 고려한 문자열입니다.

따라서 해당 루틴은 VMware와 VirtualBox뿐 아니라 macOS 환경에서 Windows를 실행하는 Parallels Desktop 계열 가상화 환경까지 탐지하도록 구성된 Anti-VM 기능을 수행합니다.

while ( v9 );

v10 = strcmp((const char *)&v17, "VMwareVMware");

if ( v10 )

v10 = v10 < 0 ? -1 : 1;

if ( !v10 )

break;

v11 = strcmp((const char *)&v17, " lrpepyh vr");

if ( v11 )

v11 = v11 < 0 ? -1 : 1;

if ( !v11 )

return 3;

v12 = strcmp((const char *)&v17, "VBoxVBoxVBox");

[표 2-2] Anti-VM 기능

이는 일반 사용자 환경에서는 정상 동작을 수행하지만, 악성코드 분석용 가상 환경에서는 의도적으로 행위를 최소화하거나 분석 자체를 방해하기 위한 대표적인 Anti-Analysis 기법입니다. 특히 APT 계열 악성코드에서 자주 사용되는 방식으로, 자동화 샌드박스 분석 환경에서 실제 악성 행위가 수집되지 않도록 만들기 위한 목적을 가집니다.

환경 검사가 완료되면 악성코드는 중복 실행 방지를 위한 Mutex를 생성합니다. 코드 내부에서는 i5zJH9FL10cVd3sSW9eyWWErPJ 문자열이 Mutex 이름으로 사용되며, 동일한 Mutex가 이미 존재할 경우 프로세스를 즉시 종료합니다.

wcscpy(Name, L"i5zJH9FL10cVd3sSW9eyWWErPJ");

hMutex = CreateMutexW(nullptr, 0, Name);

if ( !hMutex || GetLastError() == 183 )

return 0;

[표 2-3] Mutex 생성

이는 동일 시스템에서 다중 인스턴스 실행으로 인해 충돌이 발생하거나 사용자의 이상 징후 인지가 높아지는 상황을 방지하기 위한 전형적인 RAT 계열 구조입니다.

이후 악성코드는 %APPDATA%\naverwhale 경로를 생성하고 Hidden 및 System 속성을 부여합니다. 해당 폴더는 키로그, 화면 캡처 이미지, 마이크 녹음 파일, 업로드 대기 파일 등 각종 수집 데이터를 저장하는 작업 디렉터리 역할을 수행합니다.

특히 naverwhale이라는 이름은 국내 사용자가 흔히 사용하는 네이버 웨일 브라우저를 연상시키도록 설계되어 있으며, 사용자나 관리자가 파일 경로를 확인하더라도 정상 브라우저 관련 폴더로 오인할 가능성을 높입니다.

strcpy(v10, "naverwhale");

strcat(Destination, v10);

FileAttributesA = GetFileAttributesA(Destination);

if ( FileAttributesA == -1 || (FileAttributesA & 0x10) == 0 )

{

CreateDirectoryA(Destination, nullptr);

SetFileAttributesA(Destination, 6u);

[표 2-4] naverwhale 디렉터리 생성

분석 과정에서는 NarwhalRAT이 단순 고정형 구조가 아니라, 런타임 중 동적으로 설정을 변경할 수 있는 구조라는 점도 확인되었습니다. 내부에는 약 1,700바이트 규모의 전역 설정 영역이 존재하며, 이 영역에는 C2 주소, 통신 암호, 기능 활성화 플래그, 업로드 경로, pCloud 관련 설정 등이 저장됩니다.

특히 cmserver:, caserver:, cdserver: 명령을 통해 C2 주소를 동적으로 변경할 수 있습니다.

strcpy(v115, "chcommpwd:");

v4 = sub_404EF0(v2, v115);

strcpy(Source, "Change Comm Pwd Arg is not correct");

if ( v4 )

{

v5 = (const char *)(v4 + 10);

if ( v4 == -10 )

{

v6 = Source;

LABEL_28:

sub_451D40(v6);

sub_451A80(a1);

return 11;

}

if ( !strlen((const char *)(v4 + 10)) || (v7 = strlen(v5), v7 > 0x1E) )

{

v6 = v147;

strcpy(v147, "Comm Pwd is Empty or too Long");

goto LABEL_28;

}

v8 = dword_499970 + 260;

v105 = (char *)(dword_499970 + 260);

*(_OWORD *)(dword_499970 + 260) = 0;

*(_OWORD *)(v8 + 16) = 0;

sub_404FA0(v7, v105, "%s", (char)v5);

strcpy(v153, "Ch Comm Pwd Completed: ");

sub_451D40(v153);

v9 = (char *)(dword_499970 + 260);

goto LABEL_33;

}

strcpy(v126, "cmserver:");

v10 = sub_404EF0(v2, v126);

strcpy(v164, "Ch Man Server Arg is not correct");

[표 2-5] C2 주소나 통신 암호를 동적으로 변경

또한 NarwhalRAT은 실행 지속성뿐 아니라 운영 설정 자체를 유지하기 위한 설정 지속성 구조도 함께 구현하고 있었습니다.

기존 .ent 설정 파일이 존재하지 않을 경우, 악성코드는 SHGetFolderPathA()를 이용해 %LOCALAPPDATA% 경로를 얻은 뒤 하위에 \Microsoft\Internet Explorer 디렉터리를 생성합니다.

이후 6자리 랜덤 문자열을 생성하고 .ent 확장자와 조합하여 %LOCALAPPDATA%\Microsoft\Internet Explorer\<random>.ent 형식의 암호화 설정 파일을 생성합니다.

if ( SHGetFolderPathA(nullptr, 28, nullptr, 0, pszPath) < 0 )

return 0;

v50 = 0;

v48 = 0;

v49 = 0;

strcpy(v47, "\\Microsoft\\Internet Explorer");

v47[29] = 0;

v0 = strlen(v47) + 1;

v1 = &v42;

while ( *++v1 )

;

qmemcpy(v1, v47, v0);

FileAttributesA = GetFileAttributesA(pszPath);

if ( FileAttributesA == -1 || (FileAttributesA & 0x10) == 0 )

SHCreateDirectoryExA(nullptr, pszPath, nullptr);

v51 = 0;

v52 = 0;

v53 = 0;

v54 = 0;

sub_4050F0(&v51, 6);

v44 = 'tne';

v46 = 0;

strcpy(Format, "%s\\%s.%s");

v45 = 0;

[표 2-6] .ent 파일 생성

해당 경로는 정상 Internet Explorer 구성 파일처럼 보이도록 위장되어 있으며, 위협 행위자는 이를 통해 시스템 재부팅 이후에도 이전 운영 설정과 C2 인프라 정보를 유지할 수 있도록 설계한 것으로 분석됩니다.

악성코드는 현재 동작 상태, 통신 암호 관련 값, 관리 C2 서버 주소, 데이터 서버 주소, 대체 서버 주소, 기능 활성화 상태를 하나의 설정 데이터 블록으로 구성합니다. 특히 키로깅, 화면 캡처, 마이크 녹음 등 주요 정보수집 기능의 활성화 여부는 별도 플래그 값으로 관리되며, 특정 기능이 활성화되면 해당 상태 역시 설정 파일에 함께 저장됩니다.

이 설정 데이터는 평문으로 저장되지 않고 Windows CryptoAPI 기반 AES-128 방식으로 암호화됩니다. .ent 설정 파일 암호화에 사용되는 내부 하드코딩 문자열은 !221aeAescde##2aefseseppl^12로 확인되었으며, 해당 문자열은 AES 키로 직접 사용되는 것이 아니라 SHA-256 해시와 CryptDeriveKey() 과정을 거쳐 AES-128 키로 파생됩니다.

앞서 설명한 .ent 설정 파일은 단순 저장 용도가 아니라, 악성코드 재실행 이후 운영 상태를 복원하는 데 사용됩니다. 시작 단계에서는 먼저 기존 .ent 파일 존재 여부를 확인한 뒤, 파일이 존재할 경우 내부 데이터를 복호화하여 메모리상 운영 설정 영역에 다시 로드합니다.

복호화된 설정 데이터에는 통신 암호, 관리 C2 서버 주소, 데이터 서버 주소, 대체 서버 주소, 기능 활성화 플래그 등이 포함되어 있으며, 이전 실행에서 활성화된 키로깅·화면 캡처·마이크 녹음 등의 정보수집 기능 상태 역시 함께 복원됩니다.

반면 .ent 설정 파일이 존재하지 않는 초기 감염 환경에서는 악성코드 내부에 하드코딩된 기본 운영 설정이 사용됩니다. 분석 결과 NarwhalRAT 내부에는 다음과 같은 C2 주소가 기본값으로 포함되어 있었습니다.

  • hxxp://www.daehoat[.]com/wp-content/uploads/2017/02/member.php
  • hxxp://www.novel21[.]co.kr/data/editor/2110/index.php

이러한 구조를 종합하면 NarwhalRAT은 단순히 단일 C2 서버에 의존하는 RAT가 아니라, 로컬 설정 파일 복원 기능과 다수의 C2 경유지를 함께 사용하는 다중 운영 구조를 갖추고 있는 것으로 분석됩니다. 특히 기존 설정 파일이 존재할 경우 이전 운영 상태를 그대로 복원하고, 설정 파일이 없더라도 내부에 하드코딩된 기본 C2 인프라를 통해 즉시 통신을 재개할 수 있도록 설계되어 있습니다.

또한 내부 코드에서는 pCloud API 기반 보조 통신 루틴 역시 함께 구현되어 있었습니다. folderid= 및 auth= 파라미터를 직접 처리하는 전용 코드와 api.pcloud[.]com 문자열 기반 분기 로직이 확인되었으며, 이를 통해 정상 클라우드 서비스를 Dead-drop Resolver 형태의 보조 C2 채널로 활용하는 구조를 가지고 있었습니다.

이는 특정 C2 서버가 차단되거나 압수되더라도 다른 경로를 통해 명령 전달과 데이터 탈취를 지속하기 위한 운영 안정성 확보 전략으로 해석됩니다. 또한 네트워크 관점에서는 정상 웹사이트 및 클라우드 서비스 접근처럼 보이기 때문에, 일반적인 보안 장비에서 악성 통신으로 식별하기 어려운 특징도 가지고 있습니다.

NarwhalRAT은 초기화와 C2 설정 복원이 완료되면 내부 명령 처리 루틴을 통해 C2 서버로부터 전달된 명령을 해석합니다. 수신된 문자열의 앞부분을 특정 명령 Prefix와 비교한 뒤 해당 기능을 실행하거나 관련 플래그 값을 변경하는 구조로 구현되어 있습니다.

이 방식은 명령어 전체를 복잡한 프로토콜로 파싱하는 구조가 아니라, startkcap:, startscap:, usb2local:, cmd:, cmdadm: 등과 같은 문자열 Prefix를 기준으로 기능을 분기하는 형태입니다. 따라서 C2 서버는 비교적 단순한 명령 문자열만 전달해도 감염 시스템에서 특정 기능을 활성화하거나 원격 명령을 실행할 수 있습니다.

분석 과정에서 확인된 명령 체계는 원격 명령 실행, 파일 업로드 및 다운로드, 화면 캡처, 키로깅, 마이크 녹음, USB 수집, 원격 클릭, 상태 조회 및 종료 기능으로 구분됩니다. 예를 들어 화면 캡처 기능은 startscap: 명령이 수신되면 활성화 플래그를 '1'로 변경하고, endscap: 명령이 수신되면 다시 비활성화하는 방식으로 동작합니다.

rcpy(SubStr, "startscap:");

if ( sub_404EF0((char *)(v1 + 24), SubStr) )

{

*(_BYTE *)(dword_499970 + 1104) = '1';

return 14;

}

strcpy(v121, "endscap:");

if ( sub_404EF0(v2, v121) )

{

*(_BYTE *)(dword_499970 + 1104) = '0';

return 14;

}

strcpy(v130, "startscaph:");

if ( sub_404EF0(v2, v130) )

{

*(_BYTE *)(dword_499970 + 1110) = '1';

return 14;

}

strcpy(v124, "endscaph:");

if ( sub_404EF0(v2, v124) )

{

*(_BYTE *)(dword_499970 + 1110) = '0';

return 14;

}

strcpy(v118, "startlcap:");

if ( sub_404EF0(v2, v118) )

{

*(_BYTE *)(dword_499970 + 1107) = '1';

return 14;

[표 2-7] 정보수집 명령어 루틴

약 30종 이상의 명령 Prefix 기반 제어 체계가 구현되어 있었으며, 화면 캡처, 키로깅, 마이크 녹음, 파일 업로드 및 다운로드, USB 수집, 원격 명령 실행, C2 설정 변경 등 다양한 기능을 원격으로 제어할 수 있도록 설계되어 있습니다.

[그림 2-8] Prefix 기반 명령 제어 체계

특히 USB 및 이동식 저장장치 수집 기능은 usb2local: 명령을 통해 수행됩니다.

해당 루틴에서는 수집 대상 경로를 C:\Users\Public\<random>\ 하위로 복사하기 위한 명령 문자열을 동적으로 생성하며, 내부적으로 xcopy /s /e /y /c /q /h /b 옵션을 사용합니다.

이 기능은 USB 또는 지정 경로 내부 파일을 사용자 눈에 띄지 않게 로컬 임시 수집 경로로 복사한 뒤, 이후 업로드 단계에서 탈취하기 위한 중간 수집(Staging) 구조로 볼 수 있습니다.

NarwhalRAT은 단순히 키 입력만 기록하는 수준을 넘어, 사용자의 현재 작업 환경을 파악하기 위해 활성 창 및 실행 중인 윈도우 정보를 수집하는 기능이 구현되어 있었습니다. 코드 내부에서는 GetForegroundWindow(), GetWindowTextA(), GetWindowThreadProcessId(), GetWindowPlacement() API 호출 흐름이 확인되었으며, 이를 통해 현재 활성화된 창 여부, 창 제목, 프로세스명 및 창 상태 정보를 수집하는 구조를 가지고 있었습니다.

다만 수집 과정에서 모든 창 정보를 그대로 기록하지는 않으며, 불필요한 시스템 창이나 입력 보조 프로세스는 필터링합니다.

구체적으로 KakaoTalkEdgeWnd, KakaoTalkShadowWnd, Program Manager, Microsoft Text Input Application, MSCTFIME UI 문자열이 포함된 항목과 ApplicationFrameHost.exe, TextInputHost.exe 프로세스는 수집 대상에서 제외됩니다.

sub_404FA0(v7, (char *)v27, "%s", (char)v6);

if ( GetWindowTextLengthA(TopWindow) )

{

GetWindowTextA(TopWindow, (LPSTR)v26, 260);

if ( !strstr((const char *)v26, "KakaoTalkEdgeWnd")

&& !strstr((const char *)v26, "KakaoTalkShadowWnd")

&& !strstr((const char *)v26, "Program Manager")

&& !strstr((const char *)v26, "Microsoft Text Input Application")

&& !strstr((const char *)v26, "MSCTFIME UI")

&& !strstr((const char *)v27, "ApplicationFrameHost.exe")

&& !strstr((const char *)v27, "TextInputHost.exe") )

{

v31 = 0;

v30 = 658803;

strcpy(v32, "Focus");

v8 = v32;

[표 2-8] 제외 조건 필터링

이러한 필터링은 창 목록 수집 과정에서 의미 없는 보조 창이나 운영체제 구성 요소를 제거하여 수집 데이터의 노이즈를 줄이기 위한 목적으로 판단됩니다. 특히 KakaoTalk 관련 식별 문자열을 별도로 처리하고 있다는 점은, 악성코드가 국내 사용자 환경을 고려하여 개발되었을 가능성을 시사합니다.

또한 이 함수에서 생성된 창 정보는 화면 캡처 결과와 함께 저장될 수 있으며, 별도의 키로깅 기능에서 수집된 키 입력 데이터와 연계될 경우 사용자가 어떤 프로그램이나 서비스에서 활동하고 있었는지까지 파악할 수 있습니다. 예를 들어 웹 브라우저, 메신저, 업무 시스템, 금융 서비스 등의 활성 창 정보와 입력 정보를 함께 분석함으로써 사용자 행위를 보다 정밀하게 추적할 수 있습니다.

수집된 키 입력 데이터는 즉시 외부로 전송되지 않고, 내부 작업 디렉터리인 %APPDATA%\naverwhale 하위에 임시 저장된 뒤 업로드 루틴에 의해 순차적으로 전송되는 구조를 가지고 있었습니다. 이러한 방식은 네트워크 트래픽을 분산시키고, 실시간 탐지를 어렵게 만들기 위한 전형적인 RAT 계열 정보탈취 방식과 유사합니다.

 

3. 위협 귀속 (Threat Attribution)


3-1. 과거 위협 사례

본 사례를 분석하는 과정에서, 2025년 5월 11일 Genians Security Center에서 공개한 보고서와 다수의 유사점이 확인되었습니다. 해당 공개 사례에서는 Python 기반 다단계 악성코드 감염 체계가 사용되었으며, LNK 바로가기 파일, BAT 기반 난독화, Python Loader, 다중 C2 구조 등이 핵심 특징으로 제시되었습니다.

이번 NarwhalRAT 사례 역시 초기 감염 흐름부터 실행 구조, 난독화 기법, Python 기반 Payload 구성, 작업 스케줄러 지속성, C2 운영 방식 등에서 기존 공개 사례와 높은 수준의 유사성을 보였습니다. 특히 단순 IoC 중복 수준이 아니라, 공격자가 사용하는 개발 습관과 운영 방식(TTPs) 자체가 상당 부분 일치하는 점이 확인되었습니다.

우선 스피어피싱 단계에서 사용된 HWP 미끼 문서의 제작 방식이 기존 사례와 매우 유사했습니다. 경찰청 수사관을 사칭했던 사이버범죄 신고시스템(ECRM).hwp 문서와 이번 공격에 사용된 사이버 보안 주의 안내문(일회용 인증코드 악용 관련).hwp 문서는 모두 마지막 저장자명이 Lailey로 동일하게 확인되었습니다. 또한 정상 HWP 문서를 비교한 결과, 제목만 변경되었을 뿐 본문 구성과 내용은 대부분 동일한 형태를 유지하고 있었습니다.

특히 두 문서의 제목 구성 역시 유사한 패턴을 가지고 있었습니다.

  • 사이버범죄 신고시스템(ECRM) 안내 및 활용 절차 보고서
  • 사이버 보안 주의 안내문(일회용 인증코드(OTP) 악용 관련)

이는 동일 위협 행위자가 기존 정상 문서를 기반으로 제목만 교체해 스피어피싱 미끼 문서를 재활용했을 가능성을 시사합니다.

[그림 3-1] 미끼 문서 비교

LNK 바로가기 기반 초기 실행 구조 역시 높은 유사성을 보였습니다. 두 사례 모두 배치파일 내부에서 환경변수 치환 기반 문자열 난독화 기법을 사용하고 있었으며, LNK 구조 측면에서도 Link Flags, Obfuscation Pattern 등이 매우 유사했습니다. 또한 BAT 파일명과 curl.exe 파일명을 랜덤 문자열 형태로 변경하는 방식 역시 동일하게 확인되었습니다.

[그림 3-2] LNK 설정 비교

더불어 C2 서버 인프라 일부가 일치하였으며, BAT 파일명 역시 GuFLjO7q.bat에서 KHjWFcsE.bat 형태로 변경되었지만, 전체 실행 흐름과 난독화 구조는 동일한 패턴을 유지하고 있었습니다.

Payload 구조 역시 기존 사례와 상당 부분 일치했습니다. 두 사례 모두 .cat 확장자를 사용한 Python 바이트코드(.pyc) 기반 Payload를 사용하고 있었으며, 작업 스케줄러(Task Scheduler)를 이용한 지속성 확보 방식도 동일하게 구현되어 있었습니다. 또한 Python 바이트코드 내부의 문자열 난독화 구조와 복호화 흐름 역시 매우 유사한 형태를 보였습니다.

더불어 pCloud 인프라가 쓰인 점도 과거 APT37 계열 활동에서도 반복적으로 언급된 특징 중 하나이며, 특히 주 통신 채널 차단 이후에도 운영 지속성을 확보하기 위한 전형적인 다중 C2 운영 방식과 유사한 특징을 가집니다.

또한 NarwhalRAT은 naverwhale 작업 디렉터리 사용, KakaoTalk 관련 창 처리, 한국 웹사이트 기반 C2, HWP 미끼 문서 등 한국 사용자 환경을 강하게 의식한 구조를 가지고 있었습니다.

상기 정황을 종합하면, 본 사례는 기존 공개된 Python 백도어 공격 사례와 높은 수준의 유사성을 공유하고 있으며, 특히 한국 대상 사회공학 기법, Python 기반 Loader 구조, 환경변수 기반 BAT 난독화, 수동 운영형 RAT 구조, pCloud 기반 보조 통신 구조 등에서 공통점이 확인되었습니다.

No

Analysis Area

Correlation Evidence

1

Overall Campaign Structure

본 사례는 2025년 5월 11일 Genians Security Center에서 공개한 Python 기반 백도어 위협 사례와 높은 수준의 유사성을 보였습니다.

2

Spear-phishing Lure Document

경찰청 수사관 사칭에 사용된 사이버범죄 신고시스템(ECRM).hwp 문서와 이번 공격에 사용된 사이버 보안 주의 안내문(일회용 인증코드 악용 관련).hwp 문서는 모두 마지막 저장자명이 Lailey로 동일하게 확인되었습니다.

3

Decoy Document Reuse Pattern

HWP 문서는 제목만 변경되었을 뿐, 본문 구성과 내용은 대부분 동일한 형태를 유지하고 있었습니다. 이는 기존 정상 문서를 기반으로 제목만 교체해 스피어피싱 미끼 문서를 재활용한 정황으로 볼 수 있습니다.

4

Social Engineering Theme

보안 경고 등 한국 사용자를 대상으로 한 사회공학 테마를 사용하고 있었으며, 구성 패턴 역시 매우 유사했습니다.

5

LNK Obfuscation Structure

BAT 파일 내부에서 환경변수 치환 기반 문자열 난독화 기법을 사용하고 있었습니다. 또한 Link Flags, Extra Blocks, Argument Shape, Obfuscation Pattern 등 LNK 구조 자체가 일치했습니다.

6

BAT / Utility Naming Pattern

BAT 파일명과 curl.exe 파일명이 랜덤 문자열 형태로 생성되는 방식이 동일하게 확인되었습니다.

7

C2 Infrastructure Similarity

한국 웹사이트 기반 C2 인프라를 사용하고 있었으며, 일부 C2 서버 인프라가 중복되거나 운영 방식이 매우 유사했습니다.

8

Python Loader Payload Structure

.cat 확장자를 사용한 Python 바이트코드(.pyc) 기반 Payload를 사용하고 있었으며, Python Loader 기반 실행 구조와 문자열 난독화 방식이 동일합니다.

9

Persistence Technique

작업 스케줄러(Task Scheduler)를 이용한 지속성 확보 방식이 동일하게 구현되어 있었습니다.

10

Python Bytecode Obfuscation

Python 바이트코드 내부에서 문자열 난독화 및 복호화 루틴이 동일한 패턴으로 구현되어 있었으며, 환경변수 기반 BAT 실행 흐름과 연계되는 구조 역시 일치했습니다.

11

Multi-C2 Operation

일반 HTTP 기반 C2 외에도 다중 통신 경로를 함께 사용하는 구조가 확인되었습니다. 이는 단일 인프라 차단 이후에도 운영 지속성을 유지하기 위한 APT37 계열 운영 방식과 유사합니다.

12

pCloud Auxiliary Channel

pCloud 기반 보조 통신 구조가 확인되었습니다. 이러한 정상 클라우드 서비스 기반 보조 채널 운영 방식은 과거 APT37 계열 활동에서도 반복적으로 언급된 특징 중 하나입니다.

13

Korea-focused Targeting

naverwhale 작업 디렉터리 사용, KakaoTalk 관련 창 처리, 한국 웹사이트 기반 C2, 한국어 HWP 미끼 문서 등 한국 사용자 환경을 강하게 의식한 구조가 확인되었습니다.

14

TTP-level Similarity

전체적으로 Python 기반 Loader 구조, 환경변수 기반 BAT 난독화, 수동 운영형 RAT 구조, pCloud 기반 보조 통신 구조 등에서 높은 수준의 TTP 유사성이 확인되었습니다.

[표 3-1] 유사성 비교표

 

4. 결론 및 대응 (Conclusion)


4-1. 위협 캠페인 결론

본 보고서에서는 한국 사용자를 주요 표적으로 하는 Python 기반 RAT 악성코드인 NarwhalRAT의 전체 감염 흐름과 내부 동작 구조를 분석하였습니다.

분석 결과, 해당 위협은 단순 정보탈취 악성코드 수준을 넘어, 스피어피싱 기반 초기 침투, 다단계 다운로드 구조, BAT 기반 문자열 난독화, Python Loader, 인메모리 실행(Fileless Execution), AES 기반 암호화 통신, 다중 C2 운영 구조, 선택적 정보수집 기능 등을 통합한 고도화된 수동 운영형 RAT 구조를 가지고 있는 것으로 확인되었습니다.

초기 감염 단계에서는 ZIP 압축 내부의 LNK 바로가기 파일을 이용해 사용자의 실행을 유도하였으며, 이후 BAT 스크립트가 환경변수 치환 기반 문자열 재조합 기법을 사용해 실제 명령을 동적으로 복원하는 구조가 확인되었습니다. 이 과정에서 PowerShell, curl.exe, Python Runtime 등이 순차적으로 호출되며, 최종적으로 .cat 확장자로 위장된 Python 바이트코드 기반 Payload가 다운로드되는 다단계 감염 흐름을 구성하고 있었습니다.

특히 NarwhalRAT은 암호화 설정 파일을 생성해 관리 C2 서버, 데이터 서버, 대체 서버, 통신 암호, 기능 활성화 상태 등을 AES-128 기반으로 암호화 저장하는 구조가 확인되었습니다. 이를 통해 위협 행위자는 감염 시스템 재부팅 이후에도 이전 운영 상태와 수집 기능 활성화 상태를 그대로 복원할 수 있도록 설계한 것으로 분석됩니다.

명령 처리 구조 측면에서는 약 30종 이상의 Prefix 기반 원격 명령 체계가 구현되어 있었으며, 키로깅, 화면 캡처, 마이크 녹음, 파일 업로드/다운로드, USB 수집, 원격 명령 실행, 원격 클릭, C2 설정 변경 등의 기능이 포함되어 있었습니다.

종합적으로 NarwhalRAT은 Python 기반 다단계 Loader와 인메모리 실행 구조, 다중 C2 운영 체계, 선택적 정보수집 기능을 통합한 고도화된 RAT 악성코드로 판단됩니다. 또한 본 위협은 기존 공개된 Python 기반 APT37 공격 사례와 높은 수준의 구조적·운영적 유사성을 공유하고 있으며, 향후에도 유사한 변종 형태로 지속 활용될 가능성이 존재합니다.

따라서 조직에서는 단순 IOC 기반 탐지뿐 아니라, LNK 실행 이후 BAT 기반 환경변수 난독화 행위, Python Runtime 기반 비정상 메모리 실행, RWX 메모리 할당, 작업 스케줄러 생성, pCloud 기반 비정상 통신 등 행위 기반 탐지 체계를 함께 강화할 필요가 있습니다.

 

4-2. 'Genian Insights E' 기반 통합 대응 전략

본 위협은 한국 사용자를 대상으로 한 스피어피싱 기반 초기 침투 이후, LNK 바로가기 파일, BAT 기반 문자열 난독화, Python Loader, 인메모리(Fileless) 실행, 작업 스케줄러 지속성, 다중 C2 통신 구조를 단계적으로 결합한 복합 공격으로 확인되었습니다.

특히 최종 Payload가 Python ctypes 기반 메모리 실행 구조를 사용하고, 키로깅·화면 캡처·마이크 녹음·USB 수집 기능을 C2 명령으로 선택적으로 활성화하는 수동 운영형 RAT 형태를 가지고 있다는 점에서, 단순 파일 탐지 중심의 보안 체계만으로는 전체 공격 흐름을 식별하기 어려운 특징을 가집니다.

따라서 초기 유입부터 실행, 지속성 확보, 메모리상 Payload 동작, C2 통신, 정보수집 행위까지 전체 공격 체인을 가시화하고, 각 이벤트 간 상관관계를 기반으로 위협 행위를 분석·차단할 수 있는 EDR(Endpoint Detection and Response) 중심의 통합 대응 체계가 필요합니다.

'Genian Insights E'는 단일 에이전트 기반의 통합 엔드포인트 보안 플랫폼으로, NarwhalRAT과 같은 Python 기반 다단계 공격에 대해 다음과 같은 행위 기반 탐지 및 대응 기능을 제공합니다.

EDR은 공격 흐름 전체를 행위 기반으로 추적·분석할 수 있으며, 본 사례에서 확인된 다음과 같은 행위를 식별할 수 있습니다.

  • 압축파일 내부의 LNK 바로가기 실행
  • LNK → cmd.exe → BAT → PowerShell 기반 다단계 실행 흐름
  • 환경변수 치환 기반 문자열 난독화 명령 실행
  • curl.exe 또는 LOLBins 기반 외부 Payload 다운로드
  • 작업 스케줄러(Task Scheduler) 생성 및 반복 실행 등

특히 Genian Insights E는 단순 프로세스 생성 이벤트만 제공하는 것이 아니라, 부모-자식 프로세스 관계(Process Tree), 명령행(Command Line), 메모리 행위, 파일 생성, 네트워크 연결 이벤트 등을 통합적으로 분석할 수 있습니다.

또한 LnKTarget 정보를 통해 바로가기(LNK) 파일이 참조하는 난독화된 BAT 파일의 원본 내용을 확인할 수 있어 초기 실행 단계부터 분석이 가능합니다. 이를 바탕으로 BAT 난독화 이후 실제로 실행된 명령까지 연계 추적할 수 있어, 공격 흐름 전반에 대한 가시성을 제공합니다.

[그림 4-1] EDR을 통해 의심스러운 LNK 파일을 탐지한 모습

Genian Insights E의 Attack Storyline 기능을 통해 LNK 파일이 어떤 배치 파일 명령을 수행했는지 커맨드라인 기반으로 쉽게 파악할 수 있습니다.

이러한 정보는 보안 관리자가 EDR을 통해 위협 흐름을 분석하는 데 유용하게 활용될 수 있습니다.

[그림 4-2] powershell.exe 커맨드 라인 조회 화면

cmd.exe를 통해 난독화된 BAT 명령어가 실행되면, 이후 powershell.exe 프로세스에서 수행된 Command Line을 확인할 수 있습니다. 해당 명령은 정상 Windows 유틸리티인 curl.exe를 LoLBins 기법으로 악용하여, TEMP 상위의 Local 경로에 TEMPuARKK20.exe라는 이름으로 복사한 후 실행합니다. 이를 통해 실제로는 curl.exe를 사용하면서도 다른 실행 파일처럼 위장하여 행위를 은닉하려고 합니다.

이후 webhostingkorea[.]com C2 서버에 접속하여 정상 HWP 문서를 TEMP 경로에 미끼 파일로 저장한 뒤 실행하며, 추가 배치파일인 KHjWFcsE.bat를 다운로드 및 실행하여 후속 악성 행위를 수행하게 됩니다.

[그림 4-3] PowerShell과 curl.exe를 통한 C2 접속 화면

이와 같은 행위 기반 분석 정보를 통해 EDR 관리자는 위협의 초기 유입부터 실행, 추가 페이로드 다운로드 및 실행에 이르는 공격 체인을 직관적으로 추적할 수 있습니다. 이를 통해 위협을 신속하고 정확하게 식별하는 것은 물론, 위협 행위자의 활동과 그 영향을 종합적으로 분석하여 효과적인 대응 방안을 수립할 수 있습니다.

[그림 4-4] userscreen.exe 파일로 위장된 pythonw.exe 행위 화면

지속성 확보를 위해 예약 작업으로 등록된 userscreen.exe(=pythonw.exe)의 실행 Command Line을 직관적으로 확인할 수 있으며, 이를 통해 악성 코드의 실행 경로와 동작 방식을 쉽게 파악할 수 있습니다. 또한 C2 서버와의 통신 흐름을 함께 확인할 수 있습니다.



5. IoC (Indicator of Compromise)

  • MD5

3715092aa00f380cefe8b4d2eddb7d08

7cef19f9c4480adac0cd4702ff98f46c

7eb9cee1f696727752169f25cf79a338

b6b0602310bb2d4360c52685119aac1b

  • C2

crwellfood[.]com

daehoat[.]com

fe01.co[.]kr

novel21.co[.]kr

webhostingkorea[.]com

121.254.222[.]10

121.254.222[.]80

211.239.157[.]126

218.150.78[.]198

218.150.78[.]231

61.100.9[.]206