KOROMOON

착한 사마리아인이 되고 싶습니다.

9/10/2020

10 가지 프로세스 인젝션 기술 - 일반적으로 유행하는 프로세스 인젝션 기법에 대한 기술적 조사


Elastic Security 사 블로그에 2017년 07월 19일에 올라온 "Ten process injection techniques: A technical survey of common and trending process injection techniques" 글을 한글 번역함.

링크 : 

https://www.elastic.co/kr/blog/ten-process-injection-techniques-technical-survey-common-and-trending-process




프로세스 인젠션은 악성코드 및 파일 없는 공격자 트레이드크래프트(Fileless Adversary Tradecraft)에서 자주 사용되는 광범위한 방어 회피 기술이며 다른 프로세스의 주소 공간 내에서 사용자 지정 코드를 실행해야 함.

프로세스 인젠션은 은폐를 개선하고 일부 기술은 지속성을 달성해야 함.

많은 프로세스 인젠션 기술이 있지만 블로그에서는 다른 프로세스를 대신하여 악성코드 코드를 실행하는 10 가지 기술을 소개함.

또한, 리버스 엔지니어링 및 악성코드 분석을 용이하게 하고 이러한 일반적인 기술에 대한 탐지 및 방어를 지원하기 위해 관련 스크린샷을 추가로 제공함.




1. CreateRemoteThread 및 LoadLibrary 를 통한 클래식 DLL 인젠션


이 기술은 다른 프로세스에 악성코드를 주입하는 데 사용되는 가장 일반적인 기술 중 하나임.

악성코드는 다른 프로세스의 가장 주소 공간에 악성 DLL 경로를 기록하고 원격 프로세스가 대상 프로세스에 원격 스레드를 생성하여 로드하도록 함.



악성코드는 먼저 주입할 프로세스(예 : svchost.exe)를 대상이 필요함.

일반적으로 CreateToolhelp32Snapshot, Process32First, Process32Next 이 3개 API를 호출하여 프로세스를 검색하여 수행함.

CreateToolhelp32Snapshot 은 지정된 프로세스 또는 모든 프로세스의 힙 또는 모듈 상태를 열거하는 데 사용되는 API 이며 스냅샷을 반환함.

Process32First 는 스냅샷의 첫 번째 프로세스에 대한 정보를 검색한 다음 Process32Next 를 루프에서 사용하여 반복함.

대상 프로세스를 찾은 후 악성코드는 OpenProcess 를 호출하여 대상 프로세스의 핸들을 얻음.


그림 1 에서 볼 수 있듯이 악성코드는 VirtualAllocEx 를 호출하여 DLL 경로를 쓸 공간을 갖음.

그런 다음에 악성코드는 WriteProcessMemory 를 호출하여 할당된 메모리에 경로를 기록함.

마지막으로 다른 프로세스에서 코드를 실행하기 위해 악성코드는 CreateRemoteThread, NtCreateThreadEx 또는 RtlCreateUserThread 와 같은 API를 호출함. 여기서 NtCreateThreadEx 또는 RtlCreateUserThread 두 가지는 본문에 기재하지 않음.


CreateRemoteThread 는 많은 보안 제품에 의해 추적되고 표시됨.

또한, 감지할 수 있는 디스크에 악성 DLL 이 필요함.

공격자가 방어를 회피하기 위해 가장 일반적으로 코드를 주입한다는 점을 고려할 때 정교한 공격자는 이 접근 방식을 사용하지 않을 것임.

아래 그림은 이 기술을 수행하는 Rebhip 악성코드를 보여줌.


< 그림 1. 일반적인 DLL 인젝션을 수행하는 Rebhip 웜 >

Sha256: 07b8f25e7b536f5b6f686c12d04edc37e11347c8acd5c53f98a174723078c365




2. PE 인젝션 (Portable Executable Injection)


악성코드는 LoadLibrary 주소를 전달하는 대신 악의적인 코드를 기존 개방형 프로세스에 복사하여 실행할 수 있음. (작은 쉘코드 통해서 하거나 CreateRemoteThread 호출하여)

LoadLibrary 기술에 비해 PE 인젠셕의 한 가지 장점은 악성코드가 디스크에 악성 DLL 을 드롭할 필요가 없다는 점임.

