Launchers


실행기(Loader라고도 알려짐)는 현재의 실행이나 추후의 은밀한 실행을 위해 자신이나 다른 악성코드를 설정하는 악성코드의 유형을 말한다. 실행기의 목적은 악의적인 행위를 사용자에게 들키지 않게 설정하는 것이다. 실행기는 종종 로딩할 악성코드를 포함하며 일반적인 예가 Resource Section에 EXE나 DLL을 포함하는 경우가 있다.

위의 그림에서 보는 것과 같이 실행 파일의 부분에 MZ로 시작하는 DOS Header를 확인할 수가 있다. 프로그램은 이와 같이 리소스 섹션에 악성코드를 자주 저장하며, 실행될 때 리소스 섹션에서 내장된 실행파일이나 DLL을 추출해 실행한다.

리소스 처리 API로는 FindResource, LoadReasource, SizeofResource 가 존재한다. 이러한 실행기(launcher)는 관리자 권한으로 실행되거나 관리자 권한을 획득하기 위하여 권한 상승을 해야 한다.



Process Injection


가장 대중적인 위장 실행 기법은 프로세스 인젝션으로 이름과 같이 코드를 실행중인 프로세스에 인젝션하고, 그 프로세스가 자동으로 악의적인 코드를 실행하는 것이다. 멀웨어 코더들은 코드의 악의적인 행위를 숨기기 위해 프로세스 인젝션을 사용하며, 가끔은 호스트 기반 방화벽과 프로세스에 특화딘 보안 메커니즘을 우회하고자 할 때 사용한다.

특정 Windows API 호출들이 프로세스 인젝션에 일반적으로 사용되며 그 예로 VirtualAllocEX는 원격 프로세스의 메모리에 공간을 할당하기 위하여 사용되며, WriteProcessMemory는 할당된 공간에 데이터를 쓸 때 사용된다.


DLL Injection

DLL 인젝션은 원격의 프로세스가 악의적인 DLL을 로딩하게 하는 프로세스 인젝션의 한 형태이다. LoadLibrary를 호출하는 원격 프로세스에 코드를 삽입해 해당 프로세스의 컨텍스트에 DLL을 강제적으로 로드하게 한다. 감염된 프로세스가 악의적인 DLL을 로드하면 운영체제는 자동으로 그 DLL의 DllMain() 함수를 호출하게 된다. 주로 악의적인 DLL은 DllMain() 외에 다른 내용은 없는 경우가 많으며 이렇게 인젝션된 코드들은 실행한 프로세스가 소유한 시스템의 권한과 동일한 권한을 가진다.

아래에서 보는 것과 같이 오른쪽에는 원래의 프로세스를 보여준다. 하지만 myhack.dll을 Injection을 통하여 프로세스 내부에 넣을 수가 있다. 이렇게 로드된 myhack.dll의 DllMain() 함수는 실행이 될 것이며 권한 또한 기존의 프로세스와 같은 권한을 갖는다. 

호스트 프로그램 내부에 악의적인 DLL을 인젝션하기 위해 실행기 악성코드는 목표 프로세스의 핸들을 우선 확복해야 한다. 이 방법으로는 윈도우 API 호출인 CreateToolhelp32Snapshot, Process32First, Process32Next를 인젝션 목표에 대한 프로세스 목록을 찾기 위해 사용한다. 목표를 발견하면 실행기는 PID를 확보한 후 OpenProcess() 호출을 통해 핸들을 획득한다. DLL 인젝션의 순서는 다음과 같다.

1. 대상 프로세스 핸들 구하기

OpenProcess() API를 이용해서 대상 프로세스의 핸들을 구하는데 이 때 주로 PID를 이용한다. 



2. 대상 프로세스 메모리에 인젝션 시킬 DLL 경로 써주기

대상 프로세스에게 로딩할 DLL 파일의 경로를 알려줘야 한다. 아무 메모리 공간에 쓸 수 없으므로 VirtualAllocEx() API를 이용하여 대상 프로세스 메모리 공간에 버퍼를 할당한다. 그리고 WriteProcessMemory()를 통하여 할당된 버퍼 주소에 dll 경로 문자열을 써준다.




3. LoadLibraryA() API 주소 구하기

