Information Security

PE 패치를 이용한 DLL 로딩 본문

Reverse Engineering

PE 패치를 이용한 DLL 로딩

leeeeye321 2019. 6. 21. 18:16

[ PE 패치를 이용한 DLL 로딩 ]

실행 파일을 직접 수정하여 DLL을 로딩시켜 봅시다.


TextView.exe 파일을 직접 수정하여 실행 시에 myhack3.dll을 로딩하도록 실습을 진행한다.

myhack3.dll은 www.google.com에서 index.html을 다운 받아서 프로세스에 드롭(drop)시키는 기능을 가진다.

PE 파일에서 어떤 DLL을 import한다는 것은 그 DLL이 코드 내에서 제공하는 export 함수를 호출한다는 의미이다.

myhack.dll도 이를 따라 아무런 기능이 없는 dummy라는 export 함수를 정의한다.


TextView.exe는 읽고 쓰는 기능을 가진 단순한 텍스트 뷰어이다. 

PEview에서 이 프로세스의 IDT(IMPORT Directory Table)를 확인한다. 

import하는 DLL이 각각 IID(IMAGE_IMPORT_DESCRIPTOR) 구조체로 정의되어 있다.  


이를 HxD에서 확인하면 14바이트씩 4개의 IID 구조체, 마지막으로 NULL 구조체까지 총 64바이트를 차지하며 myhack3.dll의 구조체를 추가시킬 자리가 없다는 것을 알 수 있다. 

IDT 전체를 더 크고 비어있는 영역으로 이동시키고 DLL을 추가해야 한다.


.rdata 섹션의 끝 부분에 Null padding 영역이 있다. 이 부분을 사용하기 전, 메모리에 로딩되는 부분인지 확인해야 한다.


메모리에 로딩되었을 때 섹션의 크기(VirtualSize)는 2C56이다. 파일 크기(Size of Raw Data)는 2E00이고 사용되지 않는 크기는 2E00-2C56=1AA로 기존의 IDT가 위치하기에 문제가 없다.

이제 TextView.exe를 직접 수정해 봅시다.


IMAGE_OPTIONAL_HEADER에서 IMPORT Table 구조체 멤버는 IDT의 위치와 크기를 알려준다.


HxD로 이 값(Offset:160)을 찾아가서 이제부터 IDT의 위치는 .rdata 섹션의 Null padding 영역 8C80이고, 사이즈는 78(64+14)라고 수정한다.  


DLL 로딩 속도를 향상시키는 기법인 BOUND IMPORT Table은 옵션이므로 편의상 값을 0으로 만든다.

 

기존 IDT를 모두 복사한 후 새로 정의한 IDT에 [Paste Write]로 덮어쓰기한다.


IDT가 7E80~7EE3로 인식되었고, 이제 7ED0~7EE0에 myhack.dll의 IID를 구성하면 된다.


IID는 이렇게 생겼다.



 7ED0(OriginalFirstThunk)

 INT의 RVA(8D00)

 7F00

 INT(8D30)

 INT의 각 원소가 가리키는 값은 IMAGE_IMPORT_BY_NAME 구조체 포인터이다.

 7F30

 IMAGE_IMPORT_BY_NAME 구조체

 Ordinal(0000) + function name string(dummy:임포트하려는 함수)

 7EDC(Name)

 DLL Name의 RVA(8D10)

 7F10

 DLL Name(myhack3.dll)

 7EE0(FirstThunk)

 IAT의 RVA(8D20)

 실행 시에 PE 로더에 의해 실제 함수의 주소로 덮어쓴다.

 7F20

 IAT(8D30)


실행 시 IAT는 PE 로더에 의해서 실제 함수로 덮어쓰기 때문에 .rdata 섹션은 WRITE 속성을 가져야 한다.

Characteristics 값에 IMAGE_SCN_MEM_WRITE(80000000) 속성 값을 추가해 준다. 40000040 | 80000000 = C0000040


★ .rdata 섹션에 쓰기 속성 없이 정상적으로 실행하려면?

IAT 영역(6000~6154)에 IAT가 존재하면 된다. 위에서는 임의로 정한 부분에 dummy()의 IAT를 정의했는데, 

쓰기 속성을 원래대로 없애고 IAT 영역에 정의해 보겠다.


IAT 영역으로 가서 끝 부분(5354)에 dummy()의 IAT(8D30)를 추가한다.


myhack3.dll의 IID에 가서 IAT의 RVA를 6154(Offset:5354)으로 변경한다. 이렇게 dummy()의 IAT가 IAT 영역에 위치하므로, 쓰기 속성이 없어도 정상적으로 실행될 것이다.  


myhack.dll의 IID 구조체 멤버의 값이 설정되었다.


INT를 확인하면 dummy() 함수가 추가되어 있다.


이제 수정을 완료한 TextView.exe을 실행해 본다.

로딩되어 있는 myhack3.dll은 구글의 index.html을 다운받아서 TextView.exe에 드롭시킨다.


구글 사이트인 것을 확인한다. 이렇게 IDT를 수정하여 DLL 인젝션에 성공했다.

'Reverse Engineering' 카테고리의 다른 글

Debug 방식의 API 후킹  (0) 2019.07.04
Code Injection  (0) 2019.06.26
DLL Ejection  (0) 2019.06.21
DLL Injection - Remote Thread 생성 & 레지스트리 이용  (0) 2019.06.20
Windows Message Hooking  (0) 2019.06.17