计算机系统基础笔记(6)——高级话题

前言

今天介绍的是内存分布和缓冲区溢出,内容有点少耶^^

内存分布

一、内存布局(X86-64/Linux 程序)

如图
在这里插入图片描述

  • (stack):运行时栈(默认:分配8MB的限制),一般存储局部变量
  • (heap):根据需要动态分配,当调用 malloc()、calloc()和new()时申请
  • 数据(data):静态分配的数据,例如:全局变量、静态变量、字符串常量
  • 代码(Text):储存函数,只读不写
  • 共享空间:处于堆与栈之间 储存标准库
  • 内存最顶部还有一部分空间 用于储存Linux的内核代码,当代码运行错误时会通过运行该部分代码解决运行错误

下面是例子
这是一个C代码
在这里插入图片描述
这是运行时为它分配的内存空间 局部变量分配在栈中 全局变量分配在数据中 函数分配在代码中 指针(动态分配)在堆中
在这里插入图片描述

缓冲区溢出

一、蠕虫和病毒

很生动的名字 学过高中生物的应该都知道 这个特征很符合它的生物学特征^^

  • 蠕虫:一个程序
    • 可以独立运行, 可以将其完整的工作版本传播到其他计算机
  • 病毒:一个程序片段
    • 注入到其他的程序中 不能够独立运行

二、计算机的漏洞

  • 1988年11月 ,互联网蠕虫攻击了成
    千上万的互联网主机
  • 2014年4月 心脏滴血漏洞(数据加密协议(HTTPS)的漏洞)
  • 2017年4月 勒索蠕虫

三、即时通讯软件战争

  • 1999年7月 微软公司推出了MSN Messenger(即时通
    讯软件)
    MSN客户端可以直接访问当时流行的AOL
    公司的即时通讯软件(AIM)的服务器
    如图在这里插入图片描述
  • 1999年8月,奇怪的是,Messenger客户端无法再访问,微软和AOL开始了即时通讯软件战争:AOL修改了服务器程序以拒绝MSN客户端的接入,微软对MSN做出修改以应对AOL,如此这般,交手了至少13个回合
  • AOL公司攻击了AIM客户端中的缓冲区溢出漏洞
    • 攻击代码:向服务器发送4个字节的签名信息(这些字节位于AIM客户端的某个位置)
    • 当微软实现了对这个签名的匹配后,AOL修改了签名的位置(生成了新的签名)
  • 一封未知来源的电子邮件结束了这场战争, 随后发现这份邮件来自于微软内部在这里插入图片描述

四、缓冲区溢出

1.简介

  • 缓冲区溢出指对一个数组的访问超出的其内存分配的区域时
  • 问题严重的理由:
    • 它是安全漏洞产生的头号技术原因
    • 这个头号原因主要是由于社会上的工程师/用户的无知造成的

2.常见形式

  • 没有对输入字符串的长度进行
    检查
  • 特别是栈上面的字符数组,有时被称为栈破坏

3.不推荐使用的函数

  • gets 对读入的字符数量没有做具体的限制
    它的实现如图在这里插入图片描述
  • strcpy, strcat : 会进行任意长度的字符串赋值
  • scanf, fscanf, sscanf : 会使用 %s 转换模式

五、缓冲区相关的代码漏洞(重点)

1.例子

如图是一个C代码 下面是他的输入输出
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们可以看到第一个输入虽然超过了数组分配的空间但是正常输出了 而第二个输入则出现了段错误 这是由于在栈中给该函数分配了二十四个字节的空间导致的

2.漏洞分析

下面是分析

  • 这是它的汇编代码
    在这里插入图片描述
    在这里插入图片描述
    第一行(sub 0x18 也就是减去24 十进制)可以看到rsp栈顶指针下移了二十四个字节(分配给缓冲区的只有四个字节)

  • 下面我们再来仔细看看这个缓冲区的栈结构

灰色的空间是调用echo前的,存储了返回地址 便于返回到call_echo函数调用指令的下一条代码

下面为buf数组分配了四个字节的空间,栈内还有二十个字节的未利用空间
在这里插入图片描述

  • 情况1:


所以缓冲区溢出,但是没有破坏栈的结构
在这里插入图片描述

  • 情况2
    在这里插入图片描述
    可见影响到返回地址的部分了

返回到一段无关的代码区域,发生了很多事,但是没有改变关键状态,最后执行retq返回到main函数
(关键状态就是能否返回到main函数 这个返回地址是返回到call_echo函数的,所以不影响)

六、代码注入攻击

  • 输入的字符串中包含着可执行的字节编码
  • 将返回地址A覆盖为缓冲区的地址B
  • 当过程 Q 执行 ret 指令,将会跳转到攻击代码
    如图
    在这里插入图片描述

七、对抗缓冲区溢出攻击

1. 避免溢出漏洞的出现

重点在实操啊各位 要注意自己代码的安全性

  • 使用限制字符串长度的标准库函数(明确几个字符)
    • 使用 fgets 代替 gets
    • 使用 strncpy 代替 strcpy
    • 不使用 scanf 的 %s 转换模式获取字符串
      • 使用 fgets 读取字符串
      • 或者使用 %ns,n 选择一个合适的整数

2.系统级的保护机制

  • 栈随机化
    • 在程序的开头,分配一个随机大小的栈空间,这会移动整个程序的栈地址,使得“黑客”很难预测注入代码的准确位置
    • 每一次运行,栈的位置都不一样
      如图

在这里插入图片描述

  • 不可执行段 (限制可执行代码的区域)
    • x86-64增加了显示的“可执行”权限
    • 把栈标识为“不可执行”
      如图在这里插入图片描述

3.栈“金丝雀”

  • 在栈中,缓冲区的后面紧接着放置一个特殊值(“金丝雀”),在函数返回前,检查这个值是否被破坏

小知识:“金丝雀”源于历史上用这种鸟
在煤矿中感知有毒气体

  • GCC 实现: 编译选项: -fstack-protector( 现在这个选项是默认的(早期版本这个选项的关闭的))
    下面是汇编的实现

在这里插入图片描述

PS

后面对抗这部分我下个星期上完课会补充完的,那么我们下期再见^^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值