松散比较(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)面临着线程安全的问题。当多个线程同时访问同一个集合对象时,可能会导致数据不一致、丢失更新或程序崩溃等严重问题。因此,在并发编程中确保集合操作的安全性至关…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
