[BT]小迪安全2023学习笔记(第20天:Web攻防-PHP特性)

第20天

==和===

==(等值比较)
当使用 == 操作符时,PHP将进行宽松比较,也就是说,只比较两个值的等价性,而不考虑它们的类型。

如果两个值类型不同,PHP会尝试将它们转换成相同的类型,然后再进行比较。

例如,字符串 “100” 和整数 100 使用 == 比较时结果为 true,因为字符串 “100” 在比较时会被转换成整数 100。

if ("100" == 100) { // true,因为值相等
    echo "等值";
}

===(全等比较)
使用 === 操作符时,PHP将进行严格比较,这意味着它不仅比较两个值的等价性,还会比较它们的类型。

只有当两个值的类型相同,且值也相等时,比较结果才为 true。

使用上面的例子,字符串 “100” 和整数 100 使用 === 比较时结果为 false,因为尽管它们的值相等,但类型不同。

if ("100" === 100) { // false,因为类型不相同
    echo "全等";
}

MD5

PHP中MD5比对漏洞通常与==(等值比较)操作符的使用有关。这种漏洞源于PHP在使用==进行字符串比较时,如果两个比较的字符串都是以0e开头,后跟纯数字,PHP会将它们视为科学记数法表示的数值零。因此,即使两个字符串实际上是不同的,它们也会被认为是相等的。

漏洞示例

$hash1 = md5('240610708');
$hash2 = md5('QNKCDZO');

if ($hash1 == $hash2) {
    echo '两个不同的字符串产生的MD5值被认为是相等的。';
}

md5(‘240610708’) 的结果是 0e462097431906509019562988736854,
md5(‘QNKCDZO’) 的结果是 0e830400451993494058024219903391。

由于这两个MD5值都以0e开头,后面跟随的都是数字,根据PHP的等值比较规则,这两个MD5值被认为是相等的,即使它们实际上是不同的字符串的结果。

安全建议
为避免这种安全漏洞,推荐使用全等比较操作符 ===,因为全等比较会认为这两个MD5值不相等

当涉及到敏感数据比对(如密码哈希值)时,应始终使用全等比较操作符 ===,以确保既比较值也比较值的类型,从而避免潜在的安全风险。

PHP中关于数组使用md5函数可能遇到的“漏洞”或不当行为,主要是由于md5函数对非字符串参数的处理方式引起的。由于 PHP 的 md5 函数不直接支持数组类型,尝试对任何数组使用 md5 函数将导致 PHP 内部将数组转换为字符串 “Array”,然后对该字符串计算 MD5 值。因此,不管数组的内容或数组变量的名称如何,只要传递的是数组,md5 函数都会返回对字符串 “Array” 的 MD5 哈希值,这意味着所有不同的数组都会返回相同的 MD5 值。

行为示例

$hash = md5(array('key' => 'value'));
echo $hash;

上述代码会产生类似以下的警告:

vbnet
Copy code
Warning: md5() expects parameter 1 to be string, array given in ...

并且md5函数会返回对字符串"Array"的MD5哈希值,而不是输入数组的哈希值。这意味着,无论数组的内容如何,对任何数组使用md5都会返回相同的结果,即:

echo md5("Array"); // 产生固定的输出

intval函数

PHP的intval()函数用于获取变量的整数值。这个函数可以将字符串、浮点数或布尔值转换成整数。当处理数值转换时,intval()是一个非常有用的函数。

基本语法如下:

intval(mixed $value, int $base = 10): int
$value:要转换的值。它可以是字符串、浮点数、布尔值,或者任何你想转换为整数的值。
$base:转换的基数(进制)。默认是10进制。这个参数对于字符串转换特别有用,因为它允许你指定字符串表示的数值的基数。有效的基数范围是236
字符串转整数:
echo intval("42"); // 输出: 42

浮点数转整数:
echo intval(42.7); // 输出: 42

布尔值转整数:
echo intval(true); // 输出: 1
echo intval(false); // 输出: 0

