php的比较操作符有==(等于)松散比较,===(完全等于)严格比较,这里面就会引入很多有意思的问题。

在松散比较的时候,php会将他们的类型统一,比如说字符到数字,非bool类型转换成bool类型,为了避免意想不到的运行效果,应该使用严格比较。如下是php manual上的比较运算符表:

例子        名称         结果

$a == $b    等于      TRUE,如果类型转换后 $a 等于 $b。

$a === $b   全等      TRUE,如果 $a 等于 $b,并且它们的类型也相同。

$a != $b    不等      TRUE,如果类型转换后 $a 不等于 $b。

$a  $b    不等      TRUE,如果类型转换后 $a 不等于 $b。

$a !== $b   不全等     TRUE,如果 $a 不等于 $b,或者它们的类型不同。

$a  $b     大于      TRUE,如果 $a 严格大于 $b。

$a = $b    大于等于     TRUE,如果 $a 大于或者等于 $b。

0x01 安全问题

1 hash比较缺陷

php在处理hash字符串的时候会用到!=,==来进行hash比较,如果hash值以0e开头,后边都是数字,再与数字比较,就会被解释成0*10^n还是为0,就会被判断相等,绕过登录环节。

root@kali:~/tool# php -r 'var_dump("00e0345" == "0");var_dump("0e123456789"=="0");var_dump("0e1234abc"=="0");'

bool(true)

bool(true)

bool(false)

当全是数字的时候,宽松的比较会执行尽力模式,如0e12345678会被解释成0*10^12345678,除了e不全是数字的时候就不会相等,这能从var_dump("0e1234abc"=="0")可以看出来。

2 bool 欺骗

当存在json_decode和unserialize的时候,部分结构会被解释成bool类型,也会造成欺骗。json_decode示例代码:

$json_str = '{"user":true,"pass":true}';

$data = json_decode($json_str,true);

if ($data['user'] == 'admin' && $data['pass']=='secirity')

{

    print_r('logined in as bool'."\n");

}

运行结果:

root@kali:/var/www# php /root/php/hash.php

logined in as bool

unserialize示例代码:

$unserialize_str = 'a:2:{s:4:"user";b:1;s:4:"pass";b:1;}';

$data_unserialize = unserialize($unserialize_str);

if ($data_unserialize['user'] == 'admin' && $data_unserialize['pass']=='secirity')

{

    print_r('logined in unserialize'."\n");

}

运行结果如下:

1

2

root@kali:/var/www# php /root/php/hash.php

logined in unserialize

3 数字转换欺骗

$user_id = ($_POST['user_id']);

if ($user_id == "1")

{

    $user_id = (int)($user_id);

    #$user_id = intval($user_id);

    $qry = "SELECT * FROM `users` WHERE user_id='$user_id';";

}

