缓冲区溢出攻击即破坏指定buff的缓冲区大小,使其溢出到别的空间上去,破坏堆栈。

比如有如下代码:

#include <stdio.h>
#include <string.h>int main(){char buff[15] = {0};int pass = 0;printf("password:");gets(buff);if(strcmp(buff,"hello") == 0){pass = 1;}if(pass == 1){printf("ok\n");}if(pass == 0){printf("no\n");}return 0;
}

看似很简单,实则风险很大,因为上面的代码用了一个函数gets,这个函数是无上限的,它不会检查缓冲区多大,只会等到回车符才会结束输入,也就说我们可以无限输入,它会输入到目标缓冲区里,如果过大,会破坏堆栈空间

其次,判断密码的方式写死了,这样很容易被检测出来

在程序里,所有的字符常量和资源都会被放到程序对应的区中,常量字符放在字符常量区,它与立即数不同,立即数是存在于指令码的高位,用完即没,字符编译器会额外分配地址空间放所有的常量字符。

所以我们可以通过linux下一些命令get到

如:

我们可以使用strings命令获取这个文件的所有字符常量

可以看到全部打印出来了,同时可以看到密码也在里面:

就接着password后面,在破解时,黑客们只需要一点逻辑思考就轻易破解这个程序了,毫无技术可言

如果你的程序是debug编译的附带调试信息,那么可以通过ltrace命令来调出你的库函数使用情况

如:

可以看到依然破解了。

所以非常不安全。

其次,第二个方法,我们可以通过gdb的方式来破解

gdb我用的是gdb-peda,可以参考我这篇文章安装

https://jrhar.blog.csdn.net/article/details/108903157

首先进入gdb调试

然后这里我们可以使用pdiss命令调出main函数,看一下整个程序的执行流程,因为万物main起步

上面就是反汇编出来的代码

注意这一行

 0x0000000000001169 <+4>:     sub    rsp,0x20

这里是在为我们的栈空间分配内存,rsp栈指针。

这里为什么分配0x20个栈呢?我们明明只用了两个变量

char buff[15] = {0};
int pass = 0;

buff是15个字节

pass是int是4个字节总共是19个字节

而0x20=32个字节

也就是说编译器给我们分配32个字节的栈空间

这是因为现在CPU寻址能力的问题,现在cpu最小寻址都在32位宽(4字节),所以你的程序位宽必须按照4字节对齐,你的程序是19个字节,所以编译器为了符合cpu寻址位宽会给你的变量额外分配内存,并填充0,这些额外的内存不属于变量,只是为了保证内存边界宽度符号cpu寻址位宽而已。

32字节是编译器计算出最符合你当前分配内存大小的一个寻址位宽。它必须保证是4字节对齐的,也就是说可以被4整除掉,因为cpu寻址的时候32个总线必须全部用到,不可能只用到16个总线其它的总线闲置不流动电平,这样会让架构变得复杂,在单片机里要尽量不复杂架构代码。

这样cpu不需要关心总线位宽是否符合变量大小之类的,也不需要关心寄存器的大小是否够用,这些是编译器的工作。cpu只负责执行就可以了,这样能最大化的保证性能。

言归正传,我们可以在阅读汇编时可以看到这个指令

这里是加载指令,但是不知道是加载什么,我们这个时候就要猜,去破,后面的#0x2004是相对地址,不是绝对地址,现在只是文件中的,因为还没有被执行,所以反汇编没有给出物理地址,这里我们可以给ret下个断点,然它执行一次,然后让gdb得出绝对地址(因为还没有调用一些初始化的汇编代码,给内存分配堆栈,这个时候程序也不知道自己会在内存的哪个位置,这些代码是由gcc编译器生成的初始化代码,最后才会去调用我们的main函数)

上面是断点到ret这里也就是return这里

然后r起来

ok,这里是成功断点到ret这里了,那么这个时候在反汇编main函数就可以看到绝对地址了

看到地址已经变成绝对地址,这样我们就可以取出这个程序内存中的一些信息了

我们在回顾一下之这个汇编

可以看到这段代码里频繁加载rip寄存器偏移地址的值,我们这个时候不确定是什么,可以先看一下当前的分区状况

先看第一个加载的是0x555555556004这个地址的,它位于第三个分区

