/ POSTS

windows-0x08

0x08 DEP(2)

What is DEP?

지난 Post에서 RTL을 다루어 봤습니다.

이번 시간에는 RTL에 이어 Chaining RTL에 대해 알아보도록 하겠습니다.

Chaining RTL

Chaining RTL은 RTL이 Chain처럼 엮여서 반복되는 것을 말합니다.

RTL이 뭐였죠? DEP가 적용되어 Shellcode를 실행할 수 없게 되었을 때, 라이브러리 함수로 점프하여

내가 원하는 함수를 실행하는 것이었죠?

Chaining RTL은 말 그대로 내가 원하는 함수를 계속해서 실행하는 것을 뜻합니다.

의미는 알았으니, 본격적으로 알아볼텐데 STACK 구성에 집중해서 보시면 되겠습니다.

먼저, 지난 시간처럼 몇 가지 가정을 하겠습니다.

  • func1(argv1) : 인자를 하나만 필요로 하는 함수
  • func2(argv1’, argv’2) : 인자를 두 개 필요로 하는 함수
  • func3(argv’‘1, argv’‘2, argv’‘3) : 인자를 세 개 필요로 하는 함수

이 함수들을 차례대로 호출한다고 가정하고 이 때, Payload를 어떻게 구성해야하는 것인지를 살펴보도록 하겠습니다.

[그림 1-1]

이 그림 기억나시나요?? 지난 시간에 살펴봤던 함수를 하나만 호출할 때의 STACK 그림입니다.

Main-ret가 다음 호출할 함수의 SFP로 변경되고 있죠? 그래서 그 다음 4 Byte가 호출된 함수가 종료되고 다음에 갈 곳의 주소인 것도 알고 있습니다.

그럼 두 번째 함수(인자가 두 개)를 호출할 때 그림이 이렇게 되겠네요?

[그림 1-2]

Func1() 함수의 RET 자리에 Func2() 함수의 주소를 넣어줬습니다. 그럼 Func1() 함수가 종료된 후, Func2() 함수가 실행됩니다.

간단하죠?

그런데 여기엔 문제가 있습니다. 이 방법으로는 내가 원하는 함수를 마음껏 호출할 수가 없습니다.

그냥 RET에 다른 함수 주소를 덮어주면 되는거 아니야? 라고 생각하실 수 있습니다.

자, 그럼 다음에 Func3() 함수를 호출한다고 생각해봅시다.

Func3() 함수의 주소는 어디에 넣어줘야 하죠?

이미 Func1() 함수의 첫 번째 인자가 위치하고 있습니다. 이제 이해가 가시죠??

이 한계를 해결하기 위해 지금부터는 Gadget을 사용할 겁니다.

RET로 끝나는 많고 많은 Gadget 중에 시스템 해킹에서 주로 사용되는 Gadget은 다음 3가지 입니다. (이것만 쓴다는 게 아닙니다!!)

  • pr : POP RET
  • ppr : POP POP RET
  • pppr : POP POP POP RET

POP 뒤에 Operand는 생략했습니다.

이 Gadget을 이용해서 내가 원하는만큼 함수를 호출하려면 STACK을 다음과 같이 구성하면 됩니다.

[그림 1-3]

조금 이상하고 복잡한 듯이 느껴질 수 있는데, 에필로그 과정부터 Gadget 순으로 색깔별로 보시면 됩니다.

먼저 에필로그부터 살펴보겠습니다.

RETN이 실행되면 POP EIP, JMP EIP를 수행하므로 실행되고 난 후, ESP의 위치는 빨간 ESP 위치가 됩니다.

JMP EIP가 실행되면 POP RETN이 실행되겠죠?

처음 POP이 실행되면 STACK 최상단의 값을 꺼내고 ESP가 올라가면서 ESP의 위치는 파란 ESP 위치가 됩니다.

다시 RETN이 실행되면 POP EIP, JMP EIP가 실행되겠네요.

그럼 그 때의 ESP는 초록색 위치가 되는데 POP EIP를 했으므로 EIP엔 두 번째 함수 Func2()의 주소가 들어가게 될 것이고

JMP EIP를 하면서 Func2() 함수가 실행됩니다.

세 번째 함수까지 모두 호출한다고 가정했을 때, STACK의 구조는 다음과 같이 됩니다.

[그림 1-4]

이런 식으로 STACK을 구성해서 내가 원하는 함수를 계속해서 호출하는 기법을 Chaining RTL이라고 부릅니다.

자, 이제 ROP를 하기 위한 기초 준비 작업을 모두 마쳤습니다.

다음 Post에서 ROP를 알아보고 DEP편을 마무리 짓도록 하겠습니다.