PHP比较漏洞, 代码审计, 字符串数字, “0e“字符串, 布尔值比较, 极限值, switch比较, in_array比较

本文主要是介绍PHP比较漏洞, 代码审计, 字符串数字, “0e“字符串, 布尔值比较, 极限值, switch比较, in_array比较,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

PHP比较漏洞

一, 字符串与数字比较,'0e’字符串比较

在 PHP 中处理字符串和数字比较时需要小心谨慎的重要性,尤其是在安全敏感的应用中。
在某些情况下,PHP 的类型强制转换可能会导致意外和潜在的安全漏洞。

var_dump("admin" == 0);  //true
var_dump("1admin" == 1); //true
var_dump("admin1" == 1); //false
var_dump("admin1" == 0); //true
var_dump("0e123456" == "0e4456789"); //true 

这段代码展示了 PHP 中的一些有趣且可能导致安全隐患的类型强制转换行为。让我们逐一分析每个表达式:

var_dump("admin" == 0);
在 PHP 中,当一个字符串与数字进行比较时,如果字符串不是以数字开始,则该字符串会被转换为数字 0。因此,“admin” 被转换为 0,所以 0 == 0 是 true。

var_dump("1admin" == 1);
在这个例子中,字符串 “1admin” 在尝试转换为数字时,会被解析为数字 1,因为它以 1 开始,忽略后续非数字字符。因此,1 == 1 是 true。

var_dump("admin1" == 1);
这里 “admin1” 作为字符串,不能转换为数字 1,因为它不是以数字开始的。它将被转换为 0。所以,0 == 1 是 false。

var_dump("admin1" == 0);
同上,“admin1” 转换为数字时变成了 0,所以 0 == 0 是 true。

var_dump("0e123456" == "0e4456789");
这是 PHP 类型强制转换中最有趣的一个例子。当一个字符串看起来像是科学记数法时(例如 “0e123456”),在与另一个类似结构的字符串比较时,它们都会被转换为数字 0。

这是因为 e 后面的数字被解释为指数,但由于前面的数字是 0,所以整个表达式的值为 0。
因此,两个看似不同的字符串在这种情况下会被认为是相等的。

二, Hash字符串比较

原理还是科学计数法字符串比较的问题.

测试1:
var_dump("0e123456789012345678901234567890" === "0"); //false
var_dump("0e123456789012345678901234567890" == "0"); //true

因为 e 后面的数字被解释为指数,但由于前面的数字是 0,所以整个表达式的值为 0。

测试2:
$pass = $_GET['password'];
$password = '0e342768416822451524974117254469';if (md5($pass) == $password) {echo "flag{xx-xx-xxxx-xxx}";
}
else {echo "error";
}

对于上面的代码那么只要是提交的密码的md5值是以0e开头的都会绕过, 比如.

?pwd=s1885207154a

除了使用===进行判断外,从 PHP 5.6 开始,hash_equals() 函数被引入,主要用于安全地比较两个字符串的哈希值,通常用于密码或敏感数据的验证。

hash_equals() 函数的关键特点:
1. 时间恒定的比较

这意味着函数在比较两个字符串时所花费的时间不依赖于字符串的内容。这是预防某些类型的定时攻击的重要特性,例如,在一些安全关键的应用场景中,攻击者可能尝试通过测量不同输入导致的响应时间差异来推断信息

2. 二进制安全

hash_equals() 安全地处理二进制数据,确保在比较过程中不会因为特殊字符(如 NULL 字节)而意外截断或错误处理。

3. 字符串比较

它专门用于比较字符串,而不是用于其他数据类型。

一个典型例子是在用户认证系统中比较用户输入的密码哈希值与存储在数据库中的哈希值:

$expected = '存储的哈希值';
$provided = hash('sha256', '用户输入的密码');if (hash_equals($expected, $provided)) {// 密码匹配
} else {// 密码不匹配
}

三, bool比较

1. 在json字符串中:
$str = '{"user":true, "pass":true}';
$data = json_decode($str, true);if($data['user'] == 'root' && $data['pass'] == 'myPass'){echo '登陆成功 获得flag{xx-ssss-xxxx}';
}else{echo '登陆失败!';
}

这里用户名和pass都是true, 由于使用的是==判断, 两个比较的结果都是true.

