Try Attack/Reverse Engineering[basic]

위장 악성코드를 실행하는 방법

D4tai1 2019. 5. 31.

※ OS : Windows환경의 악성코드

 

1. 위장 악성코드

▶ 악성코드 제작자는 악성코드를 은닉하기 위해 여러가지 방법을 개발한다.

▶ 즉, 탐지를 우회하기 위해 위장 실행 기법을 개발한다.

 

 

2. Launchers(실행기)

(1) Launcher란?

 [1] Loader라고도 부르며 현재 실행하고 있거나 추후에 (은밀하게) 실행하기 위해 자기자신이나 다른 악성코드를 설정하는 악성코드이다.

 [2] 편의상 exploit이라고 생각하려고 한다.

 

(2) Launcher가 필요한 이유?

 [1] 나쁜 짓 할 때 사용자에게 걸리지 않으려고? 설정하기 위해서..ㅎ

 

(3) Launcher가 로딩할 악성코드를 포함한 경우

 [1] .exe파일이나 .dll을 자신의 resource section에 가지고 있다.

 [2] PE파일은 resource section은 .exe에서 사용하기는 하지만, 실행이 가능한 영역은 아니다.

 [3] resource section은 보통 아이콘, 이미지, 메뉴, 문자열 등을 가지고 있다.

 [4] Launcher가 실행될 때 resource section에서 내장된 .exe나 .dll을 추출해서 실행한다.

 

(4) 만약 resource section이 압축이나 암호화 됐다면?

 [1] 악성코드를 로딩하기 위해 resource section에서 추출해야 한다.

 [2] 추출 시에는 FindResource, LoadResource, SizeofResource와 같은 resource 처리 API를 사용해야 한다.

 [3] 필요하다면 관리자권한을 얻기 위해 권한상승도 해야한다.

  ▶ Launcher를 탐지하는데 좋은 방법 중 하나는 권한 상승과 관련된 코드가 있는지 찾는 것이다.

 

 

3. Process Injection

(1) 프로세스 인젝션이란?

 [1] 코드를 실행 중인 프로세스에 인젝션 한다.

 [2] 가장 보편화되어 있으며 악성행위(나쁜짓)를 숨기기 위해 사용한다.

 [3] 호스트기반 방화벽과 프로세스에 특화된 보안 매커니즘을 우회할 때 사용한다.

 [4] 프로세스 인젝션에 사용되는 API는?

  ▶ VirtualAllocEx : 원격 프로세스의 메모리에 공간을 할당한다.

  ▶ WriteProcessMemory : 할당된 공간에 데이터를 쓸 때 사용된다.

 

(2) DLL Injection

 [1] 원격의 프로세스가 악의적인 DLL을 로딩하게 하는 프로세스 인젝션 중 하나이다.

 [2] 가장 흔히 사용되는 위장 로딩 기법으로 LoadLibrary를 호출하는 원격프로세스에 코드를 삽입해 해당 프로세스가 DLL을 강제로 로드하게 된다.

 [3] 감염된 프로세스가 악의적인 DLL을 로딩하면 OS는 DLL의 DllMain함수를 호출한다.

 [4] DllMain에 악의적인 코드가 포함되어 있으며, 해당프로세스의 메모리에 대한 접근권한을 갖는다.

 [5] 동작하는 모든 작업은 감염된 프로세스에 의존적이다.

 [6] 악성코드 로더는 프로세스 기반 방화벽에 차단되서 인젝션 전까지는 다른 프로세스에 접근이 불가능하다.

 

정리는 여기까지 하고 피피티로 이미 정리한 내용을 올리려고 합니다~~

 

 

 

 

 

▶ 이 말은 Launcher를 탐지하는 좋은 방법 중 하나는 권한상승 관련된 코드를 찾는 것을 말합니다.

 

 

▶ DLL은 플러그인이나 기능추가 시 사용되고 다른 프로그램이 불러서 사용한다.
▶ 이 말은 DLL을 프로세스에 삽입하면 DllMain 실행될 것이고,
▶ 그렇다면 DllMain에 악성코드를 넣어 실행하도록 한다.

 