LoadLibrary()를 통하여 우리는 새로운 DLL을 프로세스에 로딩시킬수가 있다. 그러기위해서는 LoadLibrary() API의 주소가 필요하다. 여기서 우리는 인젝션 시킬 프로세스의 함수 주소를 구하는 것이 아니라 인젝터의 LoadLibrary()의 주소를 구할 것이다. 실제 windows 운영체제에서 kernel32.dll은 프로세스마다 같은 주소에 로딩되기에 이를 이용한 것이다.

* Microsoft 에서는 OS 핵심 DLL 파일들의 ImageBase를 정리해 놓았는데 이는 절대 겹치지 않도록하므로 DLL Relocation이 발생하지 않는다. 이러한 특성을 이용한 것이라 할 수 있다.


4. 대상 프로세스에 스레드를 실행시킴

이제 LoadLibrary()의 주소도 알았으므로 우리는 이를 호출하면 된다. 호출하는 방법으로는 CreateRemoteThread()를 사용하는데 이는 다른 프로세스에게 스레드를 실행시켜주는 함수이다. 

멀웨어를 분석함에 있어서 이러한 징후를 발견한다면 악의적인 DLL과 대상프로세스의 이름을 포함한 문자열을 찾아야 한다. 이 문자열들은 바로 볼 수가 없기에 실행하다보면 대상 프로세스의 이름은 대상 프로세스의 PID를 판별할 때 strcmp 함수와 같은 함수에서 발견할 수가 있다. 또한 인젝션 되는 악의적인 DLL의 이름을 알아내기 위해서는 WriteProcessMemory에 전달되는 Buffer의 값을 보면 된다.


아래는 실제로 직접 해본 것으로 악의적인 dll이 아니라 메세지 박스를 출력하는 dll이다. 이를 인젝션하면 아래와 같이 카카오톡의 창에 메세지박스가 같이 존재하는 것을 확인할 수가 있다. 이는 카카오톡이라는 프로세스와 동일한 위치에 있다는 것을 알 수가 있다.


Code Injection

DLL 인젝션과 동일하게 원격 프로세스의 메모리에 공간을 할당하여 삽입을 한다. 하지만 여기선 원격 프로세스가 개별 DLL을 로드하게 하는 대신에 악의적인 코드를 직접적으로 원격 프로세스에 인젝션 한다는 점이다. 이는 DLL 인젝션보다 유연하지만 호스트 프로세스에 부정적인 영향을 주지 않고 성공적으로 실행되게 하기 위해서는 많은 최적화 코드가 필요하다.

여기선 DLL을 로딩시킬 필요가 없으므로 GetProcAddress()가 사용되지 않으며 이외의 사용 API들은 유사하다. 



Process replacement


호스트 프로그램에 코드를 인젝션하지 않고, 일부 악성코드는 실행 중인 프로세스의 메모리 공간을 악의적인 실행 파일로 쓰기 위해 프로세스 교체라고 알려진 방법을 사용한다. 프로세스 교체는 악성코드 제작자가 프로세스 인젝션 중 발생할 수 있는 프로세스 비정상 종료의 위험 부담 없이 악성코드를 정상적인 프로세스로 위장하고자 할 때 사용한다.

이 기법은 교체되는 프로세스와 동일한 권한을 악성코드에 부여한다. 예를 들어 악성코드가 svchost,exe에 대해 프로세스 교체 공격을 수행했다면 사용자는 C:\Windows\System32 에서 실행 중인 svchost.exe를 본 후 악성코드가 아니라고 생각하게 된다.

프로세스 교체의 핵심은 대기 상태(Suspended State)의 프로세스를 생성하는 것이다. 다시 말해 프로세스를 메모리에 로드했지만, 프로세스의 메인 스레디는 대기함을 의미한다. 해당 프로그램은 외부프로그램이 메인 스레드를 재개하기 전까지는 아무것도 하지 않는다.

