#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;
}
오랜만에 32bit고 거의 모든 보호기법이 없다.
bof을 통해 ret 값을 get_shell로 덮어보자!
코드에서 Size 변수의 크기를 검사하는데 0<= Size <= 255 안에 있으면 된다.
만약 0을 입력하면 read 함수의 세 번째 인자에서 0-1 이 되는데 read 함수 세 번째 인자는 부호가 없는 size_t 형이므로 음수가 전달되면 매우 큰 수로 해석됩니다. 이를 통해 bof가 발생됩니다.
main+128을 참조하면 buf의 위치는 ebp-0x100(256)에 있다.
따라서 260 + get_shell 주소를 채우면 쉘이 실행 될 것이다.
성공!
다른 방법으로 main 코드에 signal(SIGSEGV,get_shell) 코드가 존재하는데, 이 코드는 SIGSEGV(Segmentation Fault)가 일어나면 get_shell 함수가 실행된다는 뜻입니다. 따라서 ret 값으로 get_shell 주소가 아니라 "AAAAA.."와 같은 dummy data를 overwrite하면 Segmentation Faultrk 발생해 get_shell이 실행됩니다.
이 문제를 풀면서 어떤 변수를 정의할 때, 변수를 활용하는 모든 과정에서 변수에 어떤 값이 저장될 수 있는지 이해하고, 자료형을 지정해야된다고 알았다.
'Dreamhack - pwnable' 카테고리의 다른 글
seccomp (0) | 2023.02.13 |
---|---|
cmd_center (0) | 2023.02.03 |
tcache_dup2 (0) | 2023.02.01 |
tcache_dup (0) | 2023.02.01 |
tcache_poison (0) | 2023.01.30 |