본문 바로가기
Pwnable

Fake EBP

by morae23 2019. 12. 24.

fake ebp 기법은 쉽게 말하면 단어 그대로 ebp에 fake 값을 넣음으로써 eip를 조작하는 기법이다.

 

보통 ROP를 할 때 (32bit를 기준으로) ret+8 부터 인자 값을 맞춰준다.

이 기법의 경우 ret까지만 덮을 수 있을 때 이용되며, leave; ret 가젯을 이용한다.

 

쉽게 이야기하기 위해 fake 값이라고 표현했지만, 물론 아무 값이나 넣는 것이 아니기에 맞춰주어야 할 부분들이 있다.

 

leave; ret에 대해 설명하며 어떤 값들을 넣어주어야하는지도 함께 보려고 한다.

 

우선 leave와 ret은 함수의 에필로그에 해당한다.

에필로그를 확인하기 위해 'Hello World'를 출력하는 간단한 코드를 작성하면, 아래와 같이 함수의 마지막 부분에 leave; ret;이 존재하는 것을 볼 수 있다.

 

 

그렇다면, 이제는 leave와 ret이 무엇인지 알아볼 필요가 있다.

 

# leave
   mov esp, ebp
   pop ebp

# ret
   pop eip
   jmp eip

 

이해를 돕기 위해 스택의 상황을 간단히 그려보았다.

 

1. 아래 3개의 그림 중 첫 번째 그림은 아직 mov esp, ebp가 실행되기 이전의 스택 상태이다.

어떤 함수를 호출한 상태이고, 해당 함수 내에서 buf라는 지역변수를 이용하고 있음을 알 수 있다.

아직 리턴되지 않았기 때문에 esp와 ebp는 검정색으로 표시된 위치에 있다.

 

2. 두 번째 그림은 mov esp, ebp를 실행한 이후이다.

esp가 ebp의 위치로 이동한 것을 볼 수 있다.

 

3. 세 번째 그림은 pop ebp를 실행한 이후이다.

ebp는 sfp에 담겨있던 주소를 가리키게 되고, pop을 했기 때문에 esp 또한 이동하였다.

 

 

이후에 ret (pop eip; jmp eip) 이 실행되면, eip에는 ret에 담겨있던 주소가 들어가고 jmp eip를 실행한다.

 

 


 

 

여기까지가 leave; ret의 동작에 관한 설명이다.

fake ebp의 경우 이름과 같이 우선 sfp에 담겨 있는 값을 조작하여 ebp를 바꾸는 것에서 시작된다.

 

만약 buf의 주소를 leak할 수 있다면, 아래와 같이 sfp에 buf의 주소를 넣어 ebp를 buf로 바꿀 수 있게 된다.

여기서 ret에 leave; ret 가젯을 넣어주면 leave; ret을 한번 더 실행하게 된다.

 

 

아래 그림이 두 번째 leave; ret이 실행될 때의 상황이다.

ret (pop eip; jmp eip)에 의해 esp가 내려간 가장 왼쪽 그림이 두 번째 leave; ret이 실행되기 이전의 스택 상태이다.

mov esp, ebp; pop ebp가 실행되면 위에서 설명한 것과 같이 동작하여 가장 오른쪽과 같은 상태가 된다.

 

esp가 buf+4를 가리키고 있고 여기서 pop eip; jmp eip를 실행하게 된다.

 

 

아래와 같이 buf+4에 system의 주소를 넣고, buf+12에 /bin/sh의 주소를 넣으면 쉘을 딸 수 있다!

 

 

정리를 하면,

ROP를 하고 싶으나, ret까지만 덮을 수 있는 상황에서

buf에 rop를 위한 셋팅을 해둔 뒤에 sfp를 buf-4, ret를 leave; ret 가젯으로 설정하면 된다는 것이다.

(그림에서는 buf+4,                                 buf로 설명)

물론 어느 기법이나 그렇듯 메모리 보호 기법이나 바이너리의 상황에 따라 사용할 수 있을 때에 이용하면 된다. 

'Pwnable' 카테고리의 다른 글

SROP (Sigreturn Oriented Programming  (0) 2020.02.09
Return to dl resolve  (0) 2019.12.28

댓글