▶ 원래 DllMain은 프로세스나 스레드별로 초기화를 수행하는 목적으로 호출된다.

 

 

 

▶ 인젝션할 프로세스에 대한 제어권을 얻으려면?? PID가 있어야 한다.

 

▶ GetWindowThreadProcessId()의 파라미터로 윈도우번호와 PID를 가져올 주소 를 넣는다.
 

 

▶ 프로세스의 핸들을 얻었다는 것은 프로세스가 사용하는 메모리 공간에 접근이 가능하다!!

 

▶ 프로세스가 사용하는 메모리공간에 호출할 DLL의 경로와 길이
 

 

▶ 인젝션할 DLL경로를 프로세스에 기록하기 위해서는 공간을 확보한다.
 
 

 

▶ 프로세스에서 DLL을 로드하려면 LoadLibrary() 함수를 사용해야 하는데

 

▶ LoadLibrary함수는 kernel32.dll에 들어있다.
 

 

▶ 이제 LoadLibrary()함수만 호출하면 내가 만든 dll이 프로세스 내부에 올라가게 된다.
▶ 그렇다면 LoadLibrary()를 어떻게 호출할까..?
▶ 원격에서 프로세스 내부에 스레드를 생성하고
▶ 스레드의 시작지점을 LoadLibrary()함수의 주소로 작성한다.

 

▶ 생성이 되었다면 DLL이 인젝션되고 악성스크립트가 있는 DllMain()함수가 동작한다.
 
 

▶ DLL이 로드되었을 때 운영체제는 DllMain()함수를 호출하고 운영체제가 호출하는 함수는 검사대상이 아니다.
▶ 키로거를 실행시키면 검사를 하지만.. 
▶ 메모장에 키로거 코드가 작성된 dllmain이 있는 dll을 추가한다면 입력한 내용이 외부로 전송되도록 할 수 있다.

 

▶ 걸리지 않는 이유는 메모장은 안전한 프로그램이기 때문이다.
 
 

 

▶ 대기상태의 프로세스를 생성 한다.
▶ Suspended State 프로세스는 메모리에 로드는 했지만 프로세스의 메인스레드가 대기 중인 상태 를 의미한다.
▶ 즉, 외부프로그램이 해당프로세스의 메인스레드를 부르기 전까지는 아무것도 하지 않는다.
 

 

▶ 메모리에 로드 후 ResumeThread() 함수가 호출될 때까지 대기 한다.
 

 

▶ 코드가 메모리에 올라가있지만 실행되지 않은 상태에서  정상코드를 메모리상에서 할당 해지한다.
▶ 이유는? 새로운 코드를 쓰기 위해서~

 

 

 

▶ 파라미터로는 후크프로시저의 유형을 지정하고, 후크프로시저의 포인터, 스레드식별자(TID)를 넣어줍니다.

 

 

▶ 아까와 동일하게 인젝션할 프로세스를 찾고 내부의 스레드 중 하나를 찾습니다.

 

 

▶ IAT는 어떤 라이브러리에서 어떤 함수를 사용하고 있는지를 기술한 테이블 을 말한다.
 

 

▶ 먼저 동기 함수 호출은 무엇일까? 일반적으로 우리가 함수를 호출하는 것을 말한다.
▶ 그렇다면 비동기 함수 호출은?? CALLBACK함수를 말한다. 
▶ Callback함수란??
▶ 시스템에서 이벤트 발생시 자동으로 호출하는 형태
▶ 사용자가 호출하는 형태가 아니고...
▶ 회사에 가서 면접을 본 면접자들이 각자 회사로 전화하면 면접 결과도 나오지 않았는데 번거로운 상황이 발생한다.
▶ 그래서 회사가 결과가 나왔을 때 면접자들에게 통보해주는 방식과 비슷하게 생각하면 된다.

 

 

▶ Callback 함수의 형태
▶ 원형을 보면 파라미터가 포인터변수 하나를 받는데 잘 이용하면 개수 상관없이 어떤 데이터타입이라도 보낼 수 있다.

 

▶ 호출하는 방법은? CALLBACK함수이므로 사용자가 함수이름을 써서 직접 호출하지 않을 것으로 예상된다.
 
 

