松散比较(PHP)(小迪网络安全笔记~
免责声明:本文章仅用于交流学习,因文章内容而产生的任何违法&未授权行为,与文章作者无关!!!
附:完整笔记目录~
ps:本人小白,笔记均在个人理解基础上整理,若有错误欢迎指正!
1.3 🐘松散比较(PHP)
-
引子:本章主要介绍一些由PHP自身语言特性可能产生的脆弱性,该内容往往被应用于PHP CTF入门题中,但在PHP Web开发时也可能被使用。
-
==
== 是php中的比较运算符,用于判断 == 左右两边的值是否相等。若两边的值类型不同,则会优先将两边的值类型转换为同一类型后再进行比较,也称这种比较方式为松散比较。
这其中使用最多也是最容易产生误解的就是数字、数字字符串、字符串之间的比较。这里给出官方规则:
If both operands are numeric strings, or one operand is a number and the other one is a numeric string, then the comparison is done numerically. These rules also apply to the switch statement.
简单来说,就是当数字与数字字符串,或者数字字符串与数字字符串之间进行比较时,都会被转换为数字后再比较,这些规则同样适用于switch。有没有感觉官方给出的内容有些含糊呢?这里举几个例子:// 在松散比较中,以下格式的字符串会被转换为什么数字呢?如: "sjjjer" "1999sj" "1999e9r" "1999.9er"我们分别来测试一下:
<?php $data1 = "sjjjer"; $data2 = 0; echo $data1 == $data2 ? "true" : "false"; // true --> php版本为7.3 // false --> php版本为8.2 // 从官方给出的解释来看,在php8版本前字符串默认被转换为数字0参与比较,8版本后被修复$data1 = "1999sj19"; $data2 = 1999; echo $data1 == $data2 ? "true" : "false"; // true // 可以看到,当字符串中同时出现字母与数字时,且数字在前, // 则在比较时会默认将字符串转换为出现第一个字母前的数字$data1 = "1999e9r"; $data2 = 1999; echo $data1 == $data2 ? "true" : "false"; // false // 为什么此时松散比较结果为false呢? // 是由于1999e9在转换为数字参与比较时,其实际值为1999 * 10^9,e是科学计数法的标识。 // So 我们可以修改1999的值为1999000000000再尝试比较 $data3 = 1999000000000; echo $data3 == $data1 ? "true" : "false"; // true$data1 = "1999.9er"; $data2 = 1999; echo $data1 == $data2 ? "true" : "false"; // false // 由于在比较时会将字符串转换为出现第一个字母前的数字 // 也就是 "1999.9er" --> 1999.9 (浮点数) // 当我们修改1999为1999.9时,再参与比较 $data3 = 1999.9; echo $data1 == $data3 ? "true" : "false"; // true -
switch()
上述所提松散比较时的类型转换规则同样适用于switch分支结构,也就说明php中switch结构在进行数据比较时也采用松散比较,这里来测试一下。
demo:<?php echo "请输入数据:"; $data1 = fgets(STDIN); // 由于fgets()从键盘获取到的数据默认携带 \n, // 因此需使用trim()去除 $data1 = trim($data1); switch ($data1) {case 0:echo 0;break;case 19:echo 19;break;case "sj":echo "sj";break;default:echo "数据未成功匹配!"; }// fgets()为获取用户所输入数据,默认返回值类型为字符串, // 也就是说data1的数据类型为字符串, // next 进入switch分支结构, // 该分支结构实质为字符串与数字、字符串与字符串的松散比较/*请输入数据:sj --> php版本7.3 0 请输入数据:19er 19 请输入数据:sj --> php版本8.2 sj*/ -
md5()
已知md5加密后会生成固定32位字符串。而在php的身份验证中,常常会存在这样的逻辑:获取用户输入密码并将其转换为md5值,随后再与数据库所存储用户密码比较(数据库中用户密码往往加密存储),若相等则成功验证身份。
若开发者所使用比较运算符为 == ,也就是本文所提松散比较,则可能会出现以下情况:- 用户密码经md5加密后的结果为"0e656002536496242128899000718690"。
- 由上文可知 e 为科学计数法的标识,因此在php中"0e656002536496242128899000718690" 为一串数字字符串。且使用 == 进行松散比较。
- 由php松散比较规则可知,当数字串与数字串比较时,会被转换为数字进行比较。而0e后无论跟什么其结果均为0,因此仅需再寻找另一个字符串,使其满足经md5加密后的结果为0e开头的数字字符串,就能实现,即使所输入密码与用户原码密码不一致,但经md5加密后再进行松散比较,返回结果为true。
我们来验证一下:
<?php echo "请输入您的密码:"; $input = trim(fgets(STDIN)); $password = md5("000dSb96"); if (md5($input) == $password) {echo "恭喜您!密码输入正确"; } else {echo "Sorry,您的密码有误"; }// 请输入您的密码:001st0X5 // 恭喜您!密码输入正确若想获取更多满足要求的字符串,可以写个脚本慢慢跑,这里给出我自己的脚本:
import hashlib import itertools import string# 定义函数,生成所有可能的8-16位字符串 def generate_strings():# 所有可用的字符:数字和字母chars = string.digits + string.ascii_lowercase + string.ascii_uppercase# 生成长度从8到16的字符串for length in range(8, 17):# 生成当前长度的所有可能字符串for s in itertools.product(chars, repeat=length):yield ''.join(s)# 定义函数,检查MD5值是否以0e开头且后续为数字 def check_md5(md5_hash):# 判断MD5值是否以"0e"开头,且后续部分全为数字return md5_hash.startswith("0e") and md5_hash[2:].isdigit()# 主程序 def main():# 打开result.txt文件以写入结果with open("result.txt", "w") as result_file:# 符合条件的字符串数量found_count = 0# 遍历生成的所有字符串for s in generate_strings():# 对字符串进行MD5加密md5_hash = hashlib.md5(s.encode('utf-8')).hexdigest()# 检查MD5是否满足条件if check_md5(md5_hash):# 打印符合条件的字符串和MD5值print(f"{s} {md5_hash}")# 写入到文件中result_file.write(f"{s} {md5_hash}\n")found_count += 1# 如果已经找到了10个符合条件的字符串,停止执行if found_count >= 10:breakif __name__ == "__main__":main()10分钟就跑出来了五条,看来还有很大的优化空间。。。
# 结果展示 000dSb96 0e656002536496242128899000718690 001st0X5 0e632311920444249596217934156166 001uTksg 0e012344733002178183175029976663 001yLWsp 0e561475551818519587284167859133 001CKN1u 0e364973363767512736620399322212 0029F2eL 0e819654840882947331243228254063 002zDdF8 0e693440086514416381258215413583 0031LEiY 0e050990879989909849271876008654 003kjZ6a 0e813458376037199230741560480845 003mHOrg 0e186417107900720544959665557875要是懒得用脚本跑,也可以参考:
https://blog.csdn.net/baidu_41871794/article/details/83750615,这篇博文作者也给了一些例子。 -
strcmp()
php中的字符串比较函数,strcmp($str1, $str2)会逐个字符比较字符串str1,str2的ASCII值,若str1 < str2 则返回值<0,若str1 > str2 则返回值>0,若 str1 = str2 返回值为0。
而在php 8版本之前,若所比较值类型为非字符串时,此时strcmp()函数报错且return 0,也就是说虽然strcmp()所接收参数不为字符串类型,但最终仍判断其字符串值相同。
demo:<?php $str1 = "sjjjer"; $str2 = $_GET["str"]; if (strcmp($str1, $str2) == 0) {echo "两字符串相等"; } else {echo "两字符串不等"; }// url: http://192.168.2.106:81/simplectf/SimplectfDemo4.php?str[]=sj // Warning: strcmp() expects parameter 2 to be string, array given in SimplectfDemo4.php on line 4 // 两字符串相等可以看到,虽然报错但仍执行了两字符串相等的逻辑。测试版本为php 7.3.4,php 8版本后修复。
-
in_array() & array_search()
in_array()用于查找指定值是否在数组中,返回true&false。array_search()用于查找指定值的键(索引),若找到返回索引值,若未找到返回false。同样的,这两个数组查找函数,若未指定其第三个值为true(默认为false),则采用松散比较。
demo:<?php $arr = [0, 19, "sj"]; var_dump(in_array("sjjjer", $arr)); var_dump(array_search("sj", $arr)); var_dump(array_search("sj", $arr, true));// bool(true) // int(0) // int(2) -
bool比较
上文案例所产生的有趣结果,主要基于数字、数字字符串、字符串之间的松散比较规则而成。
而接下来则对bool值与字符串的比较规则做一介绍:- ture 与 字符串比较结果为true,这里的字符串指:数字字符串(“19”),字符串(“sj”)。而false 与 字符串的比较结果为false,这里的字符串类型同true。
- true 与 空字符串比较结果为false,这里的空字符串指:“”,“0”。相反的,false 与 空字符串的比较结果为true。
注:这里的比较均为 ==
若想了解其余类型数据的比较结构,可参考官方比较表:
https://www.php.net/manual/en/types.comparisons.php
demo:<?php // 这里以json_decode() 与 unserialize()函数为例 $str = '{"username": true, "password": true}'; $data = json_decode($str); var_dump($data->username); if ($data->username == "admin" && $data->password == "sjjjer") {echo "身份认证成功!"; } else {echo "身份认证失败!"; }// bool(true) // 身份认证成功! // true与字符串松散比较结果为true。// 正确值为:$str = 'a:2:{s:8:"username";s:5:"admin";s:8:"password";s:6:"sjjjer";}'; $str = 'a:2:{s:8:"username";b:1;s:8:"password";b:1;}'; // 其中b表示bool类型,1为true $data = unserialize($str); if ($data['username'] == 'admin' && $data['password'] == 'sjjjer') {echo "身份认证成功!"; } else {echo "身份认证失败!"; }// 身份认证成功! -
===
以上内容均为开发者采用php松散比较时可能产生的结果,那有没有更为严谨的比较方式呢?采用===比较,===在比较时会先比较两边值类型,再比较值,若两边值类型不同也会返回false,也称这种比较方式为严格比较。
demo:<?php $data1 = "sj"; $data2 = 0; var_dump($data1 === $data2);// bool(false) -
实验
好了,你现在已经大致了解php的松散比较规则,以及使用松散比较可能会产生的问题了。接下来做几道ctf入门题吧:-
第一题
<?php $num = $_GET['num']; // 判断$num的值是否为数字或数字字符串 if (!is_numeric($num)) {echo $num;if ($num == 1) {echo ' flag!';} }答案:
http://192.168.2.106:81/simplectf/SimplectfDemo8.php?num=1sj -
第二题
<?php $md51 = md5('QNKCDZO'); $a = $_GET['a']; $md52 = md5($a); // 判断$a是否有值且值不为NULL if (isset($a)) {if ($a != 'QNKCDZO' && $md51 == $md52) {echo "flag";} else {echo "false!!!";} } else {echo "please input a"; }答案:
http://192.168.2.106:81/simplectf/SimplectfDemo9.php?a=000dSb96
至此,本章内容结束!
-
相关文章:
松散比较(PHP)(小迪网络安全笔记~
免责声明:本文章仅用于交流学习,因文章内容而产生的任何违法&未授权行为,与文章作者无关!!! 附:完整笔记目录~ ps:本人小白,笔记均在个人理解基础上整理,…...
一文了解如何使用 DBeaver 管理 DolphinDB
在日常的数据开发、分析和数据库运维中,一款优秀的 IDE 能够极大地提升工作效率。DBEaver 是一款由 Java 编写的一站式跨平台连接器,其社区版本已能支持连接近百种数据库,受到广大开发者的喜爱。近期。DolphinDB 与 DBeaver 团队共同努力&…...
网络基础知识指南|1-20个
1. IP地址: 即互联网协议地址,是用于标识互联网上的每一个设备或节点的唯一地址。IP地址的作用主要是进行网络设备的定位和路由,确保数据包可以从源设备准确地传送到目标设备。2. 子网掩码: 是用于将一个IP地址划分为网络地址和主机地址的工具。它通常与…...
01.09周四F34-Day50打卡
文章目录 1. -我大衣呢? -就在上次你放的地方。2. 这所学校是在曾经的影院上建立起来的。3. 她今天落到这个地步都怪你。4. 留得青山在,不怕没柴烧。(一息尚存,希望不灭。)5. 有善良的地方就有美德,有美德的地方就有奇迹。(《灰姑娘》原句)6. 为了和老外说话时不再发窘,所…...
Linux简介和环境搭建
Linux 介绍和环境搭建 1、发行版本 Linux 操作系统有多个主流发行版本,每个版本根据不同的目标、特点和使用场景为用户提供了不同的功能和体验。 Ubuntu • 特点:Ubuntu 是最为人熟知的 Linux 发行版之一,强调易用性和用户友好性ÿ…...
在移动端开发图表,uniapp+echarts,需要特殊处理,使用renderjs
1.首先要创建一个组件warning,用来装图表(我排除绿色那段代码为我的需求,不是必要代码) <template> <div class="task_container"> <div class="pop_body"> <div class="footer"> <warning…...
SpringBoot之LazyInitializationBeanFactoryPostProcessor类源码学习
源码分析 /**** author Andy Wilkinson* author Madhura Bhave* author Tyler Van Gorder* author Phillip Webb* since 2.2.0* see LazyInitializationExcludeFilter** 主要用于延迟初始化 Bean 的配置。它通过修改 BeanFactory 的配置来确保某些 Bean 在实际需要时才进行初始…...
United States of America三种表示
"United States of America", "United States", 和 "America" 都表示美国,但它们的使用场景和背景略有不同。以下是关于为什么这些名称可以合在一起表示美国的详细解释: 1. "United States of America" 全称&a…...
OpenCV基于均值漂移算法(pyrMeanShiftFiltering)的水彩画特效
1、均值漂移算法原理 pyrMeanShiftFiltering算法结合了均值迁移(Mean Shift)算法和图像金字塔(Image Pyramid)的概念,用于图像分割和平滑处理。以下是该算法的详细原理: 1.1 、均值迁移(Mean …...
【C++】拷贝构造函数与运算符重载
写在前面 拷贝构造函数、赋值运算符重载、取地址运算符都是属于类的默认成员函数! 默认成员函数是程序猿不显示声明定义,编译器会中生成。 在程序编写中,我们也经常使用拷贝的方式来获取到对应的值,例如整形变量拷贝int a 0; i…...
2024年开发语言热度排名
随着技术的不断发展和变化,编程语言的热度也在不断演变。2024年即将到来,我们有必要回顾和展望当前和未来的开发语言市场。本文将基于多个因素,包括行业需求、社区支持、流行度以及新兴趋势,对2024年的开发语言热度进行排名和分析…...
CryptoMamba:利用状态空间模型实现精确的比特币价格预测
“CryptoMamba: Leveraging State Space Models for Accurate Bitcoin Price Prediction” 论文地址:https://arxiv.org/pdf/2501.01010 Github地址:https://github.com/MShahabSepehri/CryptoMamba 摘要 预测比特币价格由于市场的高波动性和复杂的非线…...
MQTTX客户端使用
一、MQTT服务器( emqx )搭建 (1) 下载服务器MQTT Broker 从https://www.emqx.com/zh/downloads/broker/5.3.0/emqx-5.3.0-windows-amd64.zip下载MQTT Broker。 这里我使用的windows系统,下载对应版本工具:emqx-5.3.0-windows-a…...
网管平台(进阶篇):路由器的管理实践
在当今数字化时代,路由器作为网络连接的核心设备,其管理对于确保网络的稳定、高效和安全至关重要。本文旨在深入探讨路由器管理的重要性、基本设置步骤、高级功能配置以及日常维护,帮助读者构建一个高效且安全的网络环境。 一、路由器管理的…...
基于微信小程序的智能停车场管理系统设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
【Vue】父组件向子组件传递参数;子组件向父组件触发自定义事件
父组件向子组件传递参数 方法一:props 在 Vue 中,父组件向子组件传递数据主要通过props来实现,以下是具体的步骤: 父组件中传递数据 在父组件中,当需要调用子组件 AddSampleDialog 时,通过 v-bind 或其…...
搜广推校招面经七
抖音推荐算法 一、广告系统中的数据流处理方法,怎么避免延迟回流问题 延迟回流问题是指,实时系统(如广告点击预估)中,历史数据未及时更新或发生延迟,导致系统的实时预测偏离实际情况。避免延迟回流的方法有…...
Leetcode 518. 零钱兑换 II 动态规划
原题链接:Leetcode 518. 零钱兑换 II 可参考官解:零钱兑换 II 和这个解答:[Java/Python3/C]动态规划:拆分零钱兑换子问题(嵌套循环的秘密)【图解】 此题需要仔细想象和Leetcode 377. 组合总和 Ⅳ 动态规划…...
【EI 会议征稿】第四届材料工程与应用力学国际学术会议(ICMEAAE 2025)
2025 4th International Conference on Materials Engineering and Applied Mechanics 重要信息 大会官网:www.icmeaae.com 大会时间:2025年3月7-9日 大会地点:中国西安 截稿时间:2025年1月24日23:59 接受/拒稿通知…...
集合的线程安全
在多线程环境中,Java 的集合框架(Collection Framework)面临着线程安全的问题。当多个线程同时访问同一个集合对象时,可能会导致数据不一致、丢失更新或程序崩溃等严重问题。因此,在并发编程中确保集合操作的安全性至关…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
