零日(0天)漏洞是在开发过程中引入的,尚未被开发人员发现的计算机软件漏洞。 黑客可以利用零日漏洞,从而影响公司声誉。 开发人员应设法减少导致此类漏洞的缺陷数量。 PVS-Studio是用于C,C ++,C#和Java代码的静态代码分析器,是能够检测安全问题的工具之一。
零日漏洞
零日漏洞 (也称为
0天漏洞)是一种计算机软件漏洞,对于那些有兴趣缓解该漏洞(包括目标软件的供应商)的人来说是未知的或无法解决的。 在缓解漏洞之前,黑客可以利用它对计算机程序,数据,其他计算机或网络产生不利影响。 该术语表示开发人员没有一天可以修复该缺陷,因为尚无人知道。 在过去,某些知名供应商和软件产品(如
Adobe ,
Windows ,
Tor浏览器等)受到零日漏洞的影响。
有些人很幸运能找到不想要利用此漏洞的人并予以报告。
MacOS就是这样的一个例子。 在另一些情况下,开发人员自己制作了一个补丁,使用该补丁,在添加新功能的同时,还修复了零日漏洞,却不知道该漏洞。
其他人则不那么幸运。 例如,不久前,谷歌浏览器不得不紧急修复一个
漏洞 ,可以利用该
漏洞远程执行任意代码。
问题是您无法保证100%抵御这些漏洞,因为您无法有效抵抗甚至不知道的威胁。 但是,有一些方法可以减少此类缺陷在您的程序中的发生-这将是本文的主题,但是我们应该首先了解一些理论。
静态分析
静态分析是一种使用分析器检查软件程序源代码而不执行程序本身的方法,可以看作是自动代码审查。 有时,静态分析可能比对等代码检查更为有效,但不能完全取代它。 我试图在下表中总结代码审查和静态分析相对于彼此的优缺点:
CVE和CWE
常见漏洞和披露(CVE)是一个信息安全漏洞和披露的数据库。 其最初目的是将已知的软件缺陷组织到一个统一的列表中。 过去,大多数信息安全工具都使用自己的数据库和此类缺陷的名称,这是为了解决这种混乱,并建立MITER Corporation在1999年开发CVE的不同工具之间的兼容性。不足以估计代码安全性。 还需要其他一些系统,具有更好的分类和更详细的描述。 这就是常见弱点枚举(CWE)诞生的方式。 如果CWE中列出了缺陷,则可能导致可利用的漏洞,并且也被添加到CVE列表中。 下面的欧拉图显示了标准之间的关系。
某些静态分析器可以通知您,例如,您的项目是否使用了包含漏洞的库。 知道了这一点,您可以下载已修复缺陷的库的更新版本,以使您的代码不太容易受到他人代码错误引起的安全威胁的影响。
随着CVE和CWE标准被开发人员社区所接受,它们也得到了包括静态分析器在内的许多信息安全工具的支持。 支持这些分类的分析仪可以视为SAST解决方案。 SAST(静态应用程序安全性测试)允许开发人员在软件开发生命周期的最早阶段检测程序源代码中的漏洞。
SAST是另一种实践,可以最大程度地减少项目中发生零日漏洞的可能性。 支持CWE标准的分析器可以告诉您潜在漏洞在哪里潜伏,以便您可以对其进行修复,以使您的应用程序更可靠,更不可能包含0天威胁。
有各种各样的SAST工具。 我将以
PVS-Studio分析仪为例,以说明这些工具如何帮助对抗漏洞。 该分析仪的警告被归类为CWE。 下面给出一些示例。
PVS-Studio诊断消息:
CWE-561 :
无效代码(
V3021 )。
public string EncodeImage(....) { if (string.IsNullOrWhiteSpace(inputPath)) { throw new ArgumentNullException("inputPath"); } if (string.IsNullOrWhiteSpace(inputPath)) { throw new ArgumentNullException("outputPath"); } .... }
这段代码包含一个错字:两个
if语句的条件都检查同一个变量。 伴随异常的消息表明第二种情况应改为检查
outputPath变量。 此错误使代码的某些部分无法访问。
这样的错误似乎无害,但这种印象是错误的。 让我们看一下另一个与重复的
goto语句有关的琐碎且看似无害的错误。
此错误曾经导致iOS中的漏洞。
CVE-2014-1266漏洞:Apple TV 6.x之前的6.1.6版和7.0.6之前的7.x版,Apple TV中的数据传输组件中的安全传输功能中的libsecurity_ssl / lib / sslKeyExchange.c中的libsecurity_ssl / lib / sslKeyExchange.c中的SSLVerifySignedServerKeyExchange函数6.0.2之前的6.x和10.9.2之前的Apple OS X 10.9.x不会检查TLS服务器密钥交换消息中的签名,该消息允许中间人攻击者使用任意内容来欺骗SSL服务器签名步骤或省略签名步骤的私钥。
static OSStatus SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams, uint8_t *signature, UInt16 signatureLen) { OSStatus err; .... if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail; .... fail: SSLFreeBuffer(&signedHashes); SSLFreeBuffer(&hashCtx); return err; }
像在第一个示例中一样,此处重复的
goto导致了无法访问的代码:无论
if语句的条件如何,无论如何都将执行第二个
goto语句。 结果,将不检查签名,该函数将返回0,表示签名正常,并且即使签名检查失败,程序也将从服务器接收密钥。 该密钥用于加密正在传输的数据。
这个琐碎的错误产生了深远的影响。 该事件说明了为什么没有理由推测这种或那种CWE缺陷是否危险–您仅出于代码安全的考虑而必须对其进行修复。
顺便说一句,PVS-Studio可以很容易地发现此错误,并立即通过两个CWE警告报告此错误:
这是另一个例子。 很久以前,在2012年,MySQL中发现了一个安全问题,攻击者可以利用它来进入MySQL数据库。 在下面,您将看到存在漏洞的代码片段。
CVE-2012-2122漏洞:Oracle MySQL 5.1.x(5.1.63之前),5.5.x(5.5.24之前)和5.6.x(5.6.6之前)以及MariaDB 5.1.x(5.1.62之前)中的sql / password.c ,5.2.12之前的5.2.x,5.3.6之前的5.3.x和5.5.23之前的5.5.x,在具有memcmp功能某些实现的某些环境中运行时,允许远程攻击者通过使用相同的错误密码,由于返回值检查不正确,最终导致令牌比较成功。
typedef char my_bool; my_bool check_scramble(const char *scramble_arg, const char *message, const uint8 *hash_stage2) { .... return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE); }
memcmp函数返回
int类型的值,而
check_scramble函数返回
my_bool类型的值,实际上是
char 。
int值隐式转换为
char ,最高有效位被截断。 这导致大约256次尝试中使用任意密码登录的尝试中有1次成功使已知用户名成功。
同样,此CWE缺陷在编码阶段可以更早地被消除并防止成为CVE漏洞。 例如,PVS-Studio将其报告为
CWE-197 (
V642 ):数值截断错误。
请参阅文章“
PVS-Studio如何帮助检测漏洞? ”以获取有关该主题的更多信息。
结论
您不能100%地确定您的程序不受0天漏洞的影响。 但是您仍然可以使它们发生的可能性大大降低。 这可以通过使用专用的SAST工具(例如PVS-Studio)来完成。 如果发现您的项目包含归类为CWE问题的缺陷,请确保对其进行修复。 尽管很少有CWE缺陷最终出现在CVE列表中,但修复它们有助于保护您的程序免受许多潜在威胁的侵害。
参考文献
- 下载并评估PVS-Studio
- PVS-Studio代码分析器中用于查找错误和潜在漏洞的技术
- 根据常见弱点枚举(CWE)对PVS-Studio警告进行分类
- 根据SEI CERT编码标准对PVS-Studio警告进行分类