- main 함수의 ret값을 갖고 있는 주소
- get_shell() 함수의 주소 값
- 스택에 buf 주소부터 main 함수가 반환하는 값까지 거리
main에서 0x7ffff7c29d90 으로 ret한다.
0x7fffffffdf18이 주소이며 우리는 buf overflow를 이용해 get_shell() 함수의 주소로 이것을 바꾸면 된다.
손 쉽게 구할 수 있다.
scanf 함수에서 2개의 인자를 받는다.
하나는 포맷스트링[%s]과 우리의 입력값.
vararg 은 우리의 입력값이 담기는 buf 주소이다.
0x7fffffffdee0 에서 0x7fffffffdf18 까지 버퍼를 채우고 get_shell() 함수의 주소값을 넣으면 된다.
0x7fffffffdee0 - 0x7fffffffdf18 = -56
스택은 낮은 주소가 위라고 가정할때 아래부터 쌓인다.
그래서 마이너스 값이 나왔다.
우리는 버퍼를 56바이트 채운 뒤에 get_shell() 주소를 삽입할 것이다.
from pwn import *
p = remote('host3.dreamhack.games',12973)
payload = b'A'*0x30 + b'B'*0x8 + p64(0x4006aa)
p.sendlineafter('Input: ', payload)
p.interactive()
A가 차지할 0x30바이트는 버퍼의 크기이다.
근데 이상하다. 문제에는 buf의 크기가 0x28바이트이다.
스택을 보면 rsp와 rbp의 차이가 0x30바이트이다. 즉 48바이트의 스택프레임이 형성되었다. 왜 그럴까?
https://dreamhack.io/forum/qna/1619
stack align = 성능 최적화 이유 때문이라고 한다.
윈도우에서 payload를 실행하려 했으나 p64()가 윈도우에서 바이트 코드로 제대로 변환되지 않아서 오류가 발생한다. 리눅스에서 실행한다.
스택에 대한 전반적인 이해가 있어야 풀 수 있는 문제였다.
함수가 인자를 보낼때 스택에서 어떤 변화가 일어나는지 main 함수의 리턴 값을 어떻게 바꿀 수 있을지.
코드로 쓸때 어떤 오류가 나고 어떻게 코드로 옮길지.
아직 write up을 쓰면서도 헷갈려서 스택에 대한 공부가 더 필요할 것 같다.