首页
论坛
课程
招聘
pwn heap如何构造攻击堆
2018-11-5 23:28 6142

pwn heap如何构造攻击堆

2018-11-5 23:28
6142

本文是对Heap Exploitation原文的学习笔记的第一篇,之后会陆续更新。第一次写,多多包涵。看不懂的地方,可以对比我贴出来的调试详情。

在堆块被释放后,它被插入到一个binlist中。但是,指针在程序中仍然可用。如果攻击者控制了这个指针,攻击者可以在容器中修改链表结构并插入自己的“伪造”块。下面的示例程序展示了如何在fastbin freelist中实现这一点。

原文中的代码有错误

原文的代码

struct forged_chunk {
  size_t prev_size;
  size_t size;
  struct forged_chunk *fd;
  struct forged_chunk *bck;
  char buf[10];               // padding
};

// First grab a fast chunk
a = malloc(10);               

// Create a forged chunk
struct forged_chunk chunk;    
chunk.size = 0x20;            
data = (char *)&chunk.fd;     // Data starts here for an allocated chunk
strcpy(data, "attacker's data");

// Put the fast chunk back into fastbin
free(a);
// Modify 'fd' pointer of 'a' to point to our forged chunk
*((unsigned long long *)a) = (unsigned long long)&chunk;
// Remove 'a' from HEAD of fastbin
// Our forged chunk will now be at the HEAD of fastbin
malloc(10);                  

victim = malloc(10);          
printf("%s\n", victim);       // Prints "attacker's data" !!

修改后的代码

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
struct forged_chunk {
  size_t prev_size;
  size_t size;
  struct forged_chunk *fd;
  struct forged_chunk *bck;
  char buf[10];               // padding
};
unsigned long long *a,*victim;
//struct forged_chunk *victim;
//
char *data;

// First grab a fast chunk
a = malloc(10);               
// Create a forged chunk
struct forged_chunk chunk;    
chunk.size = 0x20;           
data = &chunk.fd;     // Data starts here for an allocated chunk
strcpy(data, "attacker's data");

// Put the fast chunk back into fastbin
free(a);
// Modify 'fd' pointer of 'a' to point to our forged chunk
*((unsigned long long *)a) = ((unsigned long long)&chunk-0x10);//此处与原文不同
// Remove 'a' from HEAD of fastbin
// Our forged chunk will now be at the HEAD of fastbin
malloc(10);                   // Will return 0x219c010
victim = malloc(10);// Points to 0x7ffc6de966a0
printf("%s\n",*victim);//此处与原文不同,Prints "attacker's data" !!
//printf("%s\n",attack);
return 0;
}

伪造块的大小参数设置为0x20,以便通过安全检查“malloc():内存损坏(快速)”。这个检查检查块的大小是否在特定fastbin的范围内。另外,请注意,分配块的数据是从'fd'指针开始的。这一点在上面的程序中也很明显,而我们另a指向chunk时指向的是fd向上0x10 (0x8+0x8)字节位置,要减去这个偏移,在原文中没有减去。

攻击过程

1.'a'freed
head->a->tail
2.a->fd被指向'forged chunk'
head->a->forged_chunk->undefined(forged_chunk->fd实际上会指向attacker的数据)
3.‘malloc’reguest
head->forged_chunk->undefined
4.'malloc'reguest by victim
head->undefined

调试过程

" href="#1 ">1

设置断点,开始调试。
程序运行到第一个malloc,给a分配堆。

继续运行,从stack中可以看出a地址为0x7ffffffdc98,指向地址为0x555555756260的堆。代码继续运行。

struct forged_chunk chunk;   
chunk.size = 0x20;


有汇编指令可以看出chunk.size的地址。查看地址内的数据是否如我们所想已改为0x20

data = (char *)&chunk.fd;      
strcpy(data, "attacker's data");

执行完这两句代码后可以得到chunk的fd指针地址,也就是后来我们利用的地址。这次我们向该地址写入一个字符串地址。

free(a)

对应过程head -> a -> tail

*((unsigned long long *)a) = ((unsigned long long)&chunk-0x10);

对应过程head -> a -> forged chunk -> undefined (fd of forged chunk will in fact be holding attacker's data)

可以看出a指向0x555555756260,也就是说虽然free(a),但实际上程序中a还是一样可以使用的。这条代码实际上是将chunk.fd的地址放到了0x555555756260。这里为啥要减去0x10,请看这个图。chunk的地址是图中的men所指的地方,与fd有0x10的偏移。(https://bbs.pediy.com/thread-224836.htm,从这盗的图)。


malloc(10);

对应head -> forged chunk -> undefined

victim = malloc(10);

对应head -> undefined [ forged chunk is returned to the victim ]。通过这次操作victim指向了chunk.fd

victim->chunk.fd->data->"字符串"

printf("%s\n", * victim);//代码取victim保存的地址中的值作为字符串地址传给printf.


[培训]12月3日2020京麒网络安全大会《物联网安全攻防实战》训练营,正在火热报名中!地点:北京 · 新云南皇冠假日酒店

收藏
点赞0
打赏
分享
最新回复 (9)
雪    币: 202
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
闫白告 活跃值 2018-11-5 23:31
2
0
优秀,学习到了
雪    币: 202
活跃值: 活跃值 (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Mr.Lee_391780 活跃值 2018-11-5 23:49
3
0
雪    币: 355
能力值: ( LV1,RANK:30 )
在线值:
发帖
回帖
粉丝
Victorgg 活跃值 2018-11-6 15:15
4
0
感谢楼主,学习了
雪    币: 202
活跃值: 活跃值 (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Mr.Lee_391780 活跃值 2018-11-6 16:19
5
0
我也是刚开始学习,一起交流。
雪    币: 202
活跃值: 活跃值 (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Mr.Lee_391780 活跃值 2018-11-6 16:19
6
0
Victorgg [em_63]感谢楼主,学习了
我也是刚开始学习,一起交流。
雪    币: 221
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
孙小媛 活跃值 2018-11-6 21:34
7
0
优秀!!希望楼主能够再出相关的帖子
雪    币: 202
活跃值: 活跃值 (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Mr.Lee_391780 活跃值 2018-11-6 21:37
8
0
孙小媛 [em_63][em_63]优秀!!希望楼主能够再出相关的帖子
是是是
雪    币: 199
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
callmexxaqer 活跃值 2018-11-13 17:15
9
0
没有细看,但是感觉你写错了。
a对应的是chunk的mem区;但是chunk-0x10,对应的是pre-chunk了。
要修改的话,应该是a = (long)&chunk + 0x10   这样才是让a指向了chunk的mem
雪    币: 202
活跃值: 活跃值 (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Mr.Lee_391780 活跃值 2018-11-14 22:20
10
0
callmexxaqer 没有细看,但是感觉你写错了。 a对应的是chunk的mem区;但是chunk-0x10,对应的是pre-chunk了。 要修改的话,应该是a = (long)&chunk + 0x10 ...
这里chunk是自己声明的一个模拟chunk结构的结构体变量。chunk的地址是从结构体的开始地址也就是pre_size开始的。然后,chunk是个栈模拟的堆啊,所以是减个0x10,在实际的堆中是加上个0x10.
游客
登录 | 注册 方可回帖
返回