SOC Prime Bias: 중간

20 May 2026 22:01 UTC

Phantom Stealer Analysis: Inside a Two-Layer Attack Chain

Author Photo
SOC Prime Team linkedin icon 팔로우
Phantom Stealer Analysis: Inside a Two-Layer Attack Chain
shield icon

Detection stack

  • AIDR
  • Alert
  • ETL
  • Query

요약

팬텀 스틸러는 악성으로 시작하는 두 단계 Windows 정보 도용 프로그램입니다 pdh.dll 로더로 시작하고 .NET 페이로드가 주입된 상태로 끝납니다 jsc.exe. 로더는 DLL 하이재킹, 프로세스 할로잉, 네이티브 AOT 컴파일을 사용하여 탐지 가능성을 줄입니다. 활성화되면 두 번째 단계 페이로드는 자격 증명, 브라우저 데이터, 암호화폐 지갑 정보, 클립보드 콘텐츠 및 다른 민감한 데이터를 도난하며, 복사된 지갑 주소를 공격자가 제어하는 값으로 교체할 수도 있습니다. 이 악성 코드는 상업적 범죄웨어로 판매되고 있으며 현재 활발한 공격에 사용되고 있습니다.

조사

연구원들은 로더가 자신을 복사하는 것을 발견했습니다 %APPDATA%MicrosoftRasManagementMpDlpService.exe 그리고 지속성을 유지하기 위해 Run 키를 생성합니다. 그런 다음 이중 RC4 암호화된 페이로드를 해독하고 이를 정지된 jsc.exe 프로세스에 주입하고 데이터 도난을 시작하기 전에 여러 가지 반분석 체크를 수행합니다. 내부 .NET 스틸러는 Chrome 127+ 앱 바운드 암호화를 우회할 수 있고, 스푸핑된 도메인을 사용하여 SMTP를 통해 도난된 정보를 내보냅니다. 별도의 스레드가 암호화 클리핑 및 키로깅 기능을 처리합니다.

완화

방어자는 비정상적인 pdh.dll 로드를 비시스템 경로에서 모니터링하고 DLL 하이재킹 위험을 줄이는 제어를 시행해야 합니다. 보안 팀은 또한 낯선 실행 파일이 %APPDATA%MicrosoftRasManagement 에 배치되는 것을 탐지하고 RasManSvc Run 키를 주의 깊게 감시해야 합니다. 행동 기반 탐지를 통해 jsc.exe을 포함한 프로세스 할로잉에 집중하고, 네트워크 모니터링은 식별된 명령 및 제어 도메인으로의 의심스러운 연결을 플래그해야 합니다. 브라우저 자격 증명 저장소를 추가로 강화하고 신뢰할 수 없는 애플리케이션에 대한 클립보드 접근을 더욱 엄격히 제어하면 노출을 줄일 수 있습니다.

대응

RasManagement 디렉터리 내에서 MpDlpService.exe 생성 및 관련 Run 레지스트리 키 변경을 알림. 주입된 코드가 있는 jsc.exe 프로세스를 조사하고 즉시 악의적인 활동을 종료하세요. 관련된 침해 지표를 수집하고 관련 파일을 격리한 후, 노출된 자격 증명 및 지갑 데이터를 확인하기 위해 포렌식 분석을 수행하세요. 영향을 받은 계정을 재설정하고 필요에 따라 영향을 받은 사용자에게 통보하세요.

공격 흐름

시뮬레이션 실행

전제 조건: 텔레메트리 및 베이스라인 사전 비행 점검이 통과해야 합니다.