▶ Callback 함수를 호출하는 방법
▶ QueueUserAPC API를 이용해서 호출할 수 있다.
▶ APC Procedurefunction pointer를 넣어주고,
▶ APC Procedure를 호출할 thread를 넣어주고,

 

▶ APC Procedureparameter를 넣어준다.
 

 

 

▶ 검정색은 thread를 말하고 Waitingthread의 상태를 말한다.
▶ 아무 것도 하지 않는 대기 상태 이다.

 

▶ 생성되거나 Sleep()함수 사용했을 때 아무 것도 하지 않는 것과 동일 하다.
 
 

▶ Waiting 상태에서 특정 이벤트가 발생했을 때 OSReady상태로 변경해준다.
▶ CPU에서 thread를 사용할 수 있다.

 

▶ 그러나 CPU에게서 단위시간을 할당받지 못했다.
 
 

 

▶ 현재 CPUthread를 수행하고 있다.

 

▶ 스케줄링에 따라 멈췄다가 동작하다가 반복 한다.
 

 

 
▶ Waiting상태에서 특정이벤트가 발생하면 OSthreadReady상태로 변경하고 CPUReady상태인 Thread를 사용할 수 있다.
▶ Scheduling기법에 따라 ReadyRunning을 반복 한다.
 

 

 

▶ 앞에서 말한 것과 같이 Sleep()함수를 사용하면 Waiting상태에 도달하지만
▶ SleepEx()와 같이 Ex()가 붙은 API를 사용하면 alertable상태로 진입하도록 할지 선택할 수 있다.

 

▶ 2번째 파라미터에 true를 넣어준다면 threadalertable상태로 진입한다.
 

 

▶ Alertable상태로 진입한 threadAPCQueue라고 부르는 Queue에서 Queueing된 정보가 있는지 확인한다.
▶ Queueing된 정보란? QueueUserAPC()함수에 의해 전달된 3가지 파라미터가 하나의 node가 된다.

 

▶ ThreadQueue로부터 하나의 node를 빼와서 지정된 함수를 호출하게 된다.

 

 

▶ Alertable상태로 진입한 threadAPCQueue라고 부르는 Queue에서 Queueing된 정보가 있는지 확인한다.
▶ Queueing된 정보란? QueueUserAPC()함수에 의해 전달된 3가지 파라미터가 하나의 node가 된다.
▶ ThreadQueue로부터 하나의 node를 빼와서 지정된 함수를 호출하게 된다.
▶ 결국 APC Injection이란 정상적인 경로를 실행하기 전에 alertable상태인 thread를 선점해놓고

 

▶ APC_QueueQueueUserAPC() API를 넣고 alertable상태로 진입한 thread에게 Callback함수를 실행하도록 하는 것을 말한다.
 

 

▶ 내용이 복잡하지만 간단하게 설명하면
▶ 공격할 process를 찾기 위해 for문을 돌면서
▶ OpenProcess() Process의 핸들을 얻어온 후
▶ process 내에서 사용하는 thread alertable상태에 진입할 가능성이 있는

 

▶ ThreadOpenThread()thread의 핸들을 얻어온다.
 
 

▶ , WaitFor..Ex 이런 함수를 찾는 방식을 말한다.
 

 

▶ QueueUserAPC()함수에 DLL을 로드하기 위해 kernel32.dll에 있는 LoadLibraryA()함수의 주소와 수행할 Thread의 핸들을 OpenThread()함수로 얻어서 넣고 DLL의 경로를 넣어준다.
▶ 해당 threadAlertable상태로 전환되었다면 APC_Queue에서 Queueing해서 node를 읽는다

 

▶ 이후 threadLoadLibraryA()함수를 수행한다.
 
 

 

 

 

 

'Try Attack > Reverse Engineering[basic]' 카테고리의 다른 글

파일을 입력받는 프로그램의 취약점분석 및 공격  (0) 2019.11.12
Virtual address  (0) 2019.07.12
MFC_reversing  (0) 2019.05.26
[codegate_2017] angrybird  (0) 2019.04.08
[csaw CTF 2015] wyvern  (0) 2019.04.08

댓글