위 첫 번째 기술과 유사하게 악성코드는 호스트 프로세스에 메모리를 할당(예 : VirtualAllocEx)하고 "DLL 경로"를 작성하는 대신 WriteProcessMemory 를 호출하여 악의적인 코드를 작성함.

그러나 이 방법의 장애물은 복사된 이미지의 기본 주소를 변경하는 점임.

악성코드가 PE 를 다른 프로세스에 삽입하면 예측할 수 없는 새로운 기본 주소를 갖게되므로 PE 의 고정 주소를 동적으로 다시 계산해야 함.

이를 극복하기 위해 악의적인 코드를 호스트 프로세스에서 재배치 테이블 주소를 찾고 재배치 설명자(Descriptors)를 반복하여 복사된 이미지의 절대 주소를 확인해야 함.



이 기술은 파일을 디스크에 드롭하기 않기 때문에 반사 DLL 인젝션 및 메모리 모듈과 같은 다른 기술과 유사함.

그러나 반사 DLL 인젝션 및 메모리 모듈 방식은 훨씬 더 은밀함.

메모리에서 자체적으로 로드 및 실행되기 때문에 추가적인 Windows API(예 : CreateRemoteThread 또는 LoadLibrary) 에 의존하지 않음.

반사 DLL 인젠션은 윈도우 로더(Windows's loader)에 의존하는 대신 실행될 때 자체적으로 메모리에 매핑되는 DLL 을 생성하여 작동함.

메모리 모듈은 자체적으로 DLL 매핑하는 대신 인젝터(Injector) 또는 로더(Loader)가 DLL 을 메모리에 매핑하는 역할을 수행하는 것을 제외하고는 반사 DLL 인젠션과 유사함.


반사 DLL 인젠션 및 메모리 모듈 기법은 아래 링크를 참조 바람.

참고 링크 : https://www.elastic.co/kr/blog/hunting-memory


PE 인젠션을 분석할 때 CreateRemoteThread 를 호출하기 전에 루프를 보는 것이 매우 일반적임. (일반적으로 두개의 for 문이거나 중첩 for문)

이 기술은 크립터(Crypters) 사이에서 매우 인기가 있음.

그림 2 에서 샘플 단위 테스트는 이 기술을 활용하고 있음.

코드에는 WriteProcessMemory 및 CreateRemoteThread 를 호출하기 전에 볼 수 있는 재배치 테이블을 저정하기 위한 두 개의 중첩 루프가 있음.

"and 0x0fff" 명령어는 또 다른 좋은 지시자(Indicator)이며 처음 12 비트가 포함된 재배치 블록의 가상 주소로 오프셋을 가져오는 데 사용된다는 것을 보여줌.

이제 악성코드가 필요한 모든 주소를 다시 계산했으므로 시작 주소를 CreateRemoteThread 에 전달하고 실행하기만 하면 됨.


< 그림 2. CreateRemoteThread 를 호출하기 전 PE 인젠션을 위한 루프 구조의 예 >

Sha256: ce8d7590182db2e51372a4a04d6a0927a65b2640739f9ec01cfd6c143b1110da




3. Process Hollowing (일명 프로세스 교체 및 실행)


악성코드는 호스트 프로그램에 코드를 인젠션하는 대신(예 : DLL 인젠션) Process Hollowing 기법을 수행할 수 있음.

Process Hollowing 기법은 악성코드가 대상 프로세스의 메모리에서 합법적인 코드를 매핑 해제(비우기)하고 대상 프로세스(예 : svchost.exe)의 메모리 공간을 악성 실행 파일로 덮어쓸 때 발생함.



악성코드는 먼저 일시 중단 모드에서 악의적인 코드를 호스팅하는 새로운 프로세스를 생성함.

그림 3 과 같이 CreateProcess 를 호출하고 프로세스 생성 플래그를 CREATE_SUSPENDED (0x00000004) 로 설정하면 됨.

새 프로세스의 기본 스레드는 일시 중단된 상태로 만들어지며 ResumeThread 함수가 호출될 때까지 실행되지 않음.

다음으로 악의적인 코드는 합법적인 파일의 콘텐츠를 악성 페이로드로 교해야 함.

이는 ZwUnmapViewOfSection 또는 NtUnmapViewOfSection 을 호출하여 대상 프로세스의 메모리 매핑을 해제하여 수행됨.

이 2개의 API 는 기본적으로 센션이 가리키는 모든 메모리를 해제함.

이제 메모리가 매핑 해제되었으므로 로더는 VirtualAllocEx를 수행하여 악성코드에 대한 새 메모리를 할당하고 WriteProcessMemory 를 사용하여 각 악성코드 세션을 대상 프로세스 공간에 기록함.

악성코드는 SetThreadContext 를 호출하여 자신이 작성한 새 코드 섹션에 진입점을 가리킴.

마지막으로 악성코드는 ResumeThread 를 호출하여 일시 중단된 스레드를 다시 시작하여 프로세스를 일시 중단된 상태에서 해제함.


< 그림 3. Ransom.Cryak 의 수행 프로세스 비우기 >

Sha256: eae72d803bf67df22526f50fc7ab84d838efb2865c27aef1a61592b1c520d144




4. 스레드 실행 하이재킹 (일명 약자로 SIR - 일시 중지, 인젝션, 재개)


이 기술은 Process Hollowing 기법과 몇 가지 유사점을 가지고 있음.

스레드 실행 하이재킹에서 악성코드는 프로세스의 기존 스레드를 대상으로 하고 시끄러운(noisy) 프로세스 및 스레드 생성 작업을 방지함.

따라서, 분석 중에 OpenThread 로부터 CreateToolhelp32Snapshot 및 Thread32First 에 대한 호출과 OpenThread 가 이어질 것임.



대상 스레드에 대한 핸들을 얻은 후 악성코드는 SuspendThread 를 호출하여 스레드를 일시 중단 모드로 전환하여 인젝션을 수행함.

악성코드는 VirtualAllocEx 및 WriteProcessMemory 를 호출하여 메모리를 할당하고 코드 삽일을 수행함.

코드에는 쉘코드, 악성 DLL 경로 및 LoadLibrary 주소가 포함될 수 있음.


그림 4 는 이 기술을 사용하는 일반적인 트로이 목마를 보여줌.

스레드의 실행을 가로채기 위해 악성코드는 SetThreadContext 를 호출하여 대상 스레드의 EIP 레지스터(다음 명령어 주소가 포함된 레지스터)를 수정함.

그 후 악성코드는 스레드를 재개하여 호스트 프로세스에 작성한 쉘코드를 실행함.

공격자 관점에서 SIR 기법의 접근 방식은 시스템 호출 중에 스레드를 일시 중단하고 다시 시작하면 시스템이 중단될 수 있으므로 문제가 될 수 있음.

이를 방지하기 위해 EIP 레지스터가 NTDLL.dll 범위 내에 있으면 보다 정교한 악성코드가 재개되고 나중에 다시 시도함.


< 그림 4. 스레드 실행 하이재킹을 수행하는 일반 트로이 목마 >

Sha256: 787cbc8a6d1bc58ea169e51e1ad029a637f22560660cc129ab8a099a745bd50e




5. SetWindowsHookEx 를 통한 후크 인젝션(Hook Injection)


후킹은 함수 호출을 가로채는 데 사용되는 기술임.

악성코드는 후킹 기능을 활용하여 특정 스레드에서 이벤트가 트리거 될 때 악성 DLL을 로드할 수 있음.

일반적으로 SetWindowsHookEx 를 호출하여 후크 루틴을 후크 체인에 설치하면 됨.

SetWindowsHookEx 함수는 4개의 인수를 사용함.

첫 번째 인수는 이벤트 유형임.

이벤트는 후크 유형의 범위를 반영하며 키보드 키(WH_KEYBOARD)를 누르는 것부터 마우스 입력(WH_MOUSE), CBT 등에 이르기까지 다양함.

두 번째 인수는 악성코드가 이벤트 실행 시 호출하려는 함수에 대한 포인터이고 세 번째 인수는 함수를 포함하는 모듈임.

따라서 SetWindowsHookEx 를 호출하기 전에 LoadLibrary 및 GetProcAddress 에 대한 호출을 보는 것은 매우 일반적임.

이 함수에 대한 마지막 인수는 후크 프로시저가 연관되는 스레드임.

이 값을 0으로 설정하면 이벤트가 트리거될 때 모든 스레그가 작업을 수행함.

그러나 악성코드는 일반적으로 소음(noise)을 줄이기 위해 하나의 스레드를 대상으로 함.

따라서 단일 스레드를 찾고 대상으로 지정하기 위해 SetWindowsHookEx 전에 CreateToolhelp32Snapshot 및 Thread32Next 호출을 볼 수도 있음.

DLL 이 인젝션되면 악성코드는 스레드 ID 가 SetWindowsHookEx 함수에 전달된 프로세스를 대신하여 악의적인 코드를 실행함.

그림 5 에서 Locky Ransomware 는 이 기술을 구현함.


< 그림 5. 후크 인젠션을 사용한 Locky Ransomware >

Sha256: 5d6ddb8458ee5ab99f3e7d9a21490ff4e5bc9808e18b9e20b6dc2c5b27927ba1




6. 레지스트리 수정을 통한 인젝션 및 지속성 (예 : Appinit_Dlls, AppCertDlls, IFEO)


Appinit_Dlls, AppCertDlls, IFEO (Image File Execution Options) 는 악성코드가 인젝션 및 지속성을 위해 사용하는 모든 레지스트리 키임.

항목은 아래와 같음.


HKLM\Software\Microsoft\Windows

NT\CurrentVersion\Windows\Appinit_Dlls

HKLM\Software\Wow6432Node\Microsoft\Windows

NT\CurrentVersion\Windows\Appinit_Dlls

HKLM\System\CurrentControlSet\Control\Session\Manager\AppCertDlls

HKLM\Software\Microsoft\Windows NT\currentversion\image file execution options


AppInit_Dlls


악성코드는 AppInit_Dlls 레지스트리 키 아래에 악성 라이브러리의 위치를 삽입하여 다른 프로세스가 라이브러리를 로드하도록 할 수 있음.

이 레지스트리 키 아래의 모든 라이브러리는 User32.dll 을 로드하는 모든 프로세스에 로드됨.

User32.dll 은 대화 상자와 같은 그래픽 요소를 저장하는 데 사용되는 매우 일반적인 라이브러리임.

따라서, 악성코드가 이 하위 키를 수정할 때 대부분의 프로세스가 악성 라이브러리를 로드함.

그림 6 은 인젝션 및 지속성을 위해 접근 방식에 의존하는 트로이 목마 Ginwui 를 보여줌.

RegCreateKeyEx 를 호출하여 Appinit_Dlls 레지스트리 키를 열고 RegSetValueEx 를 호출하여 값을 수정함.


< 그림 6. AppInit_Dlls 레지스트리 키를 수정하는 Ginwui >

Sha256: 9f10ec2786a10971eddc919a5e87a927c652e1655ddbbae72d376856d30fa27c


AppCertDlls


이 접근 방식은이 레지스트리 키 아래의 DLL 이 Win32 API 함수 CreateProcess, CreateProcessAsUser, CreateProcessWithLogonW, CreateProcessWithTokenW 및 WinExec 를 호출하는 모든 프로세스에 로드된다는 점을 제외하면 AppInit_Dlls 접근 방식과 매우 유사함.


IFEO (Image File Execution Options)


IFEO 는 일반적으로 디버깅 목적으로 사용됨.

개발자는 이 레지스트리 키에서 "디버거 값" 을 설정하여 디버깅을 위해 다른 실행 파일에 프로그램을 연결할 수 있음.

따라서 실행 파일이 시작될 때마다 첨부된 프로그램이 시작됨.

이 기능을 사용하려면 디버거에 대한 경로를 제공하고 분석하려는 실행 파일에 연결하면 됨.

악성코드는 이 레지스트리 키를 수정하여 대상 실행 파일에 연결하면 됨.

악성코드는 이 레지스트리 키를 수정하여 대상 실행 파일에 자신을 삽입할 수 있음.

그림 7 에서 Diztakun 트로이 목마는 작업 관리자의 디버거 값을 수정하여 이 기술을 구현함.


< 그림 7. IFEO 레지스트리 키를 수정하는 Diztakun 트로이 목마 >

Sha256: f0089056fc6a314713077273c5910f878813fa750f801dfca4ae7e9d7578a148




7. APC 인젠션 및 원자폭탄(AtomBombing)


악성코드는 APC(비동기 프로시저 호출)를 활용하여 다른 스레드가 대상 스레드인 APC 대기열에 연결하여 사용자 지정 코드를 실행하도록 할 수 있음.

각 스레드에는 대상 스레드가 변경 가능한 상태가 될 때 실행을 기다리는 APC 대기열이 있음.

스레드는 SleepEx, SignalObjectAndWait, MsgWaitForMultipleObjectsEx, WaitForMultipleObjectsEx 또는 WaitForSingleObjectEx 함수를 호출하는 경우 경고 가능한 상태가 됨.

악성코드는 일반적으로 변경 가능한 상태에 있는 스레드를 찾은 다음 OpenThread 및 QueueUserAPC 를 호출하여 APC 를 스레드에 대기시킴.

QueueUserAPC 는 세 가지 인수를 취함 : 

1) 대상 스레드에 대한 핸들

