#有几张图出自hollk师傅的文章,原文链接:https://blog.csdn.net/qq_41202237/article/details/108481889#

堆溢出-unlink

对unlink的利用大概就是对chunk进行内存布局,然后借助unlink中对指针的操作来修改chunk中的指针

unlink的宏定义:

#define unlink(AV, P, BK, FD) {                                            FD = P->fd;                                     BK = P->bk;                                     if (__builtin_expect (FD->bk != P || BK->fd != P, 0))           malloc_printerr (check_action, "corrupted double-linked list", P, AV);  else {                                    FD->bk = BK;                                BK->fd = FD;                                if (!in_smallbin_range (P->size)                     && __builtin_expect (P->fd_nextsize != NULL, 0)) {              if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0)       || __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0))    malloc_printerr (check_action,                     "corrupted double-linked list (not small)",    P, AV);                        if (FD->fd_nextsize == NULL) {                     if (P->fd_nextsize == P)                   FD->fd_nextsize = FD->bk_nextsize = FD;             else {                                  FD->fd_nextsize = P->fd_nextsize;                FD->bk_nextsize = P->bk_nextsize;                P->fd_nextsize->bk_nextsize = FD;                P->bk_nextsize->fd_nextsize = FD;                }                               } else {                                P->fd_nextsize->bk_nextsize = P->bk_nextsize;             P->bk_nextsize->fd_nextsize = P->fd_nextsize;             }                                   }                                   }
}

在以前认识的函数中free()函数在执行时有一个int_free 的过程中调用了unlink,如下:

#define unlink(AV, P, BK, FD)
static void _int_free (mstate av, mchunkptr p, int have_lock)
free(){_int_free(){unlink();}
}

堆释放

设置这样一个堆的创建与释放过程,依次释放first second third_chunk,中间创建的heap1 2 3是为了隔开需要释放的几个chunk,防止他们在free时合并

#include<stdio.h>
void main(){long *heap1 = malloc(0x80);
long *first_chunk = malloc(0x80);
long *heap2 = malloc(0x80);
long *second_chunk = malloc(0x80);
long *heap3 = malloc(0x80);
long *third_chunk = malloc(0x80);
long *heap4 = malloc(0x80);free(first_chunk);
free(second_chunk);
free(third_chunk);return 0;
}

使用命令gcc -g text.c - o test编译生成一个elf文件来进行gdb的动态调试

先在程序的第15行下一个断点 :b 15

然后r运行程序之后输入bin 看一下这几个内存空间被释放到了哪里去:

这里可以看见释放的三个chunk是以链表形式储存在unsorted bin 当中.

unlink的检查过程及操作理解

前面可以看见释放的三个chunk是以链表的方式储存在unsorted bin当中:

这里可以看见三个chunk的 fd 和 bk的相互指向关系,unlink的大概操作就是将second_chunk 从这个链表中取出来,那么如果second_chunk 被取出,剩下的三个chunk就会变成一下这样:

chunk状态检查

仍然是前面的这个test的例子,再次使用gdb来调试一下,看一下second_chunk中的情况;


检查1:检查被释放的chunk相邻高地址的chunk的pre_size是否与size位值相同:

这就是检查被释放chunk的相邻chunk的pre_size是否与这个chunk的size相同,防止chunk的size值被篡改,以及检查这个被释放chunk是否处于空闲状态

检查2:检查被释放chunk的相邻高地址chunk的P位值是否为0:

前面提到过的P位:这是AMP三个字段中最为重要的一个字段,记录前一个chunk是不是malloc的chunk,如果是1,那么就是已经写入用户数据的chunk,如果是0,则是free chunk,在释放内存空间时,如果上一个chunk为free chunk,那么就会将两个chunk合并为一个chunk,size字节就会变大

这里还是检查确认被释放的chunk是否为空闲状态

检查3:检查被释放chunk的前后指针fd 和 bk:

