PHP中“==”运算符的安全问题

  PHP是一种通用的开源脚本语言,它的语法混合了C,Java,以及Perl等优秀语言的语法。除此之外,它还提供了大量的函数库可供开发人员使用。但是,如果使用不当,PHP也会给应用程序带来非常大的安全风险。

  在这篇文章中,我们将会对PHP应用程序中经常会出现的一些问题进行深入地分析,尤其是当我们使用“==”(比较运算符)来进行字符串比较时,可能会出现的一些安全问题。虽然近期有很多文章都围绕着这一话题进行过一些探讨,但我决定从“黑盒测试”的角度出发,讨论一下如何利用这个问题来对目标进行渗透和攻击。首先,我会对引起这个问题的根本原因进行分析,以便我们能够更加深入地理解其工作机制,这样才可以保证我们能够尽可能地避免这种安全问题的发生。

  在2011年,PHP官方漏洞追踪系统发现,当字符串与数字在进行比较的时候,程序会出现某些非常奇怪的现象。从安全的角度出发,这个问题实际上并不能算是一个安全问题。比如说,你可以看到下面这段代码:

  实际上,当使用类似“==”这样的比较运算符进行操作时,就会出现这样的情况。上面这个例子中出现的问题不能算是一个漏洞,因为它是PHP所提供的一种名为“类型转换”的功能。从本质上来分析,当我们使用特定的比较运算符(例如== , !=, )来进行操作时,PHP首先会尝试去确定参与比较的数据类型。但是这样的一种类型转换机制将有可能导致计算结果与我们预期的结果有较大出入,而且也会带来非常严重的安全问题。安全研究专家在该问题的完整披露报告中写到:这种类型转化机制将有可能导致权限提升,甚至还会使程序的密码验证过程变得不安全。

  Gynvael写过一篇关于这一话题的经典文章,PHP等号运算符“==”所涵盖的数据类型非常广泛,我们给大家提供了一个较为完整的比较参考列表,并给出了一些示例,具体内容如下所示:

  正如你所看到的,当我们使用“==”来比较这些数字字符串时,参与比较的就是字符串中数字的实际大小,从安全的角度出发,这就是一个非常有趣的问题了。在这种情况下,你可以使用科学计数法来表示一个数字,并将其放在一个字符串中,PHP将会自动把它作为一个数字类型来处理。我们之所以会得到这样的输出类型,是因为PHP使用了一种哈希算法(通常使用十六进制数值表示)来进行处理。比如说,如果一个数字为0,那么在进行松散比较的过程中,PHP会自动对其类型进行转换,但其值永远为0。对于一个给定的散列算法而言,密码就有可能会变成可以被替换的了。比如说,当密码的哈希值被转换成使用科学计数法来表示的数字时,将有可能正好与其他的密码哈希相匹配。这样一来,即使是一个完全不同的密码,也有可能可以通过系统的验证。但有趣的是,当某些采用科学计数法表示的数字在进行比较的时候,结果可能会让你意想不到:

  从静态分析的角度来看,这些安全问题就显得有些普通了。但如果我们从黑盒的角度来看待这些问题,我们能够得到什么样的启发呢?对于应用程序中的任何用户账号而言,如果应用程序使用了当前最为流行的哈希散列算法(例如SHA1和MD5)来对密码进行处理,而你在对密码哈希进行验证的时候使用了PHP的松散比较,那么此时就有可能出现安全问题。我们现在可以考虑进行一次典型的渗透测试,你可以创建一个普通的账号,将密码设置成哈希值类似的其中一个密码,然后使用其他的密码进行登录操作。很明显,系统的安全性完全取决于你所使用的散列算法。所以,我们假设你没有在散列算法中使用“Salt”值,那么你至少得使用两种不同的散列算法来对密码进行处理。

  现在,在我们去对这些密码组合进行研究之前,我们还应该考虑到一点——即密码的要求。因为我们在对这些密码和散列算法进行分析之前,首先得确保我们所设置的初始密码复合了密码复杂度的要求,否则我们的分析和研究将会没有任何的意义。因此,我们得确保我们的密码长度至少为八个字符,密码中包含有大小写字母,数字,以及至少一个特殊字符:具体如下所示:

  为此,我专门编写了一个Python脚本,虽然我没有竭尽全力去优化这个脚本的性能,但是在PyPy编译器的帮助下,这个精心编写的脚本可以在我的AMDFX8350所有可用的CPU核心中稳定运行。除此之外,我还使用到了hashlib库中的散列函数,而且为了避免遇到Python GIL的进程同步问题,我还生成了独立的进程来对密码数据进行处理。不仅如此,我还使用了非常复杂的技术来为每一个密码生成不同的前缀,正如上面这段代码所示。

  在经过了一个多小时的分析之后,我得到了四个密码的SHA1值。令我感到惊讶的是,得到四个密码的MD5值所需的时间竟然更短。

  如果你无法得到如上图所示的计算结果,那么你应该感到幸运。你可以尝试将用户名和密码捆绑在一起,然后使用带“salt”值的散列算法来进行计算。你只需要修改一小部分代码即可实现,点击“这里”获取修改后的脚本。

  PHP给我们提供了一个解决方案,如果你想要对比哈希值,你应该使用password_verify()或hash_equals()这两个函数。它们会对数据进行严格比较,并排除一些其他的干扰因素。但是请你注意,hash_equals()函数也可以用于字符串的比较。

  虽然我们的分析步骤执行起来有些过于复杂,但是从黑盒测试的角度出发,我们所描述的方法也许可以给大家提供一些有价值的信息。如果某个应用程序中的密码采用了这样的一种验证机制,那么它所带来的安全问题将会超出PHP数据类型转换本身所存在的问题。

  这个问题给我们带来的影响远远不止于此。攻击者可以将这些密码添加到字典文件中,然后对应用程序中的所有用户进行暴力破解攻击。而且,如果应用程序的密码恢复机制中存在不安全的因素,攻击者还有可能对目标账号进行不限次数的攻击,直到攻击成功为止。

  比特软件信息化周刊提供以数据库、操作系统和管理软件为重点的全面软件信息化产业热点、应用方案推荐、实用技巧分享等。以最新的软件资讯,最新的软件技巧,最新的软件与服务业内动态来为IT用户找到软捷径。

  比特商务周刊是一个及行业资讯、深度分析、企业导购等为一体的综合性周刊。其中,与中国计量科学研究院合力打造的比特实验室可以为商业用户提供最权威的采购指南。是企业用户不可缺少的智选周刊!

  比特网络周刊向企业网管员以及网络技术和产品使用者提供关于网络产业动态、技术热点、组网、建网、网络管理、网络运维等最新技术和实用技巧,帮助网管答疑解惑,成为网管好帮手。

  比特服务器周刊作为比特网的重点频道之一,主要关注x86服务器,RISC架构服务器以及高性能计算机行业的产品及发展动态。通过最独到的编辑观点和业界动态分析,让您第一时间了解服务器行业的趋势。

  比特存储周刊长期以来,为读者提供企业存储领域高质量的原创内容,及时、全面的资讯、技术、方案以及案例文章,力求成为业界领先的存储媒体。比特存储周刊始终致力于用户的企业信息化建设、存储业务、数据保护与容灾构建以及数据管理部署等方面服务。

  比特安全周刊通过专业的信息安全内容建设,为企业级用户打造最具商业价值的信息沟通平台,并为安全厂商提供多层面、多维度的媒体宣传手段。与其他同类网站信息安全内容相比,比特安全周刊运作模式更加独立,对信息安全界的动态新闻更新更快。

  新闻中心以独特视角精选一周内最具影响力的行业重大事件或圈内精彩故事,为企业级用户打造重点突出,可读性强,商业价值高的信息共享平台;同时为互联网、IT业界及通信厂商提供一条精准快捷,渗透力强,覆盖面广的媒体传播途径。

  比特云计算周刊关注云计算产业热点技术应用与趋势发展,全方位报道云计算领域最新动态。为用户与企业架设起沟通交流平台。包括IaaS、PaaS、SaaS各种不同的服务类型以及相关的安全与管理内容介绍。

  比特CIO俱乐部周刊以大量高端CIO沙龙或专题研讨会以及对明星CIO的深入采访为依托,汇聚中国500强CIO的集体智慧。旨为中国杰出的CIO提供一个良好的互融互通 、促进交流的平台,并持续提供丰富的资讯和服务,探讨信息化建设,推动中国信息化发展引领CIO未来职业发展。

  IT专家新闻邮件长期以来,以定向、分众、整合的商业模式,为企业IT专业人士以及IT系统采购决策者提供高质量的原创内容,包括IT新闻、评论、专家答疑、技巧和白皮书。此外,IT专家网还为读者提供包括咨询、社区、论坛、线下会议、读者沙龙等多种服务。

  X周刊是一份IT人的技术娱乐周刊,给用户实时传递I最新T资讯、IT段子、技术技巧、畅销书籍,同时用户还能参与我们推荐的互动游戏,给广大的IT技术人士忙碌工作之余带来轻松休闲一刻。

相关阅读