2) 악성코드가 실행하려는 기능에 대한 포인터

3) 함수 포인터에 전달되는 매개 변수

그림 8 에는 Amanahe 악성코드는 먼저 OpenThread 를 호출하여 다른 스레드의 핸들을 얻은 다음 LoadLibraryA를 함수 포인터로 사용과 함께 QueueUserAPC 를 호출하여 악성 DLL 을 다른 스레드에 삽입함.


AtomBombing 은 enSilo 연구소에서 처음 도입 된 후 Dridex V4 에서 사용 된 기술임.

이전 게시물에서 자세히 논의했듯이 이 기술은 APC 주입에도 의존함.

그러나 다른 프로세스의 메모리에 쓰기 위해 원자 테이블을 사용함.


< 그림 8. APC 인젠션을 수행하는 Almanahe >

Sha256: f74399cc0be275376dad23151e3d0c2e2a1c966e6db6a695a05ec1a30551c0ad




8. SetWindowLong 을 통한 EWMI (Extra Window Memory Injection)


EWMI 는 Explorer 트레이 창의 추가 창 메모리에 인젝션하는 데 의존하며 Gapz 나 PowerLoader 와 같은 악성코드 군에서 몇 차례 사용됨.

윈도우 클래스를 등록할 때 어플리케이션은 추가 윈도우 메모리(EWM)라고 하는 추가 메모리 바이트 수를 지정할 수 있음.