可以看左图红色框中的内容,这里是second_chunk的fd和bk。首先看fd,它指向的位置就是前一个被释放的块first_chunk,这里需要检查的是first_chunk的bk是否指向second_chunk的地址。再看second_chunk的bk,它指向的是后一个被释放的块third_chunk,这里需要检查的是third_chunk的fd是否指向second_chunk的地址

以上三个检查就是对于某个chunk是否处于free状态的三次检查确认,以及三大标准:pre_size,P位,前后指针

例题:[2014 HITCON stkof]

网址:https://github.com/ctf-wiki/ctf-challenges/tree/master/pwn/heap/unlink/2014_hitcon_stkof

保护检查:

除了没开PIE,其他的都开了

这个程序运行起来并没有以前那样的操作提示页面,只有一个一直等待输入的操作

进入ID看一下静态分析

主函数:

__int64 __fastcall main(int a1, char **a2, char **a3)
{int v3; // eaxint v5; // [rsp+Ch] [rbp-74h]char nptr[104]; // [rsp+10h] [rbp-70h] BYREFunsigned __int64 v7; // [rsp+78h] [rbp-8h]v7 = __readfsqword(0x28u);alarm(0x78u);while ( fgets(nptr, 10, stdin) ){v3 = atoi(nptr);if ( v3 == 2 ){v5 = sub_4009E8();goto LABEL_14;}if ( v3 > 2 ){if ( v3 == 3 ){v5 = sub_400B07();goto LABEL_14;}if ( v3 == 4 ){v5 = sub_400BA9();goto LABEL_14;}}else if ( v3 == 1 ){v5 = sub_400936();goto LABEL_14;}v5 = -1;
LABEL_14:if ( v5 )puts("FAIL");elseputs("OK");fflush(stdout);}return 0LL;
}

可以看出这个程序的主体其实就是先让我们输入一个数字存入v3之中,根据v3的值进入不同的函数功能之中(v3可以是1 2 3 4)

下面看一下每个函数是要干什么

sub_4009E8()

__int64 sub_4009E8()
{__int64 result; // raxint i; // eaxunsigned int v2; // [rsp+8h] [rbp-88h]__int64 n; // [rsp+10h] [rbp-80h]char *ptr; // [rsp+18h] [rbp-78h]char s[104]; // [rsp+20h] [rbp-70h] BYREFunsigned __int64 v6; // [rsp+88h] [rbp-8h]v6 = __readfsqword(0x28u);fgets(s, 16, stdin);v2 = atol(s);if ( v2 > 0x100000 )return 0xFFFFFFFFLL;if ( !(&::s)[v2] )return 0xFFFFFFFFLL;fgets(s, 16, stdin);n = atoll(s);ptr = (&::s)[v2];for ( i = fread(ptr, 1uLL, n, stdin); i > 0; i = fread(ptr, 1uLL, n, stdin) ){ptr += i;n -= i;}if ( n )result = 0xFFFFFFFFLL;elseresult = 0LL;return result;
}

