防止在堆栈溢出代码段中发现最重要的安全漏洞

发布于:2020-12-30 15:01:17

0

620

0

堆栈溢出 代码 安全漏洞

上周,我们告诉您有关一项研究的发现,这些研究在Stack Overflow答案中发现了一些C ++代码片段中的安全漏洞,以及其中的某些漏洞是如何迁移到实际的,实时的Github项目中的。今天,我们跟踪研究中突出显示的前八种错误类型,并提出避免发生相同错误的方法。 

为了获得这些答案,我们检查了通用弱点枚举数据库中Verdi等人在其研究中发布的数字。我们只针对涉及特定弱点而不是类别的CWE编号,因为在开始解决这些弱点之前,它们需要一些更多的信息。 

尽管研究专门在C ++代码段中发现了这些漏洞,但下面提到的CWE可以在多种编程语言中发生。其他编程语言可能更倾向于其他CWE,因此请不要将此作为安全性检查清单。

事不宜迟,如果您遇到问题,哟,我会解决。 

CWE-754 错误检查异常或异常情况

此漏洞的发生是基于以下假设:事件或特定情况不会发生,例如内存不足,无法访问资源。

在给定的程序中,您可能能够控制大多数数据流,因此可以假定所有函数返回值都在期望值之内。但是罕见的事件仍然可能发生。更糟糕的是,有时聪明的攻击者会触发这些事件并给您的系统造成破坏。 

您可以通过假设总是在需要时成功分配内存,文件或字符串具有特定大小,或者数据库或输入调用将返回非NULL的内容来暴露此弱点。在许多情况下,意外数据将使进程崩溃。也许您的代码可以优雅地处理此问题。或者,系统可能会继续处于意外状态,从而使系统容易受到攻击者的欺骗。 

最近,一个以太网/串行RTU模块暴露了这一弱点。尽管该漏洞可能已得到修补,但以前,攻击者可以通过将截断的SNMP数据包发送到特定的UDP端口来发起拒绝服务攻击,或者通过另一个端口上的大量数据包断开连接来断开所有连接。 

某些语言可能能够在造成危害之前捕获这些异常。但是对于没有的低级语言,您可以执行以下操作:

  • 每次检查您的返回值

  • 假设所有输入都是恶意的,并且仅接受某些值

  • 计划低资源条件

  • 失败的建筑师

异常和失败管理并不能解决所有问题。过于冗长和特定的异常会为攻击者提供有关如何在代码中查找其他漏洞的线索。 

CWE-20 输入验证不正确

当软件无法正确验证输入时,攻击者便能够以应用程序其余部分所不希望的形式编写输入。

俗话说“垃圾进,垃圾出”。如果您的输入不正确,则可能会导致某些不良结果。这有点像恶作剧,在那儿您咬咬了您认为是Lindor松露中的一种,但实际上是巧克力包裹的抱子甘蓝。恶意攻击者将试图向您提供一些比抱子甘蓝更糟糕的输入。 

这种弱点与上一个弱点有一个共同点,即开发人员假定没有人可以访问其功能中的输入。错误的开发者名单很 长。 

某些版本的MS Excel(所有版本都已使用10年或以上)允许用户在加载电子表格后在系统上执行任意代码。恶意电子表格中嵌入的各种对象都访问了VBA性能缓存,该缓存在运行时未进行清理,因此其行为异常。 

尤其是在具有数据库驱动的后端的网络应用程序中,软件具有大量矢量,用于不受信任的输入。您可能会认为,每次都可以通过清洁输入来克服此弱点,但是还有很多其他安全措施可采取:

  • 检查客户端和服务器上的输入值

  • 对于来自多个来源的任何输入值组合,请验证组合值以及输入

  • 注意跨语言的代码,例如在本机虚拟机上运行的解释语言中会发生这种情况

  • 明确将您的输入转换为预期的数据类型

  • 验证之前,请确保所有数据都在规范字符编码方案中

  • 使用静态分析

CWE-252 未检查的返回值

方法或函数不检查返回值,这可能会导致意外状态。

您可能现在已经注意到一个主题:在破坏自己之前先检查一下自己。或者,更简单地说,验证所有数据以确保它是您想要的。如果您查看某个函数并认为它永远不会失败,或者认为它是否失败都没有关系,那么您将自己暴露于此漏洞中。 

与以前的弱点类似,此弱点可能会使系统处于意外状态,从而导致崩溃或其他异常,包括执行任意代码。这就是2007年许多Linux实施中发生的情况。攻击者可能将TLV数据包伪造为BGP数据包,从而使他们可以执行所需的操作。这特别危险,因为BGP数据包通常由自治系统传递以共享路由信息。 

缓解这个问题很简单:检查您的返回值,确保它们在预期范围内,如果不是,则抛出异常。 

CWE-477 使用作废功能

该代码使用了不推荐使用或过时的功能,这表明该代码尚未得到积极的审查或维护。

随着漏洞的发现和软件实践的改变,语言和软件可能会过时地淘汰某些功能。尽管您可以继续使用已弃用的功能,但这样做可能会出现安全问题。而且某些函数(例如rand())对于严肃的代码可能已经过时了。 

该弱点可能表明的一个更严重的问题是,有关软件没有得到维护或更新。如果没有人跟上软件和系统的变化,过时的功能可能会持续存在。在未维护的系统中,安全漏洞会随着软件的老化而滚滚滚滚。问题有时会得到新的答案,但是对于多年前发布在Stack Overflow上的代码段,没有人维护(也不应该维护),因此要确保所有内容仍然安全。 