CreateProcess()를 통하여 프로세스가 생성되면 다음 단계로 대상 프로세스의 메모리를 악의적인 실행 파일로 교체한다. 일반적으로 파라미터로 전다로딘 섹션에서 지정하고 있는 모든 메로리를 해제하기 위해 ZwUnmapViewOfSection()을 사용한다. 메모리를 언매핑한 후 로더는 VirutalAllocEx()를 실행하여 악성코드를 위한 새로운 메모리를 할당하고 WriteProcessMemory()를 사용해 악성코드의 각 섹션을 대상 프로세스의 공간에 작성한다. 마지막 단계로 진입점이 악의적인 코드를 가리키게 SetThreadContext를 호출해 악의적인 코드가 실행되게 대상 프로세스의 환경을 복원한다. 최종적으로 악성코드가 실행되게 ResumeThread를 호출해 대상 프로세스를 교체한다.

프로세스 교체는 악성코드의 은닉에 효과적인 방법이다. 대상 프로세스로 가장함으로써 악성코드는 방화벽이나 침입 방지 시스템(IPS)를 우회하고 일반 윈도우 프로세스로 보이게 함으로써 탐지를 피할 수 있다. 

여기서 우리는 ProcessExplorer의 String탭을 통하여 이를 탐지하는데 도움이 될 것이다.




Hook Injection


후크 인젝션은 윈도우 후크의 이점을 이용해 악성코드를 로딩하는 방법이다. 윈도우 후크는 애플리케이션으로 전달되는 메세지를 가로 챌 때 사용하는데 악성코드 제작자는 다음 2가지를 이루기 위해 후크 인젝션을 사용한다.

1. 특정 메세지가 인터셉터될 때마다 악의적인 코드가 실행되는 것을 보장하기 위해서

2. 대상 프로세스의 메모리 공간에 특정 DLL 로드를 보장하기 위해서


아래 글미과 같이 사용자는 운영체제로 전달되는 이벤트를 생성한다. 그 후에 이벤트에서 생성한 메세지를 등록된 스레드로 전달한다. 오른쪽 그림은 공격자가 메세지를 가로채는 악의적인 DLL을 삽입하는 한 가지 방법을 보여준다.


로컬과 원격 후크

윈도우 후크에는 다음과 같은 두가지 유형이 있다.

- 로컬 후크는 내부 프로세스로 전달되는 메세지를 관찰하거나 조작하기 위해 사용된다.

- 원격 후크는 원격 프로세스에 전달되는 메세지를 관찰하거나 조작하기 위해 사용된다.

원격 후크는 두 가지 형태가 있다. 상위 레벨 원격 후크는 후크 프로시저가 DLL에 포함돼 있는 익스포트 함수로 존재해야한다. 익스포트 함수는 운영체제에서 후킹된 스레드나 전체 스레드의 프로세스 스페이스로 매핑하낟. 하위 레벨 원격 후크는 후크가 설치된 프로세스의 후크 프로시저를 필요로 한다. 이 프로시저는 운영체제가 프로세스 이벤트를 받기 전에 통보된다.


Keyloggers Using Hooks

후크 인젝션은 키 스트로크를 기록하는 키로거로 알려진 악의적인 애플리케이션에서 자주 사용한다. 키 스트로크는 WH_KEYBOARD나 WH_KEYBOARD_LL 후크 프로시저 유형을 각각 사용해 상위 레벨이나 하위 레벨 후크를 등록해 캡처할 수 있다.


SetWindowsHookEx 사용

원격 윈도우 후킹에 사용하는 주요 함수 호출은 SetWindowsHookEx이며, 다음과 같은 파라미터를 가진다.

- idHook : 설치할 후크 프로시저의 유형을 정의

- lpfn : 후크 프로시저에 대한 포인터

- hMod : 상위 레벨의 경우 lpfn에 정의된 후크 프로시저를 포함하는 DLL에 대한 핸들을 식별, 하위 레벨의 경우 lpfn 프로시저에 정의된 로컬 모듈을 식별

- dwThreadId : 후크 프로시저와 연관된 스레드의 식별자를 저으이. 파라미터가 0이라면 후크 프로시저는 호출한 스레드와 동일한 데스크톱에 실행 중인 모든 스레드로 정의 된다. 하위 레벨 후크에 대해서는 0으로 설정 돼야 한다.


스레드 지정

악성코드는 키로거나 동급의 목적을 가진 경우에만 모든 스레드에 로딩 된다. 모든 스레드에 로드하는 것은 실행 시스템의 성능을 저하시키고 IPS에 탐지될 수 있다. 그러므로 목적이 단순히 원격 프로세스에 DLL을 로딩하는 것이라면 탐지 되지 않게 하기 위해 싱글 스레드에만 인젝션해야한다.

