ROP를 이용한 DEP 우회공격 – (1) Basic Idea

 

본 문서는 Corelan.be 사이트의 tutorial을 기초로 작성되었습니다.

— 시작하기에 앞서 : DEP란 무엇인가 —

어떤 프로그램을 Exploit 하는데 사용되는 기법은 매우 다양하지만
그 중에서도 가장 많이 볼 수 있는 케이스가 바로 Overflow 공격이라 할 수 있겠다.
코드상 정의된 메모리 변수 영역보다 큰 값이 입력되었을 경우 이 값을 검증하지 않았을 때
발생하는 Overflow 공격의 핵심적인 요소는 바로
[메모리 상에서 공격자가 입력한 쉘코드가 실행] 되는 것에 있다.

이와 같은 공격을 방어하기 위해 M$ 형님들은 스택상 로드된  쉘코드가
실행되지 않도록 하였는데 이를 DEP (Data Execution Prevention)이라 한다.
간단하게 DEP의  의미를 짚어보고 넘어가보자.

DEP(데이터 실행 방지)는 바이러스 및 다른 보안 위험으로부터 컴퓨터가 손상되는 것을 방지해 줄 수 있는 보안 기능입니다. 위험한 프로그램이 Windows 및 다른 공인 프로그램에 대해 예약된 시스템 메모리 위치에서 코드 실행을 시도하여 Windows 공격을 시도할 수 있습니다. 이러한 종류의 공격으로 인해 프로그램 및 파일이 손상될 수 있습니다.

DEP는 프로그램을 모니터링하여 프로그램이 시스템 메모리를 안전하게 사용하게 함으로써 컴퓨터를 보호합니다. DEP는 컴퓨터에서 메모리를 부적절하게 사용하는 프로그램을 감지하면 해당 프로그램을 닫고 사용자에게 알려 줍니다.

출처 : http://windows.microsoft.com/ko-kr/windows-vista/what-is-data-execution-prevention

 

쉽게 풀어쓰자면 Overflow로 인한 메모리 영역의 훼손이 발생하더라도,
실행 (Execution)을 방지함으로써 공격을 방어할 수 있는 기법이다.

일반적으로 프로그램에서 Stack-Overflow와 같은 취약점이 발생하명 아래 그림과 같이
스택영역을 사용자가 입력한 쉘코드(Shellcode)로 덮어 쓸 수 있으며,
EIP 레지스터 조작을 통해 해당 코드를 실행할 수 있게 된다.

stack_over_flow
[우측 하단 – 스택영역에 덮어 써진 쉘코드]

그러나 DEP 가 활성화 되어 있을 경우, 보호된 메모리 영역에서 코드를 실행이 감지되면
Accesss Violation이 발생하면서 프로그램이 종료되어 버린다.
따라서 공격자는 메모리 제어가 가능하더라도 쉘코드를 실행할 수가 없다.

 

— DEP 우회기법 : ROP (Return Oriented Programming) —

앞서 말했듯이 DEP 를 통해 보호된 메모리 영역에서는 공격자가 삽입한 코드의 실행이 불가능하다.
그러나 이미 로드된 (정상적으로 실행가능한 영역에서 추출된) 명령어 코드는 사용이 가능하다.
다시 말해 새로운 코드를 사용하는 것이 아니라 “이미 프로그램 내부에 존재하는 코드 조각들을 끼워 맞추는 것”이다.
Cap 2014-06-10 15-09-43-574

위 코드를 잠시 살펴보자.

코드 영역을 보면 PUSH ESP  / AND AL, 10 / POP ESI / MOV [EDX], ECX / RETN 명령어가 있는데
아래와 같이 해석이 가능하다.

1. 현재 ESP값을 스택에 저장 (PUSH)
2. AL 값과 10을 AND 연산
3. 현재 ESP값을 꺼내 (POP) ESI 저장
4. ECX값을 [EDX] 에 저장
5. RETN

우리가 주목해야 할 부분은 1 / 3 / 5 번 명령구문이다.
1-5를 하나의 코드 조각이라고 가정해보자.
만약 EIP가 이 “코드조각”을 가리키도록 만들 수 있다면 “현재 ESP값을 ESI로 복사” 할 수 있게 된다.
즉, 실행가능한 영역에 존재하는 코드조각을 통해 공격자가 원하는 행위를 이끌어낼 수 있는것이다.
(여기서 공격자가 원하는 행위 = ESP값을 ESI로 복사하는 것)

마지막 RETN가 실행되면 우측 하단에 보이는 ESP값 (000FF734)이 EIP로 셋팅되고,
다음 코드조각 (000FF734)이 실행됨으로써 원하는 행위를 연속적으로 할 수 있다.

Cap 2014-06-10 15-40-53-251[ROP 체인을 통한 명령어 수행]

 위에서 설명한 내용을 간단하게 도식화 하면 위 그림과 같다.

