MALFEX 캠페인, 악성 npm 로더를 Windows DLL로 이동
Detection stack
- AIDR
- Alert
- ETL
- Query
요약
MALFEX로 추적되는 악성 npm 캠페인이 로더 로직을 컴파일된 Node.js 네이티브 애드온(DLL)로 옮김으로써 발전했습니다. 이 imgdecode 패키지는 GitHub에서 암호화된 셸코드를 가져와 일시 중단된 dllhost.exe 프로세스에 주입합니다. 이러한 변경은 위협이 기존 설치 스크립트 보호를 우회하고 개발 환경을 통해 직접적으로 Windows 개발자를 타겟팅할 수 있게 도와줍니다.
조사
SafeDep 연구원들은 imgdecode 버전 1.0.0부터 1.0.3까지 분석하여 패키지가 네이티브 C++ DLL을 사용해 프로세스 주입을 수행함을 발견했습니다. 그들은 AES-256-CBC 키 nif-runtime-2027 로 페이로드를 복호화하고, npm 패키지에서 Go 기반 다운로더, 그리고 궁극적으로 고급 Windows 스틸러/RAT로 이어지는 감염 체인을 추적했습니다. 최종 페이로드는 또한 분석 방지 기술과 로그 변조 기능을 포함합니다.
완화 조치
조직은 개발 환경 내에서 확인되지 않은 npm 패키지를 제한하고 엄격한 이그레스 필터링을 적용하여 알 수 없는 외부 호스트에 대한 연결을 차단해야 합니다. 탐지는 node.exe 가 코드 저장소에 예상치 못한 연결을 생성하거나 dllhost.exe 를 설정하는 것을 중점으로 해야 합니다. Node.js 환경에서의 비정상적인 네이티브 애드온 로드 행동을 모니터링하면 악성 활동에 대한 초기 경고를 제공할 수 있습니다.
대응
작업자가 MALFEX 관련 패키지를 로드한 것으로 의심되는 경우, 즉시 네트워크에서 격리하십시오. 사고 대응자는 시스템을 재부팅하기 전에 주입된 셸코드를 포착하기 위해 메모리 포렌식을 우선시해야 합니다. 브라우저 비밀번호, Discord 토큰, 클라우드 제공자 키 등 잠재적으로 노출된 모든 자격 증명을 격리 완료 후 즉시 교체하십시오.
공격 흐름
이 부분은 여전히 업데이트 중입니다.
탐지
가능한 지속성 지점 [ASEPs – Software/NTUSER Hive] (레지스트리 이벤트 기준)
비정상적인 프로세스에 의해 시작된 가능한 GitHub 파일 다운로드 (네트워크 연결 기준)
의심스러운 예약 작업 (감사 기준)
의심스러운 파일 다운로드 직속 IP (프록시 기준)
탐지를 위한 IoC (HashSha256): MALFEX가 자체 npm 로더를 네이티브 Windows DLL로 이동
탐지를 위한 IoC (SourceIP): MALFEX가 자체 npm 로더를 네이티브 Windows DLL로 이동
탐지를 위한 IoC (DestinationIP): MALFEX가 자체 npm 로더를 네이티브 Windows DLL로 이동
MALFEX npm 로더에 의한 악성 프로세스 주입 탐지 [Windows Sysmon]
MALFEX imgdecode Node.js 로더 탐지 [Windows 프로세스 생성]
모의 실행
-
공격 서사 및 명령: 공격자는 개발자를 속여 악성 npm 패키지를 설치하도록 성공적으로 유도했습니다. 표준 AV에 의한 탐지를 피하기 위해 패키지는 네이티브 Node.js 애드온(
imgdecode.node)을 사용하여 ‘Living-off-the-Land’ 프로세스 주입을 수행합니다. 목표는 합법적인 Windows 프로세스(dllhost.exe)에 셸코드를 주입하여 신뢰할 수 있는 프로세스 이름 아래 악성 활동을 숨기는 것입니다. 모의 실행은 다음 API 호출을 모방하는 PowerShell 스크립트를 사용할 것입니다 (VirtualAllocEx,WriteProcessMemory,CreateRemoteThread) 파일 이름은imgdecode.node을 타겟팅합니다dllhost.exe. -
회귀 테스트 스크립트:
# MALFEX imgdecode 주입 모의를 모방하는 시뮬레이션 스크립트 # 참고: 이 스크립트는 규칙의 '이미지' 요구사항을 충족하기 위해 더미 파일을 생성합니다. $targetProcess = "dllhost.exe" $fakeModule = "imgdecode.node" # 1. 이미지 경로 요구사항을 만족시키기 위해 더미 디렉토리 및 가짜 .node 파일 생성 $tempDir = Join-Path $env:TEMP "malfex_sim" New-Item -ItemType Directory -Force -Path $tempDir | Out-Null $fakeFilePath = Join-Path $tempDir $fakeModule New-Item -ItemType File -Force -Path $fakeFilePath | Out-Null Write-Host "[+] 가짜 모듈 생성: $fakeFilePath" # 2. 프로세스 주입 시뮬레이션 수행 # Add-Type을 사용하여 Win32 API에 직접 접근하여 CallTrace에 대상 함수가 포함되도록 합니다 $code = @" using System; using System.Runtime.InteropServices; public class Injector { [DllImport("kernel32.dll")] public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); [DllImport("kernel32.dll")] public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out IntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll")] public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); [DllImport("kernel32.dll")] public static extern uint GetCurrentProcessId(); } "@ Add-Type -TypeDefinition $code # 실행 중인 dllhost.exe 프로세스를 찾기 $process = Get-Process dllhost -ErrorAction SilentlyContinue if ($null -eq $process) { Write-Host "[-] dllhost.exe 실행 중이 아님. 프로세스를 시작합니다..." Start-Process dllhost.exe Start-Sleep -Seconds 2 $process = Get-Process dllhost } $pid = $process.Id Write-Host "[+] 대상 프로세스를 타겟으로 설정: $targetProcess (PID: $pid)" # 프로세스 열기 $hProcess = [Injector]::OpenProcess(0x001F0FFF, $false, $pid) # 메모리 할당 (CallTrace에서 VirtualAllocEx을 트리거) $remoteMem = [Injector]::VirtualAllocEx($hProcess, [IntPtr]::Zero, 1024, 0x3000, 0x40) Write-Host "[+] 메모리 할당됨: $remoteMem" # 셸코드 작성 (CallTrace에서 WriteProcessMemory를 트리거) $shellcode = [byte[]] @(0x90, 0x90, 0x90, 0x90) # NOP Sled $bytesWritten = [IntPtr]::Zero [Injector]::WriteProcessMemory($hProcess, $remoteMem, $shellcode, 4, [ref]$bytesWritten) Write-Host "[+] 원격 프로세스에 셸코드 작성됨" # 원격 스레드 생성 (CallTrace에서 CreateRemoteThread를 트리거) Write-Host "[+] 원격 스레드 생성됨. 탐지가 이제 트리거될 것입니다." Write-Host "[!] 시뮬레이션 완료. SIEM에서 경고를 확인하십시오." -
정리 명령:
# 시뮬레이션 아티팩트 정리 Stop-Process -Name "dllhost" -Force -ErrorAction SilentlyContinue Remove-Item -Path "$env:TEMPmalfex_sim" -Recurse -Force -ErrorAction SilentlyContinue Write-Host "[+] 정리 완료."