chapter 1. 걸어서 통과하기

2018. 1. 22. 03:310x03 Reversing Theory/역공학 연습문제

728x90

특정 악성코드의 일부 코드라고 한다. 이 코드에서 배울 수 있는 건 아주 많다. 

그래서 하나하나 다 적으면서 복습을 해보려고 한다.

넘나 재밌는거.....!! 

하루 하루 지날 때 마다 한 단계씩 지식이 늘어나는 것 같아서 너무 좋다 ! 

그럼 잡담은 그만하고 공부하자. 


핵심 : 

1. 작성 된 DLL 일부 이다

2. 목표로 삼은 컴퓨터의 IDT 변조를 파악한다. -- IDT의 존재에 대해 오늘 처음 알았죠.

3. 목표로 삼은 컴퓨터가 윈도우즈에 로그인 되어 있는지 파악한다. (explorer.exe를 통해) -- 이렇게 파악을 한다는 거면 컨셉이 RCE인가.?

4. 목표로 삼은 컴퓨터에 영향을 줄 스레드를 만든다. -- 스레드 안에서 조용히 은닉되어서 악의적 행위를 하려고 하는 것 같다. 내가 최근에 작성해 본 코드도 스레드안에서 자동으로 체력을 깎이게 만들어 봤으니 이 체력이 악의적 행위로 탈바꿈 되면 악성코드가 되는 것이다 ㅠㅠ 


BOOL __stdcall DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)

_DllMain@12 proc near



push ebp -----> 기저 프레임포인터를 저장 

mov ebp, esp --> 함수 프롤로그 설정 

sub esp, 130h --> 현 함수의 스택 크기 설정 

push edi --> edi를 스택에 저장 

sidt fwrod ptr [ebp-8] --> 6바이트 IDT 레지스터를 특별한 메모리 영역에 씀 

mov eax, [ebp-6]  # 이런주소의 값을 대입하는 건 처음 보았다. // IDT 기저주소를 읽음 

cmp eax, 8003F400h 

jbe short loc_10001C88 


cmp eax, 80047400h

jnb short loc_10001C88

// ------------> 기저주소의 변형여부를 탐지 함

if (IDT > 0x8003F400 && IDT < 0x8003F400) 

{

return FALSE;

}


// 

xor eax, eax --> 사용한 eax를 초기화 시킴 

pop edi --> 스택에서 사용한 edi를 복구 시킴 

mov esp, ebp 

pop ebp --> 이전 함수로 돌아가기 위해 ebp를 레지스터로 복구 시킴  --> 함수 에필로그 

retn 0Ch


loc_10001C88:

xor eax, eax

mov ecx, 49h

lea edi, [ebp-12Ch]

mov dword ptr [ebp-130h], 0

push eax // CreateToolhelp32Snapshot의 th32ProcessID

push 2 // CreateToolhelp32Snapshot의 dwFlags

rep stosd  // ecx 반복의 경우 edi가 가리키는 곳으로 eax의 내용을 저장하고 매번 4 바이트 씩 edi를 증가 또는 감소시킵니다 (방향 플래그에 따라 다름). 일반적으로 이것은 memset-type 작업에 사용됩니다. (출처 : https://stackoverflow.com/questions/3818856/what-does-the-rep-stos-x86-assembly-instruction-sequence-do)

--... 뭔소린지...--


call CreateToolhelp32Snapshot // eax와 2를 인자 값으로 사용하는 함수


mov edi, eax

cmp edi, 0FFFFFFFFh // if(edi == -1)

jnz short loc_10001CB9

xor eax,eax --> init

//

if(edi == -1)

{

__asm

{

xor eax, eax

}

return eax

}

//

pop edi

mov esp, ebp

pop ebp    // edi와 ebp를 정리하지 않으면 올바르게 retn이 되지 않는다 ( p.18 3번에서 테스트 함 )

retn 0Ch


loc_10001CB9:

lea eax, [ebp-130h] // mov dword ptr [ebp-130h], 0 로 인해 [ebp-130h] 안의 값은 0이고, [ebp-130h]의 주소를 eax에 복사

push esi // 3개의 레지스터를 스택에 push 한다

push eax --> Process32First 함수 -> lppe

push edi --> Process32First 함수 -> hSnapshot

mov dword ptr [ebp-130h], 128h // 0x128로 init

call Process32First // 시스템 스냅 샷에서 발생한 첫 번째 프로세스에 대한 정보를 검색

이  부분은 조금 많이 중요해 보여서 상세 분석을 들어 갔다. 악성코드에서 아주 유용하게 사용되는 api함수 같기도 하고..