그러나 EWM 에는 공간이 많지 않음.

이 제한을 우회하기 위해 악성코드는 explorer.exe 의 공유 섹션에 코드를 작성하고 SetWindowLong 및 SendNotifyMessage 를 사용하여 쉘코드를 가리키는 함수 포인터를 만든 다음 실행함.


악성코드는 공유 섹션에 쓸 때 두 가지 옵션이 있음.

공유 섹션을 생성하여 자신과 다른 프로세스(예 : explorer.exe)에 모두 매핑하거나 이미 존재하는 공유 섹션을 열 수 있음.

전자는 몇 가지 다른 API 호출 외에 힙 공간을 할당하고 NTMapViewOfSection 을 호출하는 오버헤드가 있으므로 후자의 접근 방식이 더 자주 사용됨.

악성코드가 공유 섹션에 쉘코드를 작성한 후 GetWindowLong 및 SetWindowLong 을 사용하여 "Shell_TrayWnd" 의 추가 윈도우 메모리에 액세스하고 수정함.

GetWindowLong 은 지정된 오프셋에서 32 비트값을 윈도우 클래스 개체의 추가 윈도우 메모리로 검색하는 데 사용되는 API 이며 SetWindowLong 은 지정된 오프셋에서 값을 변경하는 데 사용됨.

