安全软件设计-第2部分

这篇文章侧重于软件安全性,涵盖了设计安全软件时要牢记的几个漏洞和缺陷。 具有设计缺陷和实现错误的系统为攻击者提供了切入点,这些攻击者希望破坏公司或从用户那里窃取。 这就是软件安全性源泉-它着重于从编码级别进行软件的安全设计和实现。 错误是软件的必然组成部分,对于大多数用户而言,带来的不便只是很小的一部分。 但是,恶意行为者会主动寻找错误并加以利用以造成危害。 一个安全的系统必须通过减少错误或使它们更难以利用和保护系统的机密性,完整性和可用性来防止不良行为。

CWE和CVE

常见弱点枚举(CWE)和常见漏洞与暴露(CVE)是MITER的数据库,提供信息安全社区遵循的标准。 这些有助于消除开发人员,设计人员和架构师在软件中犯下的最常见错误,并导致更安全的软件。
CVE提供了在特定软件版本中发现的漏洞的数据库,并根据严重性对漏洞进行评分,而CWE记录了潜在的漏洞本身(可能导致漏洞),与任何软件版本无关。


这是涵盖信息安全主题的系列文章的一部分:

  1. 信息安全导论
  2. 云中的安全性
  3. 移动安全挑战
  4. 安全软件设计-第1部分
  5. 安全软件设计-第2部分(本文)

低级别漏洞

这些主要违反了诸如C和C ++之类的编程语言中的内存安全性,在这些语言中可以直接访问和修改内存。 它们包括缓冲区溢出(在堆栈和堆上)漏洞,整数溢出,格式字符串不匹配以及指针悬空。 在这里,指针正在访问它不应该访问的内存。

阅读有关堆栈粉碎的更多信息,并用这张真棒纸尝试一下-粉碎堆栈以获得乐趣和利润

进攻
它们利用上述漏洞使程序崩溃或执行恶意的任意代码。

  • 堆栈粉碎-攻击者使用输入使缓冲区溢出,以填充堆栈中的所有局部变量空间,并访问禁止的内存区域以使程序崩溃或执行恶意代码。
  • 返回libc攻击—如果堆栈不可执行(请参见下面的防御中的更多内容),则可以将堆栈中的返回地址更改为地址空间中已经存在的库函数的位置。
  • 格式字符串攻击-如果未正确验证输入,则可以插入精心设计的恶意代码,并且可以在堆栈上执行任意命令。
  • 陈旧的内存访问-悬空的指针指向已释放的内存。 如果现在正在其他地方使用内存,则通过悬空指针覆盖内存位置可能会导致系统崩溃。
  • 面向返回的编程(ROP)-通过溢出缓冲区,可以将精心设计的代码插入堆栈。 该代码通常包含一个NOP底座(由CPU执行的一系列空操作),直到到达堆栈帧的返回地址为止。 现在,返回地址指向攻击者提供的位置,CPU跳至该位置并执行恶意代码。

防御

  • 地址空间布局随机化(ASLR)-ASLR随机排列堆栈,堆和库的地址位置,从而防止攻击者可靠地跳转到内存中的被利用功能。
  • 不可执行的数据-使堆栈和堆数据段不可执行,以使攻击者无法执行堆栈中的代码。
  • 堆栈金丝雀—通过在局部变量和已保存的称为金丝雀的基本指针之间放置一个特殊的数字,可以防止堆栈崩溃和ROP。 然后,程序会在从函数返回之前检查此数字是否已更改。 如果攻击者重写了寄信人地址,那么金丝雀也会被修改。
  • 内存安全性实施—一种编译时转换,用于强制执行C的完整空间安全性。
    在此处了解更多信息。
  • 使用诸如Java之类的内存安全语言-不允许直接访问内存,也不会受到这些漏洞的影响。

有关缓冲区溢出的更多信息

缓冲区溢出漏洞是最广泛的漏洞之一,并且几乎被Internet上的每种蠕虫所利用,从1988年的Morris Internet Worm蠕虫到最近的WannaCry勒索软件攻击(2017年5月)。攻击者提供了一个过大的输入来填充缓冲区并在缓冲区之后写入内存空间。 精心设计的输入可能导致执行恶意代码或至少使程序崩溃。

为了发起缓冲区溢出攻击,攻击者需要做两件事:

  1. 识别应用程序中的缓冲区溢出漏洞
    –检查程序的源代码
    –使用超大输入(使用调试器,例如C程序的gdb)跟踪程序的执行情况
    –模糊测试等工具
  2. 该漏洞需要由外部数据或输入字符串触发
    –程序使用了不安全的例程,例如gets,strcat,strcpy,sprintf等,在该例程中,程序不检查复制到缓冲区中的输入长度。 如果检查了长度(例如,在str n cpy,str n cat中 ),则输入将被截断并且缓冲区不会溢出。

要自己尝试,请遵循此演示!

注意:本文是参考Prasad Honnavalli先生在“信息安全”讲座中使用的幻灯片以及各种在线资源发布的