싱글 스레드 지정을 위해서는 대상 프로세스를 찾기 위해 프로세스 목록을 검색해야하며, 대상 프로세스가 실행돼 있지 않다면 악성코드가 프로그램을 실행해야 한다. 악의적인 애플리케이션이 자주 사용되는 윈도우 메세지를 후킹한다면 IPS에 탐지될 확률이 높아진다. 아래의 그림은 다른 프로세스의 메모리 공간에 DLL을 로딩하기 위해 후크인젝션 하는 어셈코드다.


Detours

기존 운영체제와 애플리케이션을 쉽게 장착하고 확장할 수 있는 방법으로 제시된 라이브러리이다. 이를 통하여 IAT를 수정하거나 기존 프로그램 파일에 DLL을 덧붙이거나 실행 중인 프로세스에 함수 후킹을 한다. 멀웨어 코더는 일반적으로 Detours를 이용해 가장 일반적으로 디스크에 존재하는 바이너리에 새로운 DLL을 추가한다. 


APC 인젝션

CreateRemoteThread를 이용해 스레드를 생성한 후 원격 프로세스에서 함수를 실행하는 것을 위에서 보았다. 하지만 스레드 생성은 쉽지 않으므로 기존 스레드에 함수를 실행하는 것이 더 효과 적이다. 이런 기능이 윈도우 비동기 프로시저 호출로 존재한다.

APC는 APC의 정규 실행 경로를 실행하기 전에 스레드가 다른 코드를 실행하게 지시할 수 있다. 모든 스레드는 스레드에 첨부된 APC 큐를 갖고 있으며 WaitForSingleObjectEx, WaitForMultipleObjectEx, SleepEx 같은 함수를 호출했을 때와 같이 스레드가 대체 가능한 상태에 있을 때 처리된다. APC 는 다음과 같은 두 가지 형태가 있다.

- 시스템이나 드라이버를 위해 생성된 APC는 커널 모드 APC라고 한다.

- 애플리케이션을 위해 생성된 APC는 사용자 모드 APC 라고한다.

사용자 공간에서는 QueueUserAPC를 사용해 사용자 공간에서 다른 스레드가 원격 스레드에서 실행될 함수를 큐에 넣을 수가 있으며 커널 공간에서는 MeI itializeApc와 KeInsertQueueApc와 같은 두 개의 주요 함수를 사용한다.





참고

http://www.reversecore.com/38    ; Dll 인젝션

https://www.trustwave.com/Resources/SpiderLabs-Blog/Analyzing-Malware-Hollow-Processes/   ; 프로세스 교체



문제 풀이


Lab12-01

파일 Lab12-01.exe와 Lab12-01dll 에서 발견되는 악성코드를 분석하자. 분석을 할 때 이 파일들은 동일한 디렉터리에 존재해야함을 주의하자

1. 악성코드가 실행 됐을 때 어떤 일이 일어나는가?

어떠한 프로세스에 12-01.dll을 인젝션 시킨다.


2. 어떤 프로세스가 인젝션 됐는가?

explorer.exe에 12-01.dll 인젝션 시키는것


3. 악성코드의 팝업을 어떻게 멈출 수 있는가?

explorer.exe를 강제로 종료시킨뒤 task 매니저에서 다시 explorer를 실행하면 더 이상 작동하지않는다. 또는 재부팅을 하여도 인젝션이 해제가 되어있을 것이다.


4. 이 악성코드는 어떻게 작동하는가?

dll injection을 진행한 뒤 그 dll에는 메세지박스를 60초마다 출력하도록 한다.


EXE

000000006030   000000406030      0   explorer.exe

000000006040   000000406040      0   <unknown>

00000000604C   00000040604C      0   LoadLibraryA

00000000605C   00000040605C      0   kernel32.dll

00000000606C   00000040606C      0   Lab12-01.dll

000000006080   000000406080      0   EnumProcesses

000000006090   000000406090      0   GetModuleBaseNameA

0000000060A4   0000004060A4      0   psapi.dll