$result = mysql_query($qry) or die('

' . mysql_error() . '' );

print_r(mysql_fetch_row($result));

将user_id=0.999999999999999999999发送出去得到结果如下:

Array

(

    [0] => 0

    [1] => lxx'

    [2] =>

    [3] =>

    [4] =>

    [5] =>

)

本来是要查询user_id的数据,结果却是user_id=0的数据。int和intval在转换数字的时候都是就低的,再如下代码:

if ($_POST['uid'] != 1) {

 $res = $db->query("SELECT * FROM user WHERE uid=%d", (int)$_POST['uid']);

 mail(...);

} else {

 die("Cannot reset password of admin");

}

假如传入1.1,就绕过了$_POST['uid']!=1的判断,就能对uid=1的用户进行操作了。另外intval还有个尽力模式,就是转换所有数字直到遇到非数字为止,如果采用:

if (intval($qq) === '123456')

{

    $db->query("select * from user where qq = $qq")

}

攻击者传入123456 union select version()进行攻击。

4 PHP5.4.4 特殊情况

这个版本的php的一个修改导致两个数字型字符溢出导致比较相等

$ php -r 'var_dump("61529519452809720693702583126814" == "61529519452809720000000000000000");'

bool(true)

3 题外话:

同样有类似问题的还有php strcmp函数,manual上是这么解释的,int strcmp ( string $str1 , string
$str2
),str1是第一个字符串,str2是第二个字符串,如果str1小于str2,返回str2,返回>0,两者相等返回0,假如str2为一个array呢?

$_GET['key'] = array();

$key = "llocdpocuzion5dcp2bindhspiccy";

$flag = strcmp($key, $_GET['key']);

if ($flag == 0) {

    print "Welcome!";

} else {

    print "Bad key!";

}

运行结果:

root@kali:~/php# php strcmp.php

PHP Warning:  strcmp() expects parameter 2 to be string, array given in /root/php/strcmp.php on line 13

Welcome!

参考:
1,http://phpsadness.com/sad/472,http://php.net/language.operators.comparison3,http://indico.cern.ch/event/241705/material/slides/0.pdf

原文链接:http://www.myhack58.com/Article/60/61/2015/65424.htm

PHP比较操作符详解(转自hack58)的更多相关文章

  1. SQL Server 执行计划操作符详解(3)——计算标量(Compute Scalar)

    接上文:SQL Server 执行计划操作符详解(2)--串联(Concatenation ) 前言: 前面两篇文章介绍了关于串联(Concatenation)和断言(Assert)操作符,本文介绍第 ...

  2. SQL Server 执行计划操作符详解(2)——串联(Concatenation )

    本文接上文:SQL Server 执行计划操作符详解(1)--断言(Assert) 前言: 根据计划,本文开始讲述另外一个操作符串联(Concatenation),读者可以根据这个词(中英文均可)先幻 ...

  3. C#基础操作符详解(上)

    本节内容: 1.操作符概览: 2.操作符的本质: 3.操作符与运算顺序 4.操作符详解. 1.操作符概览: 操作符(Operator)也译为”运算符” 操作符是用来操作数据的,被操作符操作的数据称为操 ...

  4. javascript中的操作符详解1

    好久没有写点什么了,根据博主的技术,仍然写一点javascript新手入门文章,接下来我们一起来探讨javascript的操作符. 一.前言 javascript中有许多操作符,但是许多初学者并不理解 ...

  5. LINQ标准查询操作符详解(转)

     一. 关于LINQ       LINQ 英文全称是“Language-Integrated Query”,中文为“语言集成查询”,它是微软首席架构师.Delphi 之父和C# 之父——Anders ...

  6. SQL Server 执行计划操作符详解(1)——断言(Assert)

    前言: 很多很多地方对于语句的优化,一般比较靠谱的回复即使--把执行计划发出来看看.当然那些只看语句就说如何如何改代码,我一直都是拒绝的,因为这种算是纯蒙.根据本人经验,大量的性能问题单纯从语句来看很 ...

  7. JavaScript 中的相等操作符 ( 详解 [] == []、[] == ![]、{} == !{} )

    ECMAScript 中的相等操作符由两个等于号 ( == ) 表示,如果两个操作数相等,则返回 true. 相等操作符会先转换操作数(通常称为强制转型),然后比较它们的相等性. 在转换不同的数据类型 ...

  8. Java一元操作符++详解

    废话不多说,直接上代码. package com.coshaho.learn; /** * * OperatorLearn.java Create on 2016-11-13 下午8:38:15 * ...

  9. C++ new操作符详解

    一.new操作符的概念 我们通常讲的new是指的是new operator,其实还有另外两个概念,operator new 和 placement new. 1.new operator 我们在使用n ...

随机推荐

  1. Python学习基本

    刚开始学习是看了这个网站: 廖雪峰的官方网站  http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac92707 ...

  2. play(1) 第一个简单的应用

    去年去了一家公司,公司要求要回使用play,所以在几天的时间内猛学习了一段时间play,发现play!有很多优点:简单,小巧,高开发效率,集成很多功能,容易调试.现在虽然已经不在那家公司,没有使用pl ...

  3. father of the archangel of death"?

    e wields an axe, a sword and a machine gun and his battlefield pranks have become as legendary as hi ...

  4. SQLserver CASE WHEN

    declare @shuzu int set @shuzu=1 select (case @shuzu when '1' then '444' when '2'then '555' end) as ' ...

  5. mvc 传递匿名对象

    Controller代码: public ActionResult TupleTest() { LinqDBEntities db = new LinqDBEntities(); dynamic da ...

  6. shopex 小知识

    产品链接: http://www.--/product-172.html 中间的数字代表  sdb_goods 表中 的 goods_id  ... 表示数据库里的产品 id. 分类链接: http: ...

  7. Kafka的安装和部署及测试

    1.简介 大数据分析处理平台包括数据的接入,数据的存储,数据的处理,以及后面的展示或者应用.今天我们连说一下数据的接入,数据的接入目前比较普遍的是采用kafka将前面的数据通过消息的方式,以数据流的形 ...

  8. Json 讲解

    JSON详解 阅读目录 JSON的两种结构 认识JSON字符串 在JS中如何使用JSON 在.NET中如何使用JSON 总结 JSON的全称是”JavaScript Object Notation”, ...

  9. pointer to function

    指针.函数.数字.结构体.指针函数.函数指针 初学不好区分,做点儿实验来有效区分一下,以下代码采用dev-C++平台测试 //pointer to fucntion 函数功能是 基地址加偏移量得到偏移 ...

  10. dreamweaver快捷键

    ---恢复内容开始--- 件菜单 新建文档 Ctrl+N 打开一个 HTML文件 Ctrl+O或者将文件从[文件管理器]或[站点]窗口拖动到[文档]窗口中 在框架中打开 Ctrl+Shift+O 关闭 ...