이유: 이 섹션은 탐지 규칙을 트리거하기 위해 설계된 적대적인 기법(TTP)의 정확한 실행을 다룹니다. 명령과 서술은 식별된 TTP를 직접 반영하며 탐지 논리에서 예상되는 정확한 텔레메트리를 생성하는 것을 목표로 합니다.

  • 공격 내러티브 및 명령:
    적대자는 처음에 악성 페이로드(예: 역방향 셸 DLL)를 도난하여 사용자의 %APPDATA% 디렉터리에 저장합니다. 이를 허용된 호스트로 사용하여, 공격자는 새로운 프로세스를 생성하고 페이로드를 주입하며 실행을 재개합니다—이를 통해 jsc.exe 을(를) 수행합니다 T1055.012 and T1055.003.
    지속성을 보장하기 위해, 공격자는 악성 DLL을 %APPDATA%MicrosoftRasManagementMpDlpService.exe 에 복사하고 합법적 서비스 이름을 악용하여 로그인 시 실행되도록 서비스로 등록합니다 (T1620).

  • 회귀 테스트 스크립트:

    # ---------------------------------------------------------
    # 시뮬레이션된 적대자 스크립트 – 프로세스 할로잉 + 지속성
    # ---------------------------------------------------------
    
    # 변수
    $appData = "$env:APPDATAMicrosoftRasManagement"
    $loaderPath = Join-Path $appData "MpDlpService.exe"
    $maliciousDll = "$env:TMPmalicious.dll"   # 페이로드 대체 자리 표시자
    
    # 1. 지속성 디렉터리 준비
    New-Item -Path $appData -ItemType Directory -Force | Out-Null
    
    # 2. 더미 악성 DLL 드롭(시뮬레이션된 페이로드)
    #    실제 공격에서는 컴파일된 페이로드여야 합니다. 여기서는 0바이트 파일을 생성합니다.
    New-Item -Path $maliciousDll -ItemType File -Force | Out-Null
    
    # 3. DLL을 스푸핑된 서비스 위치로 복사
    Copy-Item -Path $maliciousDll -Destination $loaderPath -Force
    
    # 4. 복사된 파일을 가리키는 임시 서비스 등록(관리자 필요)
    $svcName = "MpDlpService"
    sc.exe create $svcName binPath= "`"$loaderPath`"" DisplayName= "Microsoft Ras Management Service" start= auto | Out-Null
    
    # 5. 서비스 시작(MpDlpService.exe 실행 유발)
    sc.exe start $svcName | Out-Null
    
    # 6. jsc.exe를 호스트로 사용하여 프로세스 할로잉 수행
    #    jsc.exe를 중단된 상태로 시작하고, 더미 페이로드로 메모리를 교체한 후,
    #    다시 재개합니다. 이는 PowerSploit의 Invoke-ProcessHollowing 함수를 사용합니다.
    function Invoke-ProcessHollowing {
        param(
            [string]$HostPath,
            [string]$PayloadPath
        )
        # .NET API 로드
        Add-Type @"
    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    public class Hollow {
      [DllImport("kernel32.dll")] public static extern bool CreateProcess(string appName, string cmdLine,
          IntPtr procSec, IntPtr threadSec, bool inherit, uint flags,
          IntPtr env, string cwd, ref STARTUPINFO si, out PROCESS_INFORMATION pi);
      [StructLayout(LayoutKind.Sequential)] public struct STARTUPINFO {
          public int cb; public string lpReserved; public string lpDesktop; public string lpTitle;
          public uint dwX; public uint dwY; public uint dwXSize; public uint dwYSize; public uint dwXCountChars;
          public uint dwYCountChars; public uint dwFillAttribute; public uint dwFlags; public short wShowWindow;
          public short cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput;
          public IntPtr hStdError;
      }
      [StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION {
          public IntPtr hProcess; public IntPtr hThread; public uint dwProcessId; public uint dwThreadId;
      }
    "@
        # 중단된 프로세스 생성
        $si = New-Object Hollow+STARTUPINFO
        $pi = New-Object Hollow+PROCESS_INFORMATION
        $si.cb = [Runtime.InteropServices.Marshal]::SizeOf($si)
        $CREATE_SUSPENDED = 0x00000004
        $ok = [Hollow]::CreateProcess($null, "`"$HostPath`"", [IntPtr]::Zero, [IntPtr]::Zero, $false,
            $CREATE_SUSPENDED, [IntPtr]::Zero, $null, [ref]$si, [ref]$pi)
        if (-not $ok) { Write-Error "중단된 프로세스를 생성하는 데 실패했습니다" ; return }
    
        # (페이로드 주입 단계 생략 – 실제 기법을 위한 자리 표시자)
        # 스레드 재개
        $RESUME_THREAD = 0x00000001
        [System.Runtime.InteropServices.Marshal]::WriteInt32($pi.hThread, 0, $RESUME_THREAD) | Out-Null
    }
    
    # 사용하여 할로잉 실행(진짜 jsc.exe를 호스트로 사용)
    $jscPath = "$env:SystemRootSystem32jsc.exe"
    Invoke-ProcessHollowing -HostPath $jscPath -PayloadPath $maliciousDll
    
    # ---------------------------------------------------------
    # 시뮬레이션 끝
    # ---------------------------------------------------------
  • 정리 명령:

    # 임시 서비스 종료 및 삭제
    sc.exe stop MpDlpService | Out-Null
    sc.exe delete MpDlpService | Out-Null
    
    # 로더 및 더미 페이로드 제거
    Remove-Item -Path "$env:APPDATAMicrosoftRasManagementMpDlpService.exe" -Force -ErrorAction SilentlyContinue
    Remove-Item -Path "$env:TMPmalicious.dll" -Force -ErrorAction SilentlyContinue
    
    # 선택 사항: 테스트로 시작된 남아 있는 jsc.exe 프로세스를 종료
    Get-Process -Name jsc -ErrorAction SilentlyContinue | Stop-Process -Force