이렇게 함으로써 악성코드는 단순히 윈도우 클래스에서 함수 포인터의 오프셋을 변경하고 공유 섹션에 기록된 쉘코드를 가리킬 수 있음.


위에서 언급한 대부분의 다른 기술과 마찬가지로 악성코드는 작성한 코드를 트리거해야 함.

이전에 논의된 기술에서 악성코드는 CreateRemoteThread, QueueUserAPC 또는 SetThreadContext 와 같은 API 를 호출하여 이를 달성했음.

이 접근 방식을 사용하면 악성코드가 대신 SendNotifyMessage 를 호출하여 삽입된 코드를 트리거함.

SendNotifyMessage 를 실행하면 Shell_TrayWnd 는 SetWindowLong 에서 이전에 설정한 값이 가리키는 주소로 제어를 수신하고 전송함.

그림 9 에서 PowerLoader 악성코드는 이 기술을 사용함.


< 그림 9. 쉘 트로이 창의 추가 윈도우 메모리에 삽입하는 PowerLoader >

Sha256: 5e56a3c4d4c304ee6278df0b32afb62bd0dd01e2a9894ad007f4cc5f873ab5cf




9. Shims 을 이용한 인젠션


Microsoft 사는 주로 이전 버전과의 호환성을 위해 개발자에게 Shims 을 제공함.

