专栏首页Ms08067安全实验室栈溢出入门系列-临近变量淹没

栈溢出入门系列-临近变量淹没

本文作者:rkvir(Ms08067实验室合伙人&二进制小组组长) 人才招募:二进制小组寻找二进制领域志同道合的朋友

一. 实验环境:

操作系统

Windows XP SP3

开发环境

VC++ 6.0

调试器

Ollydbg

二. 实验代码:

#include <stdio.h>#include<string.h> #define PASSWORD "1234567" int verify_password (char *password){int authenticated;char buffer[8];authenticated=strcmp(password,PASSWORD);strcpy(buffer,password);return authenticated;} main(){int valid_flag=0;char password[1024];while(1){printf("please input password: ");scanf("%s",password);valid_flag = verify_password(password);if(valid_flag){printf("incorrect password!\n\n");}else{printf("Congratulation! You have passed the verification!\n");break;}}}

三. 溢出原理

程序未对输入的密码进行长度检测,接收密码的缓冲区只有8,而输入的密码最长可以输入1024。判断密码是否正确的变量authenticated存储在栈中,当输入的密码长度大于8时,输入的字符串将冲破缓冲区,淹没authenticated所处的位置。当密码错误时authenticated的值是1,正确的时候authenticated的值是0.这就意味着我们可以构造一个合适的输入字符串来改变判断结果。

四. 实战调试

我们的重点不是逆向工程,而是漏洞分析,故此不再详诉诸如寻找main函数等逆向知识。

1. 在jmp mai下断点,方便后续反复调试

2. 单步步入main函数分析程序

3. 分析main函数逻辑,可以看出主要问题出在密码比对函数00401005

3.1 输出引导字符串后,要求用户输入密码。

3.2 通过00401005处的函数进行密码比对

3.3 判断比对结果是不是0,如果是0则输出成功字符串,如果是1则输出失败字符串。

4. 单步执行程序,随便输入一个密码,然后单步步入00401005函数,分析这个函数的内容。

4.1 可以看出这个00401005是个跳转,直接单步进入函数真实位置。

4.2 进入到函数内部后可以看到真正的密码是1234567,如果我们是在逆向破解这个程序,那么到了这一步,就已经算是成功了。但是我们的目的是分析漏洞,所以我们现在进一步分析这个函数。

4.2.1 可以看出,在strcmp之后,ebp-4的位置上就有了密码比对的结果

4.2.1.1 strcmp比对密码,将比对结果存入ebp-4的位置上

4.2.1.2 栈中的密码比对结果

4.2.2 如果是正常的程序,这个时候就应该返回了,但是因为是实验代码,所以下面还有一个strcpy的拷贝函数,将输入的密码字符串拷贝入一个长度为8的缓冲区中。

4.2.3 当执行完strcpy的时候我们看一下堆栈区,可以看到字符串缓冲区的位置就在密码字符串比对结果旁边,并且strcpy没有对拷贝入的字符串进行长度判断。因此我们可以判断,我们在构造一个合适的字符串传入的情况下,是可以覆盖密码字符串比对结果的。这也意味着我们可以传入一个合适的字符串来冲破密码验证。

5. 我们重新加载这个程序,并且传入一个特定的字符串“qqqqqqqq”

6. 运行到密码比对函数进行分析

6.1 可以看出strcmp函数没有任何问题的执行成功并且返回了1,代表密码错误。并且把存储在eax中的返回值存储到ebp-4的位置上。

6.1.1 函数执行

6.1.2 返回值存储在eax中

6.1.3 eax中的值mov到了ebp-4的位置上

6.2 下面到了引起溢出错误的strcpy函数,详细分析该函数溢出的过程。

6.2.1首先记录一下strcpy没有执行前堆栈的情况

6.2.2 执行strcpy函数

6.2.3 可以看到,堆栈中原本保存着密码比对结果的位置ebp-4,由于传入字符串超长,已经被覆盖成了0。这样一来,原本比对失败的结果就变成了比对成功。

7. 运行至返回,成功输出密码比对成功的信息

7.1 控制台成功信息

8. 那么是任何长于1234567的字符串都可以成功覆盖比对结果吗,尝试一下,输入9个q,可以看到,对比结果的位置上并没有被覆盖成00,而是71,而只有对比结果等于0才可以成功验证。这说明不是任意长度字符串都可以。

9. 那么有什么结果可以覆盖成整好是0呢,那么答案是长度为8的字符串,长度为8的字符串实际长度为9,因为还有用来标记字符串结束的00,我们就是要使用结尾处的00来覆盖对比结果,使其数值为0。

来源:Ms08067安全实验室

本文分享自微信公众号 - Ms08067安全实验室(Ms08067_com),作者:徐哥

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一种有趣的帐户接管手段

    关于获取他人帐户的控制权,我曾在网上学习了不少前辈的经验和技巧,而在花费了6到8个小时后,我在目标站redacted.com的忘记密码页面中找到了一些可利用的痕...

    徐焱
  • 远控免杀专题(13)-zirikatu免杀(VT免杀率39/71)

    声明:文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担!

    徐焱
  • 记一次面试题getshell

    网站首页如下,通过路径得知使用的使用的eShop程序搭建,通过faction.ico图标得知中间件是Apache Tomcat,使用的脚本应该是jsp。

    徐焱
  • .Net WebApi 初探

    实现服务层与api层共用,也就表明Service层就是api层。 关键类和接口 System.Web.Http.Dispatcher.DefaultHttpC...

    sam dragon
  • 坐标判断

    /* 功能:坐标判断 日期:2013-05-08 */ #include <stdio.h> #include <stdlib.h> #incl...

    汐楓
  • Photoshop保存ICO格式插件 ICOFormat.8bi

    Photoshop 一直不支持导入导出ico格式图标文件,不过还好有一款插件可以让photoshop支持打开和保存 ico 图标格式,这款插件就是 ICOFor...

    德顺
  • 命令模式

    命令模式定义 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。 作用 命令模式主要应用于将行...

    xiangzhihong
  • 我被面试官给虐懵了,竟然是因为我不懂Spring中的@Configuration

    现在大部分的Spring项目都采用了基于注解的配置,采用了@Configuration 替换标签的做法。一行简单的注解就可以解决很多事情。但是,其实每一个注解背...

    格姗知识圈
  • 原创 | 我被面试官给虐懵了,竟然是因为我不懂Spring中的@Configuration

    现在大部分的Spring项目都采用了基于注解的配置,采用了@Configuration 替换标签的做法。一行简单的注解就可以解决很多事情。但是,其实每一个注解背...

    cxuan
  • C#:DataTable映射成Model

    这是数据库开发中经常遇到的问题,当然,这可以用现成的ORM框架来解决,但有些时候,如果DataSet/DataTable是第三方接口返回的,ORM就不方便了,还...

    菩提树下的杨过

扫码关注云+社区

领取腾讯云代金券