SOC Prime Bias: Critical

16 Oct 2026 07:55 UTC

MALFEX 캠페인, 악성 npm 로더를 Windows DLL로 이동

Author Photo
SOC Prime Team linkedin icon 팔로우
MALFEX 캠페인, 악성 npm 로더를 Windows DLL로 이동
shield icon

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] (레지스트리 이벤트 기준)

SOC Prime 팀
2026년 10월 15일

비정상적인 프로세스에 의해 시작된 가능한 GitHub 파일 다운로드 (네트워크 연결 기준)

SOC Prime 팀
2026년 10월 15일

의심스러운 예약 작업 (감사 기준)

SOC Prime 팀
2026년 10월 15일

의심스러운 파일 다운로드 직속 IP (프록시 기준)

SOC Prime 팀
2026년 10월 15일

탐지를 위한 IoC (HashSha256): MALFEX가 자체 npm 로더를 네이티브 Windows DLL로 이동

SOC Prime AI 규칙
2026년 10월 15일

탐지를 위한 IoC (SourceIP): MALFEX가 자체 npm 로더를 네이티브 Windows DLL로 이동

SOC Prime AI 규칙
2026년 10월 15일

탐지를 위한 IoC (DestinationIP): MALFEX가 자체 npm 로더를 네이티브 Windows DLL로 이동

SOC Prime AI 규칙
2026년 10월 15일

MALFEX npm 로더에 의한 악성 프로세스 주입 탐지 [Windows Sysmon]

SOC Prime AI 규칙
2026년 10월 15일

MALFEX imgdecode Node.js 로더 탐지 [Windows 프로세스 생성]

SOC Prime AI 규칙
2026년 10월 15일

모의 실행

  • 공격 서사 및 명령: 공격자는 개발자를 속여 악성 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 "[+] 정리 완료."