0000000060B0   0000004060B0      0   EnumProcessModules

00000000554A   00000040554A      0   CreateRemoteThread

DLL

export가 존재하지 않으므로 DllMaiin()을 통한 악의적 행위, DLL 인젝션의 확률이 높음


Lab12-02

1. 이 프로그램의 목적은 무엇인가?

svchost.exe에 프로세스 교체 기법을 사용하여 리소스 섹션에 있는 내용을 실행하도록 한다. 실행되면 해당 dll이 가진 명령어들을 수행하는데 서비스에 등록을 하며 RPC 서버와의 어떤 작업도 진행한다. 키로깅


2. 실헹기 프로그램은 어떻게 실행을 숨기는가?

리소스 섹션에 숨겼으며 XOR 41을 하므로 알아차리기가 어렵다.


3. 악의적인 페이로드는 어디에 조정돼 있는가?

리소스 섹션

4. 악의적인 페이로드는 어떻게 보호되는가?

XOR 41


리소스섹션에 파일이 있는데 XOR 41로 숨겨져있다. 000000005030   000000405030      0   \svchost.exe

000000005058   000000405058      0   ntdll.dll
000000005040   000000405040      0   NtUnmapViewOfSection   >> 프로세스 교체긱법?
000000004842   000000404842      0   WriteFile
00000000464A   00000040464A      0   FreeResource
00000000465A   00000040465A      0   SizeofResource
00000000466C   00000040466C      0   LockResource
00000000467C   00000040467C      0   LoadResource
00000000468C   00000040468C      0   FindResourceA
0000000045D8   0000004045D8      0   VirtualAllocEx


Create_Suspend
ResumeThread 등등 프로세스 교체 기법을 사용 svchost.exe를


Lab12-03

1. 이 악의적인 페이로드의 목적은 무엇인가?

SetWindowsHookExA

키로킹


2. 악의적인 페이로드는 어떻게 자신을 인젝션하는가?

후킹 인젝션


3. 이 프로그램은 어떤 파일 시스템 잔여물을 만드는가?

practicalmalwareanalysis.log


Lab12-04

1. 0x401000에서 악성코드는 무엇을 하는가?

해당 프로세스가 오픈되어 있는지를 확한다.


2. 악성코드는 어떤 프로세스에 인젝션되는가?



3. LoadLibrary를 이용해 로드하는 DLL은 무엇인가?

sfc_os.dll

4. CreateRemoteThread 호출에 전달되는 네번쨰 인자는 무엇인가?

sfc_os.dll 의 스타트 어드레스


5. 메인 실행 파일에서 어떤 악성코드를 드롭했는가?

URL 로부터 파일을 다운로드


6. 이 파일과 드롭된 악성코드의 목적은 무엇인가?

psapi.dll이 나옴


리소스 섹션에 EXE가 포함됨, SeDebugPrivilege가 사용되므로 권한 상승이 이루어짐

movfile \Temp\winup.exe >>> C:\Windows\System32\wupmdmgr.exe


000000007070   000000407070      0   \winup.exe

000000007084   000000407084      0   \system32\wupdmgrd.exe

0000000070A4   0000004070A4      0   http://www.practicalmalwareanalysis.com/updater.exe

0000000061AA   0000004061AA      0   URLDownloadToFileA
0000000061BE   0000004061BE      0   urlmon.dll
000000006182   000000406182      0   WinExec
000000003010   000000403010      0   winlogon.exe
0000000022B6   0000004022B6      0   LookupPrivilegeValueA
00000000229E   00000040229E      0   AdjustTokenPrivileges
000000002216   000000402216      0   SizeofResource
000000002228   000000402228      0   LoadResource
000000002238   000000402238      0   FindResourceA
0000000021FC   0000004021FC      0   WriteFile
000000002208   000000402208      0   CreateFileA
0000000021BA   0000004021BA      0   CreateRemoteThread


'Reversing > Theory' 카테고리의 다른 글

DLL Injection  (0) 2015.08.29
데이터 인코딩  (0) 2015.08.26
Malware Behavior ( 악성코드의 행위 특성 )  (0) 2015.08.20
Code Virtualized - 코드 가상화 참고자료  (0) 2015.08.17
Practical Malware Analysis - 1  (0) 2015.07.31