프로세스 인젝션은 사이버 보안에서 가장 중요한 기술 중 하나입니다. 이 기술은 이미 실행 중인 다른 프로세스의 주소 공간에 코드를 삽입하고 해당 공간에서 코드를 실행하는 방식으로 작동합니다. 보안 관점에서 이는 진정한 재앙입니다. 대상 프로세스의 권한으로 코드가 실행되므로, 대상 프로세스의 기존 권한 상승, 탐지 메커니즘 등을 이용해 보안 통제를 우회할 수 있기 때문입니다.
프로세스 주입은 인터넷과 고급 지속적 위협(APT). 소프트웨어 개발 환경에서 애플리케이션 디버깅이나 확장을 위한 유효한 기술이지만, 위협 행위자들은 이를 악용해 무단 코드 실행, 지속성 회피, 탐지 회피를 시도합니다.본 블로그에서는 프로세스 주입의 원리, 핵심 메커니즘, 일반적인 기법, 탐지 방법 및 방어 방안을 분석합니다. 또한 메모리 조작, 주입 기법, 탐지 방법, 실제 공격 사례 등 기본 개념도 살펴보겠습니다.
프로세스 주입이란 무엇인가?
프로세스 주입은 코드를 다른 실행 중인 프로세스의 메모리 공간에 주입할 수 있게 합니다. 이 기법에서 공격자는 대상 프로세스의 주소 공간에 자신의 코드를 작성하여 임의의 코드를 실행하도록 강제합니다. 주입된 코드는 취약한 프로세스의 컨텍스트와 권한 아래에서 실행되므로, 해당 프로세스의 모든 접근 권한과 시스템 내 신뢰 수준을 상속받습니다.
프로세스 주입은 핵심적으로 다음과 같은 기술적 구성 요소로 이루어집니다: 프로세스 핸들 획득, 대상 프로세스 내 메모리 할당, 코드 쓰기 작업, 실행 트리거 메커니즘. 이들은 OpenProcess(), VirtualAllocEx(), WriteProcessMemory(), CreateRemoteThread()와 같은 Windows API 함수를 사용하여 주입 프로세스를 실행합니다.
프로세스 주입이 위험한 이유?
여러 기술적 측면으로 인해 이 공격 유형은 상대적으로 위험합니다. 주입된 스레드에서 실행되는 코드는 대상 프로세스와 동일한 권한을 가지므로, 사실상 시스템에 대한 상승된 접근 권한을 부여합니다. 이 방법은 안전하지 않은 코드가 메모리에만 존재하기 때문에 파일 기반 보안 스캔을 우회합니다.또한 시스템 안정성과 보안에 심각한 영향을 미칩니다. 주입 작업은 대상 프로세스에 의해 중단될 수 있으며 시스템 전반에 불안정성을 초래합니다. 보안 제품 프로세스를 종료하고, 보호된 애플리케이션에서 데이터를 탈취하며, 일반적인 정리 기법을 회피하는 지속적인 시스템 접근을 확립함으로써 이를 달성합니다.
프로세스 메모리 기초
프로세스 주입 기법의 기술적 기반은 프로세스 메모리 구조와 작동 방식에 대한 이해입니다. Windows OS 메모리 관리 모델의 내부적 특징은 프로세스 간 메모리 상호작용과 접근을 가능하게 하기도 하고 제한하기도 합니다. 이는 프로세스 주입의 작동 방식과 방어자가 이를 탐지하고 방어하는 방식을 즉각적으로 변화시킵니다.
가상 메모리와 프로세스 주소 공간
각 Windows 프로세스는 동일한 시스템에서 실행되는 다른 프로세스와 격리된 고유한 가상 주소 공간을 가집니다. 이 가상 주소 공간의 범위는 32비트 프로세스의 경우 0부터 0x7FFFFFFF까지, 64비트 프로세스의 경우 0부터 0x7FFFFFFFFFF까지입니다. 가상 주소에서 물리 메모리 위치로의 매핑은 Windows 메모리 관리자가 페이징 기법을 통해 수행합니다.
프로세스는 주소 공간 내에 실행 코드, 로드된 DLL, 힙 할당 영역, 스택 공간 등 여러 영역을 가집니다. 이러한 영역들은 각각 특정 기능과 데이터 유형을 지닙니다. Windows에는 메모리 프레임 페이지의 위치와 가상 주소 공간 내 존재 여부를 설명하는 페이지 테이블이 있습니다.
메모리 권한 및 보호
메모리 영역에 대한 접근 권한이 존재하며, 이는 프로세스가 해당 영역과 상호작용하는 방식을 규정합니다. 이러한 권한에는 다음이 포함됩니다:
- PAGE_EXECUTE: 메모리를 코드로 실행할 수 있음
- PAGE_READ: 메모리를 읽을 수 있음
- PAGE_WRITE: 메모리에 쓰기가 가능합니다.
- PAGE_EXECUTE_READ: 메모리를 실행하고 읽을 수 있습니다.
- PAGE_EXECUTE_READWRITE: 메모리를 실행, 읽기, 쓰기 가능
이러한 권한은 Windows 메모리 관리자에 의해 페이지 수준에서 강제 적용됩니다. 애플리케이션(또는 프로세스)이 허용되지 않은 방식으로 메모리에 접근하려고 하면 시스템은 액세스 위반을 발생시킵니다.
&메모리 작업에 중요한 Windows API
Windows에는 메모리 조작을 위한 몇 가지 중요한 API가 있습니다. 이 API들은 프로세스 주입의 기본 구성 요소입니다. 이 함수들의 'Ex' 버전은 외부 프로세스를 위한 것이며, 일반 후속 버전은 호출 프로세스의 메모리 공간을 위한 것입니다. 이러한 API를 이해하면 잠재적인 주입 활동 탐지 및 추적이 가능합니다.
- VirtualAlloc/VirtualAllocEx: 프로세스 내 메모리를 예약 및 할당합니다.
- VirtualProtect/VirtualProtectEx: 메모리 영역 권한 변경
- ReadProcessMemory: 다른 프로세스의 메모리 공간에서 데이터 읽기
- WriteProcessMemory: 다른 프로세스의 메모리 공간에 데이터를 기록합니다
- VirtualFree/VirtualFreeEx: 할당된 메모리 영역을 해제합니다
프로세스 주입 기법의 유형
프로세스 주입은 대상 프로세스에 대한 일종의 코드 실행을 활용하는 여러 가지 기법으로 구성됩니다. Windows API 호출과 메모리 조작 방식의 차이로 인해 각 기법마다 고유한 작동 패턴과 탐지 시그니처가 존재합니다.
이러한 기법을 분석하면 보안 팀이 특정 주입 방법을 식별하고 대응하는 데 큰 도움이 될 수 있습니다.
1. DLL 주입
DLL 주입은 프로세스가 악성 DLL 파일을 강제 로드하도록 하는 과정입니다. OpenProcess(), VirtualAllocEx(), CreateRemoteThread() API 함수 세트를 사용합니다. 먼저 대상 프로세스 내부에 DLL 경로를 저장할 메모리를 예약합니다. 그런 다음 원격 스레드를 시작하여 해당 경로를 매개변수로 LoadLibrary()를 호출함으로써 대상 프로세스에 악성 DLL을 로드하도록 지시합니다.
주입된 DLL은 대상 프로세스의 전체 메모리 공간 주소와 대상이 메모리에 로드한 모든 모듈에 대한 접근 권한을 가지며, 대상 프로세스의 기능/프로세스에 대한 완전한 접근 권한을 보유합니다.
2. 코드 주입
코드 주입은 악성 코드를 프로세스 메모리 공간에 주입하여 해당 코드를 실행시키는 공격 방식입니다. 이는 단순히 프로세스 메모리 공간의 주소에 코드를 기록하는 것입니다. 이 기술은 프로세스에 대한 핸들을 획득하고, VirtualAllocEx()를 사용하여 메모리를 할당하며, WriteProcessMemory()로 코드를 기록한 후, 마지막으로 CreateRemoteThread()를 통해 실행하는 다단계 기법입니다.
실행되는 코드는 대상 프로세스의 권한을 가지며, 모든 보안 권한과 접근 권한이 상속됩니다.
3. 스레드 실행 탈취
스레드 실행 탈취는 대상 프로세스 내 스레드를 일시 중지시킨 후, 실행 컨텍스트를 공격자 코드로 변경하여 실행을 계속합니다. 이 기술에서 공격자는 SuspendThread(), GetThreadContext(), SetThreadContext(), ResumeThread() API를 활용합니다.
합법적인 스레드를 사용하기 때문에, 탈취된 스레드가 기존 권한으로 악성 코드를 실행하므로 탐지하기가 더 어렵습니다.
4. APC(비동기 프로시저 호출) 주입
APC 주입은 스레드가 대기 상태에 진입할 때 실행될 악성 코드를 대기열에 등록합니다. 이 방법은 QueueUserAPC()를 사용하여 스레드에 코드를 대기열에 추가합니다. 스레드에 주입된 코드는 해당 스레드가 APC 큐를 처리할 때 실행되며, 이는 일반적으로 특정 시스템 호출이나 대기 작업 중에 발생합니다. 이 방법은 가변 상태를 반복적으로 방문하는 스레드에 적합합니다.
5. 반사적 DLL 주입
반사적 DLL 주입 방식은 Windows 로더의 도움을 받아 DLL을 로드하며 파일 시스템에 흔적을 남기지 않습니다. 이는 메모리 내 매핑 및 주소 지정 방법을 지시하는 사용자 정의 DLL입니다. 이 기법은 로더 코드와 DLL을 대상 프로세스 메모리에 주입하고 로더를 실행하여 DLL을 준비하는 것을 포함합니다. 이는 일반적인 DLL 로딩 메커니즘과 모니터링에 의한 탐지를 피합니다.
6. 프로세스 할로잉
프로세스 할로잉은 공격자가 정당한 프로세스를 일시 중지 상태로 생성(CREATE_SUSPENDED 옵션의 CreateProcess 사용)한 후, 원래 메모리 공간을 해제(NtUnmapViewOfSection/ZwUnmapViewOfSection 사용), 새 메모리를 할당(VirtualAllocEx)하고, 악성 코드를 작성(WriteProcessMemory)하며, PE 헤더와 재배치 정보를 수정하고, 프로세스 환경 블록(PEB)을 업데이트한 후, 마지막으로 실행을 재개하기 전에 진입점을 리디렉션(SetThreadContext)하는 기법입니다. 이를 통해 악성 코드는 합법적인 프로세스의 신원과 권한으로 실행될 수 있습니다.
프로세스 주입은 어떻게 작동하나요?
프로세스 주입은 대상 프로세스에서 코드를 실행하기 위해 일련의 단계를 따릅니다. 주입 방법에 상관없이, 기술적 구현은 프로세스 메모리를 조작하고 프로세스 흐름의 실행 방식을 변경하는 특정 단계를 따릅니다.
첫 번째는 대상 프로세스 식별 및 접근 획득 작업입니다. 악성 프로세스는 OpenProcess()를 사용하여 대상 프로세스에 대한 핸들을 얻습니다. 이 핸들에 필요한 접근 권한은 PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE 및 PROCESS_VM_READ입니다.
두 번째 중요한 단계는 대상 프로세스에서 메모리를 할당하는 것입니다. VirtualAllocEx()는 가상 메모리의 페이지를 예약하고 커밋하여 대상 프로세스 주소 공간에 메모리 공간을 할당합니다.
세 번째 단계는 할당된 메모리 영역에 셸코드를 복사하는 것입니다. WriteProcessMemory()는 소스 버퍼에서 대상 프로세스 메모리 영역으로 코드 바이트를 복사합니다. 이 작업은 정렬 및 크기 요구 사항을 고려해야 합니다.
실행 트리거링의 마지막 단계는 최종 핵심 구성 요소를 나타냅니다. 각 기술은 다음과 같은 메커니즘을 사용합니다.
- CreateRemoteThread()는 주입된 코드를 실행하기 위해 새 스레드를 생성합니다.
- QueueUserAPC()는 기존 스레드에서 코드 실행을 대기열에 추가합니다.
- SetThreadContext()는 기존 스레드 실행 흐름을 수정합니다.
- 함수 포인터 또는 후크의 직접 수정
실행이 시작되면, 주입된 코드는 대상 프로세스의 컨텍스트 내에서 실행되며 대상 프로세스의 리소스와 보안 토큰에 접근할 수 있습니다. 이 코드는 대상 프로세스의 권한과 신뢰 수준 아래에서 실행되며, 설계된 대로 어떤 작업이든 수행할 수 있습니다.
프로세스 주입 공격을 탐지하는 방법?&프로세스 주입은 시스템의 여러 구성 요소와 동작을 포함하기 때문에 탐지하기 어렵습니다. 주입 활동을 식별하려면 보안 시스템이 메모리 이동, API 호출 및 모든 프로세스 동작을 모니터링해야 합니다. 이러한 탐지 방법들은 결합되어 전반적인 탐지 전략을 형성합니다. 메모리 패턴 분석
메모리 패턴 분석
메모리 분석은 프로세스 메모리 영역에서 흔히 발견되는 패턴을 탐색하는 데 중점을 둡니다. 이는 보안 도구가 프로세스 메모리의 권한 설정과 예상되는 콘텐츠를 확인하기 위해 해당 영역을 스캔하기 때문입니다. 여기에는 프로세스 내에서 일반적인 콘텐츠 시그니처에 부합하지 않는 비정상적인 실행 가능 영역 및 페이지 탐지가 포함됩니다.
메모리 스캐너는 일반적으로 정적인 프로세스 메모리 구조의 변경 사항을 모니터링하거나 동적 코드 세그먼트를 탐색함으로써 원본 프로세스 바이너리와의 편차를 찾습니다.
API 호출 모니터링
Windows API 모니터링을 통해 의심스러운 메모리 조작 호출 시퀀스를 탐지합니다. 보안 도구는 프로세스 접근을 위한 OpenProcess(), 메모리 할당을 위한 VirtualAllocEx(), 메모리 쓰기를 위한 WriteProcessMemory()를 모니터링합니다. CreateRemoteThread()와 같이 스레드가 생성되거나 조작되는 경우, 이는 주입의 명확한 신호입니다.
SuspendThread() 및 SetThreadContext()와 같은 API를 통한 프로세스 및 스레드 상태 변경도 모니터링해야 합니다. 이는 주입 체인에서 흔히 발견되기 때문입니다.
행동 지표
프로세스 행동 모니터링은 이러한 주입 시도를 암시하는 예상치 못한 활동 패턴을 식별하기 위해 수행됩니다. 침입 탐지 시스템은 비교적 안정적으로 실행 중인 프로세스의 스레드와 프로세스 메모리 맵의 변경 사항을 관찰하여 이러한 프로세스를 추적합니다.
이러한 행동은 임포트 주소 테이블 수정 및 프로세스 간 메모리 작업과 함께 탐지에 중요한 지표가 됩니다.
탐지 도구
프로세스 주입을 탐지하려면 심층 모니터링 기능을 갖춘 보안 도구가 필요합니다. 실시간 분석은 API 호출과 시스템 동작을 감시하는 프로세스 모니터가 수행하며, 메모리 분석 도구는 프로세스 메모리 공간을 심층 분석합니다. 이벤트 로그 분석기를 통해 팀은 시스템 내 보안 이벤트의 이력을 기록하여 과거 상황을 파악할 수 있습니다.
SentinelOne와 같은 엔터프라이즈 탐지 및 대응(EDR) 솔루션은 다양한 모니터링 방식과 분석 기능을 결합합니다. 프로세스 모니터 및 프로세스 탐색기와 같은 시스템 관리 도구가 있으며, 프로세스별 메모리 할당량뿐만 아니라 프로세스를 상세하게 표시합니다.
프로세스 주입 공격을 방지하는 방법?
프로세스 주입에 대한 방지는 단일 보안 제어로는 제공될 수 없으며 시스템, 프로세스 및 코드 수준의 제어가 필요합니다. 이러한 완화 조치는 프로세스 주입 기능을 제한하고 잠재적 대상 프로세스에 대한 주입을 어렵게 만드는 데 중점을 둡니다.
시스템 수준 예방
시스템 수준의 예방 조치는 접근 및 권한의 올바른 관리에서 시작됩니다. 시스템은 비관리자 사용자가 시스템의 민감한 프로세스에 대한 핸들만 열 수 있도록 프로세스 생성 및 조작 권한을 구성해야 합니다. 이러한 제한은 사용자 계정 제어(UAC) 및 AppLocker 정책을 통해 어떤 프로세스가 어떤 권한 수준에서 실행될 수 있는지 관리함으로써 시행됩니다.
코드 서명
또 다른 중요한 예방 계층은 코드 서명 적용입니다. 모듈은 디지털 서명이 검증된 상태로 로드되어야 하며, 부적절하게 서명되었거나 서명되지 않은 코드는 시스템에서 거부되어야 합니다. Windows Defender 애플리케이션 제어(WDAC) 정책은 코드 무결성 요구 사항을 시행하고 서명되지 않은 DLL 및 실행 파일의 로딩을 비활성화합니다.
메모리 보호
방어의 중요한 부분인 메모리 보호 메커니즘입니다. 데이터 실행 방지(DEP)는 데이터 페이지에서의 코드 실행을 차단하는 반면, 주소 공간 배치 무작위화(ASLR)는 특정 메모리를 표적으로 삼는 것을 어렵게 만듭니다.
중간 수준의 보호 프로세스 완화 기술로는 간접 호출 대상 검사를 수행하는 제어 흐름 보호(CFG)와 멤버 서명 수준에 따라 기존 프로세스 열기 기능을 제한하는 보호 프로세스 라이트(PPL)가 있습니다.
애플리케이션 강화
애플리케이션 강화의 경우에도 보안 팀은 안전한 코딩 관행과 컴파일러 옵션을 준수해야 합니다. 개발자는 /DYNAMICBASE 및 /NXCOMPAT와 같은 보안 기능을 구성하고, 예외 처리를 구현하며, 애플리케이션 디버깅 프로세스 내에서 메모리 작업을 검증해야 합니다.
결론
프로세스 주입은 악성 코드를 다른 실행 중인 프로세스와 함께 메모리 공간에 주입합니다. 공격자는 대상 프로세스가 임의의 코드를 실행하도록 강요하고, 자신의 코드를 주소 공간에 직접 기록합니다. 이 기술이 위험한 이유는 기존 위협 탐지 기법을 회피할 수 있기 때문입니다. 이를 탐지하려면 고급 보안 솔루션과 예방 전략을 활용해야 합니다.
여기에는 메모리 보호, 행동 제어, 접근 제어 등이 포함됩니다. 프로세스 주입 기법의 작동 원리를 이해하면 조직은 시스템을 적절히 강화하고 보안 통제를 보다 효과적으로 배포할 수 있습니다.
프로세스 주입 FAQ
프로세스 주입은 공격자가 코드를 복사하여 프로세스 메모리 내에서 실행하는 공격 방식입니다. 이를 통해 악의적인 행위자는 대상 프로세스 내에서 자체 코드를 실행할 수 있게 되어 보안 조치를 회피할 수 있습니다.
프로세스 주입은 주로 활동을 숨기고 지속성을 확보하며, 더 높은 권한으로 코드를 실행하기 위해 사용되는 기법입니다. Windows DLL이 정상적인 프로세스를 통해 다른 프로세스에 주입되면, 실행된 코드는 대상 프로세스와 동일한 신뢰 수준으로 작업을 수행하고 동일한 접근 권한을 가지게 되어 보안 도구가 악성 행위를 탐지하기가 더 어려워집니다.
프로세스 주입 탐지는 메모리, API 및 프로세스 동작 모니터링이 필요합니다. 정적 프로그램 분석기는 비정상적인 메모리 할당, 스레드 생성, 비정상적인 프로세스 조작 API 시퀀스 등의 패턴을 찾아 이러한 주입 시도를 표시합니다.
프로세스 주입은 주로 악성코드에 의해 사용되지만, 디버깅, 악성코드 분석, 모니터링 기술, 애플리케이션 기능 확장 등 일부 시나리오에서는 합법적으로 사용될 수 있습니다.
APT(고급 지속 위협) 스타일 캠페인에서 프로세스 주입은 지속성을 확보하고 탐지를 회피하는 데 핵심적인 역할을 합니다. APT 행위자들은 고급 주입 기법을 활용하여 감염된 시스템에 영구적인 접근 권한을 획득하고, 장기간 운영 중에도 절대 발견되지 않도록 보장합니다.