在2018年的NUUO CMS中,过时的软件组件使用户可以随意执行代码。在具有大量依赖关系的复杂软件中,甚至不需要您的代码就具有安全性弱点即可将其暴露于威胁中。 

即使没有实现,缓解此缺陷的方法也很简单:重构代码以避免过时或过时的功能。如果需要使用这些功能,请确保您了解安全隐患并制定相应的计划。 

CWE-789 不受控制的内存分配 

根据无效大小分配内存,从而可以分配任意数量的内存。

内存分配是一个非常常见的功能,尤其是在低级语言中。但是,如果代码分配了大量的内存,则可能导致系统变慢或崩溃。尽管系统故障已足够严重,但在灵活的云系统上,过度分配可能会非常昂贵。 

这是CWE-20(输入验证不正确)的表象,因为需要验证的输入正提供给内存分配功能。内存可能越来越便宜,但仍然有限。如果攻击者可以占用您硬件上的所有内存,则不仅可能使您的程序崩溃,而且可能使该系统上运行的任何其他程序崩溃。 

在2008年,IBM solidDB没有验证设置要分配的内存量的字段。因此,只要在此字段中提供较大的值,任何传入的数据包都可能使系统崩溃。由于solidDB已嵌入许多网络和电信设备中,因此此弱点可能会对Internet的基础结构造成很多破坏。 

缓解这个问题的方法与上面的CWE-20相同,另外还要确保您没有超出系统的内存限制。 

CWE-158 空字节或空字符的不正确中和

输入是从上游组件接收的,但是当空字节发送到下游组件时,它不会中和或错误地中和。

在C ++中,字符串以null字符终止。在大多数情况下,这可以提供很大的灵活性,因为字符串可以是任意长度。但是用户可以输入任意数量的字符作为输入,包括在字符串中间的空字符。在这种情况下,字符串将被截断为该null。 

在大多数情况下,这无关紧要。但是,如果将该字符串作为一个较长的字符串(例如URL或用户名)的一部分进行组合,则他们可能能够使程序放弃超出预期的范围。虽然这个问题是关于PHP的,但是技术是相同的。输入中的空字符可以取消附加到该字符串的所有内容,包括使该文件名成为文件扩展名的文件扩展名。借助一些巧妙的脚本,恶意代理即可遍历Web目录并获取所需的任何文件。 

这是许多早期的Web服务器中发生的情况。攻击者可以在URL末尾添加一个空值并列出目录,读取源代码,并且通常绕过所有访问限制。然后,这些源文件将提供有关可被利用的系统的许多其他信息。 

在尝试捕获这些攻击时,您的代码应假定有人输入的内容为空。这是保护代码的几种方法:

  • 删除输入中的空字符 

  • 使用规范方法显式编码输入

  • 结合使用白名单和黑名单来指定有效值并阻止无效值

CWE-134 使用外部控制的格式字符串

该软件使用的函数接受格式字符串作为参数,但是格式字符串源自外部源。

诸如printf()之类的格式函数采用具有格式函数的String并将其转换为常规String。格式参数看起来像%x,它将处理函数中的参数,并将其添加到返回值中。但是,如果String是由外部控制的(即,作为输入或从文件/数据位置读取),并且未正确验证,则攻击者可能会将自己的参数放入函数中。 

一些参数允许从存储器堆栈或过程存储器读取和写入。允许来自任意用户输入的数据是一个非常糟糕的主意。攻击者可以从内存中读取信息或执行任意代码,具体取决于格式字符串中的内容。 

2006年,Dia(一种基于GTK +的图表工具)在尝试连续打开一个以一堆%s命名的bmp文件时,允许拒绝服务攻击(并可能执行代码)。该软件将尝试显示带有文件名的警告消息,但是由于它正在处理格式参数,因此它显示的是敏感信息。 

解决方案非常简单:确保传递给格式函数的所有Strings都是静态的并且在控件内。有时,编译器警告会指出存在问题的区域,因此请不要忽略它们。 

CWE-476 空指针引用

当应用程序取消引用它期望是有效的但为NULL的指针时,就会发生NULL指针取消引用,这通常会导致崩溃或退出。

当一半的问题是由于空指针异常(或取消引用)而导致的,我仔细阅读了发行说明。尽管许多空指针可能会使系统崩溃或导致程序意外退出,但有时它们会使系统处于意外状态,即奇怪,不可复制的怪癖或从其他内存地址提取数据。当攻击者可靠地找到在系统中诱发空值的途径时,它将成为安全问题。 

尽管许多空指针是由于草率的编程而发生的,但在异步系统中,空指针可能来自竞争条件。这是两个异步进程读取和写入相同变量的地方。这些操作可能会无序发生,因此,当一个进程移动得更快并且在另一个进程有机会对其进行设置之前读取该变量时,繁荣起来!空指针取消引用。 

在2004年,OpenSSL进行了空指针取消引用,这使攻击者可以制定特定的SSL / TLS握手协议,使服务崩溃,从而有效地造成了拒绝服务攻击。 

通过检查从Stack Overflow复制的代码中的这些常见错误,可以避免很多严重的安全风险。分享一些知识,找出一些答案,并在那里保持安全。