2. 在序列化字符串中:
$str = 'a:2:{s:4:"user";b:1;s:4:"pass";b:1;}';
$data = unserialize($str); if($data['user'] == 'root' && $data['pass'] == 'myPass'){print_r('获得flag{xx-ssss-xxxx}');
}else{print_r('失败!');
}

a:2: 表示一个数组,包含 2 个元素。
s:4:"user";b:1; 表示数组的第一个键值对。键是一个长度为 4 的字符串 “user”,值是布尔值 true(在 PHP 序列化格式中表示为 b:1)。
s:4:"pass";b:1; 表示数组的第二个键值对。键是一个长度为 4 的字符串 “pass”,值也是布尔值 true。
那么用户名和pass都是true, 绕过了判断.

四, 极限值比较

$a=98869694308861098395599991222222222222;
$b=98869694308861098395599992999999999999;
var_dump($a === $b);

虽然两个值不同, 但是比较的结果是true.

五, switch比较

PHP 中的 switch 语句是松散比较(==),而不是严格比较(===)。这意味着类型强制转换会发生。

$num = '3number';
switch($num){case 0:echo '000';break;case 1:echo '111';break;case 2:echo '222';break;case 3:echo '333';break;default:echo "error";
}

$num = '3number'; 时,由于进行松散比较,PHP 会尝试将这个字符串转换为数字。
由于字符串以数字 3 开始,其余部分在转换过程中将被忽略,因此 $num 被视为数字 3。
结果并不会输出error, 而是333.

六, in_array函数比较

在 PHP 中,in_arrayarray_search 函数在默认情况下使用松散比较(==)
如果没有明确设置 strict 参数为 true,这些函数会执行类型强制转换,可能导致一些非直观的结果。

$array = ['a', 0, 1, 2, '3'];
var_dump(in_array('abc', $array)); // bool(true) 
var_dump(array_search('abc', $array)); // int(1) 

in_array('abc', $array) 在比较 'abc' 和数组中的0时,由于'abc'在松散比较中会被视为 0(非数字开头的字符串在转换为数字时会成为 0),因此 in_array 会返回 true
同理,array_search('abc', $array) 在寻找'abc'时也会找到0这个元素的位置,因此返回 1

这篇关于PHP比较漏洞, 代码审计, 字符串数字, “0e“字符串, 布尔值比较, 极限值, switch比较, in_array比较的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/397874

相关文章

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

java之Objects.nonNull用法代码解读

《java之Objects.nonNull用法代码解读》:本文主要介绍java之Objects.nonNull用法代码,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录Java之Objects.nonwww.chinasem.cnNull用法代码Objects.nonN

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

JavaScript Array.from及其相关用法详解(示例演示)

《JavaScriptArray.from及其相关用法详解(示例演示)》Array.from方法是ES6引入的一个静态方法,用于从类数组对象或可迭代对象创建一个新的数组实例,本文将详细介绍Array... 目录一、Array.from 方法概述1. 方法介绍2. 示例演示二、结合实际场景的使用1. 初始化二

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

python中字符串拼接的几种方法及优缺点对比详解

《python中字符串拼接的几种方法及优缺点对比详解》在Python中,字符串拼接是常见的操作,Python提供了多种方法来拼接字符串,每种方法有其优缺点和适用场景,以下是几种常见的字符串拼接方法,需... 目录1. 使用 + 运算符示例:优缺点:2. 使用&nbsjsp;join() 方法示例:优缺点:3

Java中&和&&以及|和||的区别、应用场景和代码示例

《Java中&和&&以及|和||的区别、应用场景和代码示例》:本文主要介绍Java中的逻辑运算符&、&&、|和||的区别,包括它们在布尔和整数类型上的应用,文中通过代码介绍的非常详细,需要的朋友可... 目录前言1. & 和 &&代码示例2. | 和 ||代码示例3. 为什么要使用 & 和 | 而不是总是使

Java强制转化示例代码详解

《Java强制转化示例代码详解》:本文主要介绍Java编程语言中的类型转换,包括基本类型之间的强制类型转换和引用类型的强制类型转换,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录引入基本类型强制转换1.数字之间2.数字字符之间引入引用类型的强制转换总结引入在Java编程语言中,类型转换(无论