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 |
댓글0