图解DWORDSHOOT

在解决protostar heap3之前需要学习一些新的堆溢出的知识,其中之一就是DWORDSHOOT。

1 简介

DWORD SHOOT是发生在一种发生在双向链表删除节点的时会发生的情况。他有可能导致任意地址被改写。

2 unlink原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct node
{
char data[32];
struct node *fd; //指向前一个节点
struct node *bk; //指向前一个节点
};

void unlink (struct node *p) //将节点从双向链表中移出
{

struct node *FD;
struct node *BK;

FD = p->fd;
BK = p->bk;

FD->bk = BK;
BK->fd = FD;
}

正常情况下,unlink函数执行时内存中的数据状态入下图所示:

Image text

在ulink执行中正确的流程如下图所示:

Image text

Image text

Image text

3 DWORDSHOOT原理

​ 在对堆内存溢出后DWORDSHOOT可以修改任意地址内存,在发生攻击时的程序流程如下所示,通过堆溢出可在对一个节点数据修改(或者其他方式)改变内存分配上下面一个节点的fd和bk数据。

Image text

那么在执行FD和BK的初始化的时候发生的事情就会和预想的很不同了。

Image text

所以在最终执行unlink时就会导致预定的地址数据被改写。

Image text

从而成功的改写了进程中free函数,使得调用free函数时实际上是执行了shellcode。当然也可以修改其他在unlink之后会调用的库函数。

4 防止类似问题发生

​ 只需要再unlink之前做出相应检测就可以避免这种bug产生了。

1
2
assert (p->fd && p->fd->bk == p);
assert (p->bk && p->bk->fd == p);
文章目录
  1. 1. 1 简介
  2. 2. 2 unlink原理
  3. 3. 3 DWORDSHOOT原理
  4. 4. 4 防止类似问题发生
,