带基数的字符串转整数:
echo intval('1e', 16); // 输出: 30,因为 '1e' 在16进制下等于十进制的30

注意事项

  • 转换规则:如果$value是字符串,则会根据字符串的起始部分尝试转换成整数。如果字符串起始部分不是数字或符号(+/-),intval()将返回0。
  • 浮点数转换:转换浮点数时,intval()会将浮点数向下取整到最接近的整数值。
  • 布尔值转换:布尔值true会被转换为1,false会被转换为0。
  • 基数的使用:当处理字符串转换时,$base参数允许你指定字符串是哪个基数(进制)下的数值,这对于处理不同进制的数值字符串特别有用。

strpos函数

在PHP中,strpos() 函数用于查找字符串内首次出现的另一字符串的位置。如果找到了字符串,则返回首次出现的位置的索引(注意,索引从0开始)。如果没有找到,则返回 FALSE。

strpos(string $haystack, mixed $needle, int $offset = 0): int|false
$haystack:需要搜索的字符串。
$needle:要查找的字符串值。如果 needle 不是一个字符串,它将被转换为整型并视为字符的顺序值。
$offset:可选参数,指定从哪个字符位置开始搜索。默认值为0
$position = strpos("Hello world", "world");
echo $position; // 输出: 6

//在这个例子中,"world" 在 "Hello world" 中首次出现的位置是索引6(H=0, e=1, l=2, l=3, o=4, 空格=5, w=6)。

//未找到字符串:
$position = strpos("Hello world", "php");
if ($position === false) {
    echo "字符串未找到";
} else {
    echo "字符串位于位置: $position";
}

//在这个例子中,由于 "php" 没有在 "Hello world" 中出现,所以 strpos() 返回 false。

//使用偏移量:
$position = strpos("This is a test", "is", 3);
echo $position; // 输出: 5

//这里,搜索从索引3("s"的位置)开始,所以找到的 "is" 是在索引5的位置,而不是字符串开头处的 "is"。

注意事项
严格比较:当 strpos() 返回0时,表示找到的字符串位于 $haystack 的开始位置。因为0在PHP中是一个有效的位置索引,但它在布尔上下文中被视为 false。因此,比较 strpos() 的结果时,应使用全等(=== 或 !==)比较,以准确区分返回的0和 false。

in_array函数

PHP中的in_array()函数用于检查数组中是否存在某个值。如果指定的值存在于数组中,则函数返回true;否则,返回false。这个函数在需要判断一个项是否已经包含在数组中时非常有用,比如在处理表单输入或验证数据时。

in_array(mixed $needle, array $haystack, bool $strict = false): bool
$needle:需要搜索的值。
$haystack:被搜索的数组。
$strict:这是一个可选参数,如果设置为true,则in_array()还会检查$needle与找到的元素的类型是否完全相同。
$array = array("Apple", "Orange", "Banana");

if (in_array("Apple", $array)) {
    echo "找到了Apple。";
} else {
    echo "没有找到Apple。";
}

//使用严格模式:
$array = array(1, 2, "3", 4);

if (in_array("3", $array, true)) {
    echo "严格模式:找到了字符串'3'。";
} else {
    echo "严格模式:没有找到字符串'3'。";
}

if (in_array(3, $array, true)) {
    echo "严格模式:找到了数字3。";
} else {
    echo "严格模式:没有找到数字3。";
}

在这个例子中,第一次in_array调用未找到"3",因为启用了严格模式,而数组中的"3"是字符串类型,与搜索的数字类型不匹配。第二次调用同样没有找到数字3,因为虽然数组中确实有一个值为3的字符串,但严格模式要求类型也必须匹配

注意事项
在不使用严格模式(默认情况)时,in_array()只比较值,不比较类型。这意味着数字1和字符串"1"会被视为相等。
在使用严格模式(将$strict参数设置为true)时,in_array()会同时比较值和类型,提高了比较的准确性。

preg_match函数