ROP Gadget (코드 조각)은 모두 정상적으로 로드된 영역에서 추출한 것인데,
공격자는 이러한 코드 조각들 중  “쓸만한” 것들을 먼저 선별한 후, 해당 주소 (Address)를
스택에 연속적으로 배치함으로써 DEP를 우회하여 공격할 수 있다.

(일단 이해가 안가더라도 그냥 그런게 있구나 하고 넘어간다.)

 

— DEP를 우회할 수 있는 윈도우 API —

기본적으로  “ROP Gadget – 코드조각들 -” 활용 방법을 알게 되었으니
본격적으로 DEP를 우회하는 방법에 대해 알아보자.

DEP를 우회기법은 DEP 설정 자체를 Disable 시키거나 혹은 기능을 우회하는 방법이 있으며,
윈도우에서 제공되는 API중 DEP Bypass와 관련된 것은 아래 표와 같다.

Module XP SP3 Prof
English
kernel32 :
5.1.2600.5781
ntdll :
5.1.2600.5755
Server 2008 SP2
Std – English
(ASLR)
kernel32 : 6.0.6002.18005
ntdll : 6.0.6002.18005
Vista Business SP2 (ASLR)
kernel32 : 6.0.6002.18005
ntdll : 6.0.6002.18005
Windows 7 Prof
English (ASLR)
kernel32 : 6.1.7600.16481
ntdll : 6.1.7600.16386
VirtualAlloc (kernel32.dll) 0x7C809AF1 0x0217AD55 0x0105ad55 0×02810614
HeapAlloc (kernel32.dll) 0x7C8090F6 0x021F9AEA 0x010d9aea 0x0287f026
HeapCreate (kernel32.dll) 0x7C812C56 0x02159D0B 0x01039d0b 0x02812a57
SetProcessDEPPolicy (kernel32.dll) 0x7C8622A4 0x021C5980 0x010a5980 0x027f85a7
NtSetInformationProcess (ntdll.dll) 0x7C90DC9E 0x002c5324 0x00d55324 0x00d85ac0
VirtualProtect (kernel32.dll) 0x7C801AD4 0x02131DC3 0x01011dc3 0x028050ab
WriteProcessMemory (kernel32.dll) 0x7C802213 0x02131CB8 0x01011cb8 0x028085c1
memcpy (ntdll.dll) 0x7C901DB3 0x002a9720 0x00d39720 0x00d740f0
    (offsets) (offsets) (offsets)

1. VirtualAlloc : 새로운 메모리 영역을 할당한 후 (새 영역의) 실행 및 접근 수준을 변경할 수 있다.
2. HeapAlloc : VirtualAlloc과 유사한 형태이나 Heap 영역을 사용한다.
3. SetProcessDEPPolicy : 현재 프로세스에 대한 DEP 정책을 변경할 수 있다.
4. NtSetInformationProcess : 현재 프로세스에 대한 DEP 정책을 변경할 수 있다.
5. VirtualProtect : 주어진 메모리 영역에 대한 보호 수준을 변경할 수 있다.
6. WriteProcessMemory : 특정 메모리 영역을 다른 위치로 복사할 수 있다.

그러나 제공 되는 API를 모두 사용할 수 있는 것은 아니다.
아래와 같이 OS 환경별로 사용가능/불가능한 API가 있으므로,
공격 환경에 맞게 API를 선택하여 사용해야 한다.

API / OS XP SP2 XP SP3 Vista SP0 Vista SP1 Win 7 Win 2003 SP1 Win 2008

VirtualAlloc

yes

yes

yes

yes

yes

yes

yes

HeapCreate

yes

yes

yes

yes

yes

yes

yes

SetProcessDEPPolicy

no (1)

yes

no (1)

yes

no (2)

no (1)

yes

NtSetInformationProcess

yes

yes

yes

no (2)

no (2)

yes

no (2)

VirtualProtect

yes

yes

yes

yes

yes

yes

yes

WriteProcessMemory

yes

yes

yes

yes

yes

yes

yes

(1) 사용 불가 / (2) DEP 정책으로 인해 사용 불가

 모든 운영체제에서 사용가능한 API중에서 VirtualAlloc, HeapCreate의 경우
다른 API와의 ROP체인 연결이 필요하여 조금은 복잡할 수 있으므로,
다음장 (실습)에서는 VirtualProtect를 통해 DEP 우회 공격을 시도해보도록 하겠다.

 

— 이번 내용을 정리하자면 —

1. 운영체제는 메모리상의 쉘코드 방지를 위해 DEP 기법을 사용한다.
2. 메모리상의 코드는 실행이 불가능하므로, 실행 가능한 코드 조각 (ROP)을 모아
Chain 형태로 연결한다.
3. DEP 우회가 가능한 API + ROP Gadget을 이용하면 공격이 가능하다.

 

<참고 레퍼런스>

https://www.corelan.be/index.php/2010/06/16/exploit-writing-tutorial-part-10-chaining-dep-with-rop-the-rubikstm-cube/

Site Footer