这个函数的功能大概是:先从外部接受输入缓冲区的数据,再将输入的数据转换为数值输入给变量v2,然后对v2的值大小进行判定,如果大于了0x100000则结束程序,之后判断*(&:

堆溢出-unlink相关推荐

  1. Linux (x86) Exploit 开发系列教程之九 使用 unlink 的堆溢出

    使用 unlink 的堆溢出 译者:飞龙 原文:Heap overflow using unlink 预备条件: 理解 glibc malloc 这篇文章中,让我们了解如何使用 unlink 技巧成功 ...

  2. 【pwn学习】堆溢出(三)- Unlink和UAF

    前置学习 [pwn学习]堆溢出(一) [pwn学习]堆溢出(二)- First Fit 文章目录 什么是Unlink? Unlink如何利用? 加入错误检查 什么是Use-After-free? 例题 ...

  3. 堆溢出攻击(XP SP2 - 2003)

    微软在堆中也增加了一些安全校验操作,使得原本是不容易的堆溢出变得困难重重: * PEB Random:在 Windows XP SP2 之后,微软不再使用固定的 PEB 基址 0x7FFDF000,而 ...

  4. Linux (x86) Exploit 开发系列教程之十 使用 Malloc Maleficarum 的堆溢出

    使用 Malloc Maleficarum 的堆溢出 译者:飞龙 原文:Heap overflow using Malloc Maleficarum 预备条件: 理解 glibc malloc 从 2 ...

  5. 总结windows下堆溢出的三种利用方式

    创建时间:2004-04-08 文章属性:转载 文章提交:watercloud (watercloud_at_xfocus.org) 原文由Leven发在网络编程版: https://www.xfoc ...

  6. Netgear R6400v2 堆溢出漏洞分析与利用

    2020 年 6 月,ZDI发布了一个关于Netgear R6700型号设备上堆溢出漏洞的安全公告,随后又发布了一篇关于该漏洞的博客,其中对该漏洞进行了详细分析,并给出了完整的漏洞利用代码.该漏洞存在 ...

  7. [pwn]堆:unlink绕过,0CTF2015 freenote详解

    [pwn]堆:2free=unlink绕过,0CTF2015 freenote 题目地址,提取码:f0xd 拿到题目,国际惯例,首先查看安全策略; 没有开启PIE和full partial.然后查看程 ...

  8. 【pwn学习】堆溢出(一)

    文章目录 什么是堆溢出 基本示例 堆分配函数 堆填充长度 堆攻击总结 学习这部分之前,如果对堆的基础还不甚了解可以参考一下下面的学习笔记 Linux堆管理基础知识(一) Linux堆管理基础知识(二) ...

  9. 5.4 堆溢出利用(上)——DWORD SHOOT

    目录 一.预备知识 二.实验环境 三.实验代码 四.实验步骤 一.预备知识 堆管理系统的三类操作:堆块分配.堆块释放和堆快合并归根结底都是对链表的修改.堆溢出利用的精髓就是用精心构造的数据溢出下一个堆 ...

  10. android 9patch 漏洞,Android 9patch 图片解析堆溢出漏洞分析(CVE-2015-1532)

    [前言] 日前谷歌公开了一个今年1月份更新的漏洞.这个漏洞修复了一个存在于Android 5.1版本以下图片渲染的问题,可以查看相关链接. 9patch是Android上特有的一种图片格式,就是在普通 ...

最新文章

  1. pku 1077 Eight
  2. 分割BiSeNet笔记
  3. linux环境下安装mysql 8.0
  4. 【译】 Diving Into The Ethereum VM Part 6 - How Solidity Events Are Implemented
  5. create document history via code
  6. Java迭代器contains的问题
  7. vagrant系列教程(四):vagrant搭建redis与redis的监控程序redis-stat(转)
  8. 《我的成长》6月下2009年第7期(总第7期)
  9. tensorflow 相关的 warning
  10. crontab导致磁盘空间满问题的解决
  11. Linux 修改 Tomcat 编码
  12. OpenGL图形渲染管线(Pipeline)学习
  13. Linux 学习笔记 (一)
  14. 基于VUMAT复合材料夹层结构冲击仿真
  15. Modbus协议中文pdf免费下载地址
  16. npm jdf压缩并上传静态文件到服务器
  17. python实现触摸精灵功能_触摸精灵lua脚本实现微信群加好友功能
  18. EM算法及python实现
  19. Mac IntelliJIDEA非正常关闭解决(reopen失败)
  20. 笔记本电脑散热风扇声音比较大解决方法

热门文章

  1. 一元二次方程的解的程序
  2. response返回中文乱码
  3. linux spec cpu,SPEC CPU2006的安装和使用
  4. windows替换鼠标指针
  5. 英特尔:准备好放弃芯片制造了吗?
  6. 四六级成绩批量查询器
  7. Trojan.Win32.Scar.cjdy分析
  8. macOS如何编辑hosts
  9. drop python_用Python做自己的AirDrop 1 - 环境搭建
  10. URP管线下使用Dither做像素化风格