잰이_IT/보안 - 리버싱

리버싱 핵심원리_ 어셈블리를 이용한 code Injection

janey25 2018. 8. 10. 19:28

 

리버싱 핵심원리_ 어셈블리를 이용한 code Injection


- OllyDbg Assemble 기능을 이용해 인젝션 코드 Thread Proc() 함수 생성 

- Assemble 기능을 이용하면 c언어보다 더 자유로운 코드 생성가능

- ThreadProc() 함수는 notepad.exe에 인젝션


- EIP 주소 바꾸기 기능 알아두기!

-> 'New Origin Here'

- 여기서 코드에 Space -> 어셈 프로그래밍 준비 완료!


- 코드뿐만이 아니라 Data(문자열) 포함이라는 것이 핵심!!

- Analysis 명령 -> 코드 재해석 기능


 인젝터 제작


- ThreadProc() 함수 바이너리 코드 얻기

-> 주소로 이동 후 파일 저장, 텍스트 에디터로 열어본다.

Hex로 이루어진 IA-32명령어가 바로 인젝션할 코드

- Cpp 코드 앞에랑 다른점 -> 인젝션 코드에 필요한 문자열 데이터도 함께 포함한다는 것

- THREAD_PARAM 구조체에서 문자열 멤버를 따로만들 필요 읍따.


- 코드 인젝션 후 디버깅,, 인젝션 성공하면 스레드 코드 시작 위치에 멈츈다


상세분석


1. 스택프레인 생성 명령어 '55 8BEC'

-> 목적은 함수 종료시 스택 정리를 위함

2. THREAD_PARAM 구조체 포인터

- [EBP+8] 에 함수로 넘어온 첫번째 param = THREAD_PARAM 구조체 포인터

- 첫번쨰는 LoadLibraryA() API, 두번째는 GetProcAddress() API 

- 인젝션 후 스레드 실행시 저장

- 명령어 실행 후 ESI 레지스터 주소 확인해보면 THREAD_PARAM 구조체 위해 

notepad.exe 프로세스 메모리 공간이 할당한 메모리 버퍼 주소 저장되어있음

3. "user32.dll" 문자열

- Push 6c6c 명령 -> 스택에 값을 저장해라! (6c 가 1이라는 뜻)

- Little Endian 이므로 문자 뒤집히는거 조심하깅

+ 코드 인젝션시 데이터 따로 말고 코드에 포함시켜 코드만 인젝션 가능!

4. "user32.dll" 문자열 param 입력

- LoadLibraryA() API는 param 로딩시 DLL 파일 이름 문자열 주소 받기

- ESP 값 -> 문자열 시작주소

- PUSH ESP 명령어 -> ESP 스택 입력

5. LoadLibraryA("user32.dll") 호출

- ESI엔 LoadLibraryA() API 시작 주소 저장 -> CALL ESI 전개식 보기

- CALL 명령어 실행 -> LoadLibraryA() 호출 -> Param "user32.dll" 로딩

-> 로딩주소 리턴 => EAX에 저장

6. "MessageBoxA" 문자열

- 3번과 동일한 방법

7. GetProcAddress(hMod,"MessageBoxA") 호출

- 현재 EAX -> user32.dll 로딩주소

- PUSH ESP -> MessageBoxA 문자열 스택 입력

-> PUSH EAX -> user32.dll 시작 주소를 hMod를 스택에 입력

- [ESI+4] -> GetProcAddr 주솟값 -> CALL GetProcAddr-

-> CALL[ESI+4]는 GetProcAddress(-,"MessageBoxA") API 를 호출하는 것

=> 이렇게 하면 user32.dll Message-() API 시작 주소가 EAX 레지스터에 저장

8. MessageBoxA() PARAM 입력

- MB_OK, ReverseCore, www.reversecore.com,NULL

1) PUSH 0 -> 스택에 0이력 -> MessageBoxA() 의 네번째 param 인 uType 으로 들어감

2) Call로 코드 사이 포함 문자열 데이터 주소 스택에 입력

        문자열 세번째 Param인 Ip Caption 으로 사용

  Call -> Push + Jmp 동작원리 알아두기

3) 2와 동일

4) MessageBoxA() API 첫 번째 Param 인 hWnd 값 입력_ 메세지 박스 소속창 핸들 입력 => 0이니까 무소속!


12. MessageBoxA() 호출

- CALL EAX -> GetProc 에 의해 리턴된 MessageBoxA() 시작주소 저장

13. ThreadProc() 리턴 값 세팅

- notepad.exe의 인젝션 코드 (ThreadProc() 스레드 함수) 종료준비

- 리턴값 EAX -> 0으로 셋팅 XOR사용, 쉽고 빠름

14. 스택 프레임 해제 + 함수 리턴

- THreadProc() 함수 시작시 생성 스택 프레임 해제 -> Returen -> 종료

- 스택 프레임 중요!! -> pop 으로 일일이 없앨필요 없고 쉽고 편리한 초기화~!!