Shims 을 사용하면 개발자가 코드를 다시 작성하지 않고도 프로그램에 수정 사항을 적용할 수 있음.

Shims 을 활용하여 개발자는 운영 체제에 어플리케이션 처리 방법을 알릴 수 있음.

Shims 는 기본적으로 API 에 연결하고 특정 실행 파일을 대상으로 하는 방법임.

악성코드는 Shims 을 활용하여 지속성과 인젠션 모두에 대해 실행 파일을 대상으로 지정할 수 있음.

Windows 는 적절한 수정 사항을 적용하기 위해 Shimming 데이터베이스를 확인하기 위해 바이너리를 로드할 때 Shim 엔진을 실행함.


적용할 수 있는 수정 사항이 많이 있지만 악성코드의 즐겨 찾기는 다소 보안과 관련된 수정 사항임. (예 : DisableNX, DisableSEH, InjectDLL 등)

Shimming 데이터베이스를 설치하기 위해 악성코드는 다양한 접근 방식을 배포할 수 있음.

예를 들어, 일반적인 접근 방식 중 하나는 단순히 sdbinst.exe 를 실행하고 악의적인 sdb 파일을 가리키도록 하는 것임.

그림 10 에서 "Search Protect by Conduit" 애드웨어는 지속성과 인젠션을 위해 Shim 을 사용함.

vc32loader.dll 을 로드하기 위해 Chrome 의 "InjectDLL" Shim 을 수행함.

sdb 파일을 분석하기 위해 몇 가지 기존 도구가 있지만 아래 나열된 sdb 분석을 위해 python-sdb 를 사용했음.


< 그림 10. 인젠션 목적으로 Search Protect 에서 사용하는 SDB >

Sha256 : 6d5048baf2c3bba85adc9ac5ffd96b21c9a27d76003c4aa657157978d7437a20




10. IAT Hooking 및 Inline Hooking (일명 Userland Rootkits)


IAT 후킹과 인라인 후킹은 일반적으로 사용자 영역 루트킷으로 알려져 있음.

IAT 후킹은 악성코드가 가져오기 주소 테이블(IAT - Imort Address Table)을 변경하는 데 사용하는 기술임.

합법적인 응용 프로그램이 DLL 에 있는 API 를 호출하면 원래 함수 대신 대체된 함수가 실행됨.

반대로 인라인 후킹을 사용하면 악성코드가 API 기능 자체를 수정함.

그림 11 에서 FinFisher 악성코드는 CreateWindowEx 가 가리키는 위치를 수정하여 IAT 후킹을 수행함.


< 그림 11. CreateWindowEx 가 가리키는 위치를 변경하여 IAT 후킹을 수행하는 FinFisher >

Sha256: f827c92fbe832db3f09f47fe0dcaafd89b40c7064ab90833a1f418f2d1e75e8e




결론


이 게시물에서는 악성코드가 다른 프로세스에서 활동을 숨기는 데 사용하는 10가지 기술을 다루었음.

일반적으로 악성코드는 쉘코드를 다른 프로세스에 직접 인젠션하거나 다른 프로세스가 악성 라이브러리를 로드하도록 함.

표 1 에서는 다양한 기법을 분류하고 이 게시물에서 다루는 각 주입 기법을 관찰하기 위한 참고 자료로 사용된 샘플을 제공함.

게시물 전체에 포함된 수치는 분석가가 악성코드를 리버싱할 때 다양한 기술을 인식하는 데 도움이 됨.


< 표 1. 프로세스 인젠션은 코드를 다른 프로세스에 직접 주입하거나 DLL 을 강제로 다른 프로세스에 로드하여 수행 할 수 있음 >


댓글 없음:

댓글 쓰기