这是PHP中用于执行正则表达式匹配的函数。preg_match()函数会执行一个正则表达式匹配测试,如果模式匹配成功,则返回1;如果失败,则返回0;如果发生错误,则返回FALSE。

preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0)
$pattern:要搜索的模式,即正则表达式。正则表达式字符串需要被定界符包围,如/pattern/$subject:输入字符串,即需要进行正则表达式匹配的文本。
$matches:(可选)如果提供,它将被填充为搜索结果。$matches[0]将包含完整模式匹配到的文本,$matches[1]将包含第一个括号内的子模式匹配到的文本,依此类推。
$flags:(可选)可以用来控制匹配的各种选项。
$offset:(可选)从目标字符串的哪个位置开始搜索(以字节为单位)。
$subject = "This is a test";
$pattern = "/is/";

if (preg_match($pattern, $subject, $matches)) {
    echo "匹配成功。\n";
    print_r($matches);
} else {
    echo "匹配失败。";
}

str_replace函数

PHP中的str_replace()函数用于替换字符串中的一些字符或子字符串。这个函数非常灵活,可以处理简单的字符替换,也能进行批量的子字符串替换,并且可以在数组中搜索和替换。

str_replace(mixed $search, mixed $replace, mixed $subject, int &$count = null): mixed
$search:要查找的字符串(或字符串数组)。这是你想要在$subject中被替换掉的部分。
$replace:用于替换的字符串(或字符串数组)。这是替换$search找到的内容的部分。
$subject:输入字符串(或字符串数组)。这是被搜索和替换的原文本。
$count:(可选)一个变量,用于统计进行替换的次数。
//返回替换后的字符串或数组。如果$subject是数组,那么str_replace()返回一个数组;如果$subject是字符串,返回一个字符串。

echo str_replace("world", "PHP", "Hello world"); // 输出:Hello PHP,默认只替换一次

//数组替换:
$find = array('apple', 'banana');
$replace = array('orange', 'grape');
$subject = 'I love apple and banana.';

echo str_replace($find, $replace, $subject); // 输出:I love orange and grape.

//统计替换次数:
$count = 0;
str_replace('apple', 'orange', 'apple pie, apple juice, and apples', $count);
echo $count; // 输出:3

注意事项
如果$search和$replace都是数组,则它们的键值一一对应,即每个$search的值将被对应$replace的值替换。
如果$replace的元素少于$search的元素,多出的$search将用空字符串进行替换。
如果$subject是数组,则$search和$replace的处理会应用于数组的每一个元素。
str_replace()是大小写敏感的。如果需要进行大小写不敏感的替换,请使用str_ireplace()函数。

例题1

include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
	$num=$_GET ['num’];
	if(preg_match(”f [0-9]/,$num)){
		die("no no no! ");
	}
	if (intval ($num) ){
		echo$flag;
	}
}

payload:url + ?num[] = 1

解析:$num是一个数组,这导致preg_match()直接返回false,并且不会执行die(“no no no!”),因为preg_match()期望的是字符串,而这里提供的是数组。当对数组应用intval()函数时,PHP会将数组转换为整数。在PHP中,将数组转换成整数通常结果为0。

综上,该代码片段试图通过正则表达式来限制输入值必须为数字,并通过intval()来确保这个值在经过类型转换后仍然为真(即非零)。然而,由于$_GET[‘num’]可以通过num[] = 1变为数组,从而绕过了正则表达式检查。

例题2

include ("flag. php");
highlight_file(__FILE__);
if(isset ($_GET ['num'])){
	$num =$_GET['num'];
	if($num==="4476"){
		die("no no no! ");
	}
	if(intval ($num, 0)===4476){
		echo $flag;
	}else {
		echo intval ($num, 0);
	}
}

payload: url + ?num = 010574