Process32First 함수 같은 경우는 2개의 인자를 가지고 있다. 첫 번째로 HANDLE hSnapshot, 두 번째로 LPPROCESSENTRY32 lppe를 소유하고 있는 함수이다. WIN32API에서 핸들이란 아주 중요하다고 봐야 한다. 어떠한 모듈들을 다룰 때 사용되기 때문이다.  상기에서 push edi를 hSnapshot이라고 표기한 이유는 다음과 같다.  edi를 어디서 썼는지 한번 살펴 보고 오자.

call CreateToolhelp32Snapshot // eax와 2를 인자 값으로 사용하는 함수


mov edi, eax


CreateToolhelp32Snapshot의 반환 값이 eax 일테고, 그 값을 edi에 대입했으니까 edi 또한 반환 된 값이라고 볼 수 있다.



그렇다면, push edi는 CreateToolhelp32Snapshot 함수에서 핸들을 반환 해온 값이라고 보면 된다. 

그럼, lppe는 무슨 값을 나타낼까?

lea eax, [ebp-130h] 여기에서 보면 알 수 있듯이 지역변수 (ebp-130h)의 주소를 가리키고 있다.


lppe의 데이터 형이 LPPROCESSENTRY32 인 것으로 보아 lppe는 LPPROCESSENTRY32의 구조체 변수라고 볼 수 있다.


loc_10001C88:

xor eax, eax

mov ecx, 49h

lea edi, [ebp-12Ch]

mov dword ptr [ebp-130h], 0

push eax // CreateToolhelp32Snapshot의 th32ProcessID

push 2 // CreateToolhelp32Snapshot의 dwFlags

rep stosd

해당 루틴이 구조체를 0으로 초기화 하는 구문이라고 하는데 유독 이 부분은 이해가 안 된다... 

구조체 공부를 더 깊게 해야하는 것인가 ! 

해결 : rep가 ecx가 0이 될 때까지 반복하는 명령어 , stosd는 edi가 가리키는 주소에 eax 저장 그렇다면 구조체 변수는 감소연산자를 가진 반복문 구문안에서 0으로 초기화가 된다고 보면 됨.  

지역변수 범위 ebp-130h ~ ebp-12Ch

잠온다.  일어나서 마저 하자 ㅎㅎ 


test eax, eax //eax init to 0

jz short loc_10001D24 

mov esi, ds:_stricmp 

lea ecx, [ebp-10Ch] // ecx에 지역변수(ebp-10Ch)주소를 설정하는데 PROCESSENTRY32에 있는 영역이 된다.

push 10007C50h // szExeFile의 주소가 0x10007C50 이다 -> 책에 따르면 'explorer.exe'라고 한다 

push ecx  // PROCESSENTRY32에서 szExeFile 필드 

call esi ; _stricmp

add esp, 8     // stricmp가 cdecl 호출 규약이기 때문에 add esp, 0x8을 통해 스택을 지운다. 즉 esp를 올린다고 보면 된다

test eax, eax

jz short loc_10001D16 


loc_10001CF0:

lea edx, [ebp-130h]

push edx // [ebp-130h] 주소를 edx에 복사 --> _Out_ LPPROCESSENTRY32 lppe

push edi -->  _In_  HANDLE           hSnapshot

call Process32Next // edx와 edi를 인자 값으로 사용함 

test eax, eax // Process32Next의 반환 값을 and연산 취했을 때 결과에 따라 분기가 달라짐 

jz short loc_10001D24

lea eax, [ebp-10Ch]

push 10007C50h

push eax

call esi ; _stricmp

add esp, 8 // esp 정리 (2번)

test eax, eax 

jnz short loc_10001CF0


loc_10001D16:

mov eax, [ebp-118h] // PROCESSENTRY32's th32ParentProcessID

mov ecx, [ebp-128h] // PROCESSENTRY32's th32ProcessID

jmp short loc_10001D2A


loc_10001D24:    

mov eax, [ebp+0Ch]

mov ecx, [ebp+0Ch] // eax와 ecx 둘 다 저장 해두는 군..


loc_10001D2A:

cmp eax, ecx // DllMain(ebp+8)의 매개변수 fdwReason을 읽고 0인지 검사

pop esi

jnz short loc_10001D38

xor eax, eax

pop edi

mov esp, ebp

pop ebp

retn 0Ch


loc_10001D38:

mov eax, [ebp+0Ch]

dec eax

jnz short loc_10001D53

push 0

push 0

push 0

push 100032D0h

push 0

push 0

call ds:CreateThread // 6개의 인자를 넣음 


loc_10001D53:

mov eax, 1

pop edi

mov esp, ebp

pop ebp

retn 0Ch

__DllMain@12 endp



끄읏 ~  

'0x03 Reversing Theory > 역공학 연습문제' 카테고리의 다른 글

p. 38  (0) 2018.01.22
p. 18  (0) 2018.01.21
주저리주저리  (0) 2018.01.21