0

0

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

大家讲道理

大家讲道理

发布时间:2016-11-12 10:28:27

|

1318人浏览过

|

来源于php中文网

原创

前言

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

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

问题的描述

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

9a73e7bb23368ab59999abbd08c37684.png

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

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

35eb74bd40b59bffd3e7bbbac92662bf.png

立即学习PHP免费学习笔记(深入)”;

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

AIFreePhp企业建站系统
AIFreePhp企业建站系统

AiFreePhp(爱免费php企业建站程序是一个免费开源的PHP建站程序),基于PHP + MYSQL 与模板技术,具有产品展示,文章栏目,下载管理,友情链接等功能。无任何限制功能,程序简单实用,可用于中小企业网站建设,不收取任何费用。使用本程序,不可将程序变相转售,二次开发发布。 运行安装目/install/index.php一般要求安装在站点的根目录,不是根目录有试过有没有问题,请大家尽量以

下载

3.png

从“黑盒测试”的角度出发来考虑这个问题

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

现在,在我们去对这些密码组合进行研究之前,我们还应该考虑到一点——即密码的要求。因为我们在对这些密码和散列算法进行分析之前,首先得确保我们所设置的初始密码复合了密码复杂度的要求,否则我们的分析和研究将会没有任何的意义。因此,我们得确保我们的密码长度至少为八个字符,密码中包含有大小写字母,数字,以及至少一个特殊字符:具体如下所示:
import random
import hashlib
import re
import string
import sys
prof = re.compile("^0+ed*$") # you can also consider: re.compile("^d*e0+$")
prefix = string.lower(sys.argv[1])+'!'+string.upper(sys.argv[1])+"%s"
num=0
while True:
    num+=1
    b = hashlib.sha256(prefix % num).hexdigest()
    if (b[0]=='0' and prof.match(b)):
        print(prefix+str(num),b)
为此,我专门编写了一个Python脚本,虽然我没有竭尽全力去优化这个脚本的性能,但是在PyPy编译器的帮助下,这个精心编写的脚本可以在我的AMD FX8350所有可用的CPU核心中稳定运行。除此之外,我还使用到了hashlib库中的散列函数,而且为了避免遇到Python GIL的进程同步问题,我还生成了独立的进程来对密码数据进行处理。不仅如此,我还使用了非常复杂的技术来为每一个密码生成不同的前缀,正如上面这段代码所示。
分析结果

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

密码的计算结果十分相似,具体如下所示:

4.png

你可以随意选取两个密码来进行对比,对比的演示结果如下:

5.png

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

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

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

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

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

0

2026.01.15

公务员递补名单公布时间 公务员递补要求
公务员递补名单公布时间 公务员递补要求

公务员递补名单公布时间不固定,通常在面试前,由招录单位(如国家知识产权局、海关等)发布,依据是原入围考生放弃资格,会按笔试成绩从高到低递补,递补考生需按公告要求限时确认并提交材料,及时参加面试/体检等后续环节。要求核心是按招录单位公告及时响应、提交材料(确认书、资格复审材料)并准时参加面试。

2

2026.01.15

公务员调剂条件 2026调剂公告时间
公务员调剂条件 2026调剂公告时间

(一)符合拟调剂职位所要求的资格条件。 (二)公共科目笔试成绩同时达到拟调剂职位和原报考职位的合格分数线,且考试类别相同。 拟调剂职位设置了专业科目笔试条件的,专业科目笔试成绩还须同时达到合格分数线,且考试类别相同。 (三)未进入原报考职位面试人员名单。

10

2026.01.15

国考成绩查询入口 国考分数公布时间2026
国考成绩查询入口 国考分数公布时间2026

笔试成绩查询入口已开通,考生可登录国家公务员局中央机关及其直属机构2026年度考试录用公务员专题网站http://bm.scs.gov.cn/pp/gkweb/core/web/ui/business/examResult/written_result.html,查询笔试成绩和合格分数线,点击“笔试成绩查询”按钮,凭借身份证及准考证进行查询。

2

2026.01.15

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

63

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

32

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

73

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

20

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

25

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.7万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 2.5万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号