解析:使用intval()函数时,如果指定第二个参数(基数)为0,那么intval()函数会根据字符串的格式自动判断数值的基数。特别是,如果字符串以"0"开头,PHP会将这个字符串当作八进制数来处理。
因此,当传递num=010574时,intval($num)会将010574解释为一个八进制数,转换成十进制是4476。由于$num(字符串"010574")不严格等于(===)字符串"4476",因此不会执行die(“no no no!”);语句。在接下来的if语句中,intval($num)的结果确实等于4476(十进制),因此满足条件,执行echo $flag;,展示了$flag的内容。

例题三

show_source(__FILE__);
include('flag.php');
$a = $_GET['cmd'];
if (preg_match('/^php$/im', $a)) {
    if (preg_match('/^php$/i', $a)) {
        echo 'hacker';
    } else {
        echo $flag;
    }
} else {
    echo 'nonononono';
}

payload: url + ?cmd = %0aphp

解析:%0a是URL编码形式的换行符(\n)。由于第一个preg_match使用了多行(m)模式,它将允许正则表达式匹配字符串中的任何位置(由于换行符的存在),使得$a匹配成功。换句话说,尽管$a的值以换行符开始,它仍然满足正则表达式的条件。第二个preg_match没有使用多行模式,因此理论上不会匹配以换行符开始的字符串\nphp,这导致执行流进入else分支,打印出$flag。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/448811.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AHU 汇编 实验三

实验名称:实验三 串操作指令 二、实验内容: 在数据段定义缓冲区,从键盘接收两串字符到两个缓冲区,将第二串中与第一串字符不一致的字符显示在屏幕。 实验过程: 源代码: data segmentmess1 db 16,?,16…

连接端口和连接端口转换OrCAD补丁

来介绍此功能之前先复习一下一些OrCAD的基础知识。 说到连通两个器件,有什么办法呢?最直接的就是用线连通。比如下面这两个器件需要连通,我们可以直接用线Place wire连接。 但是如果这两个器件由于某些原因,他们之间相隔很远&…

STM32CubeMX 配置 STM32F103 工程:通过DAC输出正弦波

说明:STM32CubeMX 配置 STM32F103 工程,通过DAC输出正弦波,参考代码可自动计算频率,自动计算正弦数据。 先参考这篇文章配置时钟、工程输出的设置: STM32CubeMX 配置 STM32F103 工程:通过DAC生成三角波、…

【C++】排序算法

一、排序算法概述 在C语言中&#xff0c;通常需要手写排序算法实现对数组或链表的排序&#xff0c;但是在C中&#xff0c;标准库中的<algorithm>头文件中已经实现了基于快排的不稳定排序算法 std::sort() &#xff0c;以及稳定的排序算法 std::stable_sort() 。 排序算…

c# combox 行间距调整

初始化combox comboBox1.DropDownStyle ComboBoxStyle.DropDownList;comboBox1.ItemHeight 25; // 设置 combox 的行高comboBox1.DrawMode DrawMode.OwnerDrawVariable; 添加 DrawItem 事件 private void comboBox1_DrawItem(object sender, DrawItemEventArgs e){if (…

鸿蒙Harmony应用开发—ArkTS声明式开发(模态转场设置:全屏模态转场)

通过bindContentCover属性为组件绑定全屏模态页面&#xff0c;在组件插入和删除时可通过设置转场参数ModalTransition显示过渡动效。 说明&#xff1a; 从API Version 10开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 不支持横竖屏切换。…

docker安装各种组件

一 docker基本命令 镜像操作 ① 列举镜像 docker images ② 搜索镜像&#xff08;以jdk为例&#xff09; docker search jdk ③ 下载镜像 docker pull java ④ 查看所有镜像 docker images ⑤ 启动镜像&#xff08;以jdk8为例&#xff09; docker run -it --name jdk…

AI会砸了我们的饭碗?

Sora&#xff0c;由OpenAI推出&#xff0c;是一款创新的文本到视频生成模型。它能够将文本描述转化为引人入胜的高清视频片段。采用了扩散模型和变换器架构&#xff0c;Sora实现了高效的训练。其方法包括统一表示法、基于补丁的表示法、视频压缩网络和扩散变换器。 Sora具备多种…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:CalendarPicker)