这些分区我们此时不太清楚是干什么的,但是可以通过一些权限得知出来,r--p,这是一个可读的分区,那么只能是数据区,它不可写,那么它只能是常量区,注意如果你知道对方的编译器是什么的话其实可以去查一下这个编译器的分区,这样不必像这样去猜

但是我的目的就是在一切都是未知的情况下去教大家如何去破解这个程序。

第二个可以看到x,x代表可执行的就知道它是代码区了

然后可以看到heap堆,然后下面还有mapped这些都是共享区,共享内存会用到这些,还有stack静态区这些

这些先不关心,我们知道它加载常量区的某个字符

我们可以来打印一下看看到底是什么

先打印第一个加载的

可以看到hello ok no等这些字符

这个时候我们就可以去尝试逐个输入看下是否正确

可以看到成功破解.

破解的过程中,就是要不停的去猜,去试,去猜测这个程序的作者的想法

其次通过汇编我们可以看到这里

它有去加载strcmp这个函数,推测就是判断

这里我们推测,然后直接断点到这里

可以看到进行传参时,将比较字符暴漏出来了,反汇编的调用情况就能看到明文密码。

其次,当我们实在无法获取明文时,可以看到还有汇编代码

当调用strcmp成功时,它下面有个jne的汇编指令,由此我们可以判断出,作者调用if语句来判断strcmp函数,同时下面有一个test指令用于设置标志位的,jne,则判断是否相等

当相等的情况下,则会给rbp-0x4这个地址存一个1,同时调用cmp比较一下是否为1

在下面就是输入0,然后jne判断一次,这样的汇编逻辑上基本上可以得知,它设置了一个状态码,我们不知道这个状态码是干什么的,但是我们知道它存在于rbp-0x04这个位置上

在找找汇编代码发现

这里是在给这个堆栈做初始化,它上面的几行汇编代码是在对别的变量初始化,但是看这里,gets这里取了,rbp-0x13的值,所以我们可以猜测这个一定是缓冲区了

在最开始这里就定义了它

我们可以猜测这里可能有一个变量,下面还有一些其它的初始化在0x4与0x13之间,这里需要注意栈是从高往低增长的。

我们这里大概可以猜出它俩是相连的,或者中间隔了几个变量,

这里我们只需要做到能够将它设置为1就可以了,因为它用的是gets这个函数无上限,那么我们可以利用这个方式溢出到别的变量空间里去,这就是缓冲区溢出攻击

首先这个变量在0x13这个起始位置,其次是rbp在0x04这个位置

0x13=19

0x04=4

那么从栈顶减去栈尾=15

所以它的总大小可能会是15,因为我们不知道它中间那些变量是否是堆栈边界保护生成空地址,所以这里我们猜测大小是这么大,如果不是,那么在从0x5开始算,就这样一步一步的去算,去猜测

那么我们猜测,这个标志位跟在pass后面,通过上面的jne代码得知等于1的情况下才会执行成功条件,等于0的情况下则错误,同时strcmp的条件是符合则设置1,不符合设置0

那么我们这次无论如何都强制设置为1,在输入的时候破坏掉缓冲区

注意要保证溢出是1才行,所以这里我们需要打印ascii码为1的字符,也就是”^A“,这个符号是我在ascii码对照表里找到的

在键盘上按下ctrl+a建就能打印出来

这次我们输入16个,超出缓冲区的大小看看能不能溢出到int里

成功破解

注意这种方法有些gcc不行,因为有些gcc开启了堆栈保护,尝试溢出的堆栈都会被终止掉

我们在编译时需要加上这个选项-fno-stack-protector

这样就关闭了堆栈保护,就可以让其溢出攻击了。

