栈溢出攻击c语言_软件漏洞分析入门(四)初级栈溢出C_修改程序流程

本文是关于栈溢出攻击的实践教程,通过C语言代码演示如何利用缓冲区溢出修改程序流程,以绕过密码验证。通过OllyDbg调试器分析栈帧,从文件读取字符串以包含特殊ASCII字符,目标是使`verify_password`函数返回时跳转到密码验证通过的代码段。
摘要由CSDN通过智能技术生成

To be the apostrophe which changed “Impossible” into “I'm possible”                                 —— failwest

没有星星的夜里,我用知识吸引你

上节课没有操练滴东西,不少蠢蠢欲动的同学肯定已经坐不住了。悟空,不要猴急,下面的两堂课都是实践课,用来在实践中深入体会上节课中的知识,并且很有趣味性哦

信息安全技术是一个对技术性要求极高的领域,除了扎实的计算机理论基础外、更重要的是优秀的动手实践能力。在我看来,不懂二进制就无从谈起安全技术。

缓冲区溢出的概念我若干年前已经了然于胸,不就是淹个返回地址把 CPU 指到缓冲区的 shellcode 去么。然而当我开始动手实践的时候,才发现实际中的情况远远比原理复杂。

国内近年来对网络安全的重视程度正在逐渐增加,许多高校相继成立了“信息安全学院”或者设立“网络安全专业”。科班出身的学生往往具有扎实的理论基础,他们通晓密码学知识、知道 PKI 体系架构,但要谈到如何真刀实枪的分析病毒样本、如何拿掉 PE 上复杂的保护壳、如何在二进制文件中定位漏洞、如何对软件实施有效的攻击测试……能够做到的人并不多。

虽然每年有大量的网络安全技术人才从高校涌入人力市场,真正能够满足用人单位需求的却聊聊无几。捧着书本去做应急响应和风险评估是滥竽充数的作法,社会需要的是能够为客户切实解决安全风险的技术精英,而不是满腹教条的阔论者。

我所知道的很多资深安全专家都并非科班出身,他们有的学医、有的学文、有的根本没有学历和文凭,但他们却技术精湛,充满自信。

这个行业属于有兴趣、够执着的人,属于为了梦想能够不懈努力的意志坚定者。如果你是这样的人,请跟着我把这个系列的所有实验全部完成,之后你会发现眼中的软件,程序,语言,计算机都与以前看到的有所不同——因为以前使用肉眼来看问题,我会教你用心和调试器以及手指来重新体验它们。

首先简单复习上节课的内容:

高级语言经过编译后,最终函数调用通过为其开辟栈帧来实现

开辟栈帧的动作是编译器加进去的,高级语言程序员不用在意

函数栈帧中首先是函数的局部变量,局部变量后面存放着函数返回地址

当前被调用的子函数返回时,会从它的栈帧底部取出返回地址,并跳转到那个位置(母函数中)继续执行母函数

我们这节课的思路是,让溢出数组的数据跃过 authenticated,一直淹没到返回地址,把这个地址从 main 函数中分支判断的地方直接改到密码验证通过的分支!

这样当 verify_password 函数返回时,就会返回到错误的指令区去执行(密码验证通过的地方)

由于用键盘输入字符的ASCII表示范围有限,很多值如0x11,0x12等符号无法直接用键盘输入,所以我们把用于实验的代码在第二讲的基础上稍加改动,将程序的输入由键盘改为从文件中读取字符串。

#include #define PASSWORD '1234567'

int verify_password (char *password)

{

int authenticated;

char buffer[8];

authenticated=strcmp(password,PASSWORD);

strcpy(buffer,password);//over flowed here!

return authenticated;

}

main()

{

int valid_flag=0;

char password[1024];

FILE * fp;

if(!(fp=fopen('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);

}

程序的基本逻辑和第二讲中的代码大体相同,只是现在将从同目录下的password.txt 文件中读取字符串而不是用键盘输入。我们可以用十六进制的编辑器把我们想写入的但不能直接键入的 ASCII 字符写进这个 password.txt 文件。

用 VC6.0 将上述代码编译链接。我这里使用默认编译选项,BUILD 成 debug 版本。鉴于有些同学反映自己的用的是 VS2003 和 VS2005,我好人做到底,把我 build 出来的 PE 一并在附件中双手奉上——没话说了吧!不许不学,不许学不会,不许说难,不许不做实验!呵呵。

要 PE 的点击左下角阅读原文查看、下载。

在与 PE 文件同目录下建立 password.txt 并写入测试用的密码之后,就可以用OllyDbg 加载调试了。

停~~~啥是OllyDbg,开玩笑,在这里问啥是 Ollydbg 分明是不给看雪老大的面子么!如果没有这个调试器的话,去工具版找吧,帖子附件要挂出个 OD 的话会给被人鄙视的。

在开始动手之前,我们先理理思路,看看要达到实验目的我们都需要做哪些工作。

要摸清楚栈中的状况,如函数地址距离缓冲区的偏移量,到底第几个字节能淹到返回地址等。这虽然可以通过分析代码得到,但我还是推荐从动态调试中获得这些信息。

要得到程序中密码验证通过的指令地址,以便程序直接跳去这个分支执行

要在 password.txt 文件的相应偏移处填上这个地址

这样 verify_password 函数返回后就会直接跳转到验证通过的正确分支去执行了。

首先用 OllyDbg 加载得到的可执行 PE 文件如图:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值