日历选择器组件&#xff0c;提供下拉日历弹窗&#xff0c;可以让用户选择日期。 说明&#xff1a; 该组件从API Version 10开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 CalendarPicker(options?: CalendarOptions) …

conda安装playwright

进入conda安装目录激活环境 D:\Anacoda3>conda activate base 安装playwright &#xff08;base&#xff09;D:\Anacoda3>pip3 install playwright -i https://pypi.tuna.tsinghua.edu.cn/simple &#xff08;base&#xff09;D:\Anacoda3>python -m playwright insta…

深入理解React中的useState:函数组件状态管理的利器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

transformer参数推导

一、目录 1.Bert Embedding 参数量计算 2.多头自注意力self_attention 参数计算: d_model* d_model 3*(d_model* d_qkvnum_heads) 3. 全连接层参数量 4.layerNormer 参数量 2hidden 5. 编码器 解码器参数 6. 语言模型head 参数&#xff1a;hidden* vocab 二、实现 参考&…

仿生蝴蝶制作——蝴蝶翅膀制作

前言 上一次已经设计好了的翅膀图纸 接下来就是根据这个图纸来制作翅膀。 过程中其实可以不用尺子准确测量&#xff0c;直接用碳纤维棒比着剪下来就好了&#xff0c;然后把减下来的一截比着剪下另一只翅膀需要的材料。因为左右两只翅膀差别不能太大&#xff0c;所以这样是最好…

【Java设计模式】十四、策略模式

文章目录 1、策略模式2、案例&#xff1a;促销策略3、总结4、在源码中的实际应用 1、策略模式 从A地到B地&#xff0c;出行方式可选汽车、火车、飞机中的一种 日常开发&#xff0c;开发工具可IDEA&#xff0c;可Eclipse 不管你选飞机还是火车&#xff0c;你最终都可以实现从A地…

SpringBoot注解--08--注解@JsonInclude

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 JsonInclude注解是jackSon中最常用的注解之一&#xff0c;是为实体类在接口序列化返回值时增加规则的注解 1.JsonInclude用法2.JsonInclude注解中的规则有 案例需求…

vue自定义主题皮肤方案

方案一&#xff1a;CSS变量换肤&#xff08;推荐&#xff09; 利用css定义变量的方法&#xff0c;用var在全局定义颜色变量&#xff08;需将变量提升到全局即伪类选择器 :root&#xff09;然后利用js操作css变量&#xff0c;document.getElementsByTagName(‘body’)[0].style…

网络套接字1

网络套接字1 &#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;Linux &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要内容讲解了udp的Linux环境下的使用&#xff0c…

鼠标在QTreeView、QTableView、QTableWidget项上移动,背景色改变

目录 1. 前言 2. 需求 3. 功能实现 3.1. 代码实现 3.2. 功能讲解 4. 附录 1. 前言 本博文用到了Qt的model/view framework框架,如果对Qt的“模型/视图/委托”框架不懂&#xff0c;本博文很难读懂。如果不懂这方面的知识&#xff0c;请在Qt Assistant 中输入Model/View…

一款适合程序员开发复杂系统的通用平台——JNPF 开发平台

在过去&#xff0c;很多开发工具更侧重代码编辑&#xff0c;针对数据库增删改查&#xff08;CRUD&#xff09;类的 Web 系统开发&#xff0c;在界面设计、前后端数据交互等环节主要还是靠写代码&#xff0c;效率比较低。目前很多所谓的低代码开发平台&#xff0c;大多数也都是基…

SQLServer数据库系列之:查询SQLServer数据库上面的连接信息、session信息、sql语句

SQLServer数据库系列之:查询SQLServer数据库上面的连接信息、session信息、sql语句 一、查询数据库上的连接信息二、查询SQLServer数据库的session信息SQLServer数据库从入门到精通系列文章之:SQLServer数据库百篇技术文章汇总 数据库专栏系列文章阅读传送门:详细整理汇总M…
最新文章