Linux开发_反编译开发_破解简单登录程序外加缓冲区溢出攻击相关推荐

  1. java反编译工具_漫话:如何给女朋友解释什么是编译与反编译

    戳蓝字"CSDN云计算"关注我们哦! 来源 | 漫话编程 某天下班后,我在家里进行电话面试,问到面试者这样一个问题:"你知道使用哪些办法可以反编译Java代码吗?&quo ...

  2. java反编译工具_如何保护Java程序 才能防止Java反编译

    简介:Java是一种跨平台的.解释型语言.Java 源代码编译中间"字节码"存储于class文件中.Class文件是一种字节码形式的中间代码,该字节码中包括了很多源代码的信息,例如 ...

  3. ubuntu java反编译,[原创]Ubuntu下简单配置反编译工具以及其开发环境

    0x0:前言 个人电脑重新换了下系统,Ubuntu14.04,刚好需要配置下android的反编译环境,这里简单记录一下,以供有需要的朋友参考. 其实最简单的,只需要apktool就可以了,不过有编码 ...

  4. wxapkg反编译后的数据_反编译微信小程序

    首先声明:本文章仅供学习之用,不可它用. 一.前言 看到人家上线的小程序的效果,纯靠推测,部分效果在绞尽脑汁后能做出大致的实现,但是有些细节,费劲全力都没能做出来.很想一窥源码?查看究竟?看看大厂的前 ...

  5. java反编译微信小程序_反编译微信小程序(最新)

    首先声明:本文章仅供学习之用,不可它用. 一.前言 看到人家上线的小程序的效果,纯靠推测,部分效果在绞尽脑汁后能做出大致的实现,但是有些细节,费劲全力都没能做出来.很想一窥源码?查看究竟?看看大厂的前 ...

  6. java 缓冲区溢出_缓冲区溢出攻击_java教程_缓冲区溢出攻击 漏洞

    主题:[请教] 我想实现缓冲区溢出攻击.就是原程序读取一个字符串.我输入一个特殊的字符串,覆盖 掉原返回地址,使其执行在栈里的代码. 但是当执行到栈里代码时,就会 段错误 而退出. 请问这个是不是现在 ...

  7. Linux下缓冲区溢出攻击的原理及对策

    前言 从逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用.当函数调用发生时,新的堆栈帧被压入堆栈:当函数返回时,相应的堆栈帧从堆栈中弹出.尽管堆栈帧结构的引入为在高级语言中实现 ...

  8. linux缓冲区溢出攻击步骤,如何防范Linux操作系统下缓冲区溢出攻击

    (2)改写"rc.local"文件.默认情况下,当登录Linux系统时系统运行rc.local文件,显示该Linux发行版本的名字.版本号.内核版本和服务器名称等信息,这使得大量系 ...

  9. Linux攻击原理,转:Linux下缓冲区溢出攻击的原理及对策

    前言 从逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用.当函数调用发生时,新的堆栈帧被压入堆栈:当函数返回时,相应的堆栈帧从堆栈中弹出.尽管堆栈帧结构的引入为在高级语言中实现 ...

最新文章

  1. python 空对象模式_Python 单例模式(3种方式)
  2. Java成员方法遵循动态绑定机制
  3. python多线程多进程
  4. Objective-C马路成魔【14-关键C语言功能】
  5. Python 中 with 用法详解
  6. ubuntu 16.04 源码安装samba并且配置
  7. 理论基础 —— 二叉树 —— 顺序存储结构
  8. 新浪sae平台进行数据库的连接
  9. 第 89 章 Hardware
  10. 请教 indy 中的 tldUdpServer 如何实现对本地端口6100进行监听!
  11. EventLoop-浏览器与Node.js--整理
  12. javafx 教程_示例介绍:JavaFX 8打印
  13. 洛谷P8255 解法 2020328
  14. 【机器人学】机器人开源项目KDL源码学习:(5)KDL如何求解几何雅克比矩阵
  15. linux启动/停止/重启MySQL的命令
  16. HTTP/2 协议详解
  17. MYSQL(老杜数据库笔记)
  18. HTML5+CSS3小实例:菜单悬停特效
  19. 五种以上linux的发行版本,Linux 各发行版本简介
  20. inter 实感技术

热门文章

  1. redis哨兵模式原理_Redis哨兵原理,我忍你很久了
  2. python刷今日头条阅读量_教你如何提高今日头条号推荐量阅读量播放量
  3. springboot13 页面国际化(i18n)
  4. 七句话道出做人的底线【精辟】
  5. 计算机软件技术职业工作规划,软件技术职业规划书.docx
  6. python函数调用的例子_Python案例|混用C函数
  7. java 向下转型运行时错误_java多态和向下转型问题。
  8. mysql grant show_【汇总】mysql常用操作【grant,show】
  9. 二级计算机选择题知识点资源,计算机省二级选择题.txt
  10. 直接请求接口_【分享】接口是什么?实现原理的是什么?