问题描述
在我们关于安全性的首次CS讲座之一中,我们无法检查所谓的缓冲长度,以及一些可以利用这种漏洞的方式的示例.
在这种情况下,看起来这是一种恶意读取操作的情况,该应用程序只是读出的,但是许多字节的内存
-
我是否正确地断言" Heartble Bug"是C缓冲区长度检查问题的表现吗?
-
为什么恶意使用尝试读取另一个应用程序的内存时会导致分割错误?
-
在写入记忆之前(然后从中读取)会导致分割故障吗?还是在操作系统之间有所不同?还是在其他一些环境因素之间?
-
显然无法识别该错误的利用.那是因为心跳功能在调用时不会登录?否则,肯定有任何对〜64K字符串的请求可能是恶意的?
推荐答案
我是否正确地断言" Heartbleed Bug"是C缓冲区长度检查问题的表现吗?
是.
Heartbleed错误是C?
中经典缓冲区溢出的表现.
否. "经典"缓冲区溢出是您 Write 在堆栈分配的缓冲区中更多的数据,该数据比敌对代理提供的数据提供的数据所能保留.敌对数据溢出缓冲区并覆盖当前方法的返回地址.当方法结束时,它将返回到包含攻击者选择的代码并开始执行的地址.
相反的Heartbleed缺陷不会 oftrite 一个缓冲区,并且不会执行 ecepute 任意代码,它只是读取 out code in code of code在内存中很可能在附近具有敏感数据.
为什么恶意使用尝试读取另一个应用程序的内存时会导致分割错误?
它没有尝试读取另一个应用程序的内存.利用读取当前过程的内存,而不是另一个过程.
为什么恶意使用试图从缓冲区的范围读取内存时会导致分割故障?
这是这个问题的重复:
分割故障意味着您触摸了操作系统内存管理器尚未分配给您的页面.这里的错误是,您在有效页面上触摸了数据,该数据没有分配给您.只要页面有效,您就不会得到segfault.通常,堆经理会向操作系统索要大量记忆,然后将其分配给不同的分配.就操作系统而言,所有这些分配都在内存的有效页面上.
删除null是一个segfault,仅仅是因为操作系统从未使包含零指针的页面成为有效页面.
更一般地:编译器和运行时不需要确保未定义的行为导致segfault; UB可以导致任何行为,其中包括什么都不做.有关此事的更多想法,请参见:
对于我两个人都抱怨ub 应该始终等同于安全 - 关键代码中的segfault,以及一些指示,以讨论有关漏洞的静态分析的讨论,请参见今天的博客文章:
http://ericlippert.com/2014/04/04/15/Heartbleed and静态分析/
在写入记忆之前(然后从中读取)会导致分割故障吗?
不太可能.如果读取范围不会导致segfault,那么从范围中写出不太可能. 可能的是只读内存的页面,但是在这种情况下,它似乎不太可能.
当然,后来的将各种内存归零的后果,您不应该是整个节目中的seg故障.如果您以后退出中有一个指针,那就是将null产生segfault.
.这之间的操作系统之间会有所不同吗?
这个问题很模糊.让我重新提示它.
是否有不同的操作系统和不同的C/C ++运行时库为分配虚拟内存,分配堆内存以及识别内存访问何时范围提供不同的策略?
是; 不同的事物是不同的.
或在其他某些环境因素之间?
例如?
显然无法识别该错误的利用.那是因为心跳功能在调用时不会登录?
正确.
肯定有任何对〜64K字符串的请求可能是恶意的?
我没有跟随您的思路.是什么使请求可能是恶意的是发送的字节和要求回声的字节之间的不匹配,而不是被要求回声的数据大小.
其他推荐答案
没有发生分割故障,因为访问的数据是紧邻所请求的数据的数据,并且通常位于同一过程的存储器内.我想如果请求足够大,可能会导致例外,但是这样做不符合利用者的利益,因为崩溃的过程会阻止他们获得数据.
为了明确的解释,此 xkcd 漫画很难更好: