PHP弱类型--strcmp()

本文介绍了一个名为Passcheck的PHP程序中的弱类型安全问题。该程序通过strcmp函数验证用户输入的密码是否正确,利用PHP中特殊的弱类型特性,可以通过传入特定格式的数组绕过密码检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pass check
300

核心源码

<?php
$pass=@$_POST['pass'];
$pass1=***********;//被隐藏起来的密码
if(isset($pass))
{
if(@!strcmp($pass,$pass1)){
echo "flag:nctf{*}";
}else{
echo "the pass is wrong!";
}
}else{
echo "please input pass!";
}
?>

题目链接:tip:strcmp(array,string)=null=0

首先呢,这个题目因为题放在内网,没有vpn所以没法做,但是提示都这么明显了,就是php的strcmp函数了。传入一个array就好了。

ps:

strcmp()函数在PHP官方手册中的描述是int strcmp ( string str1,string str2 ),需要给strcmp()传递2个string类型的参数。如果str1小于str2,返回-1,相等返回0,否则返回1。strcmp函数比较字符串的本质是将两个变量转换为ascii,然后进行减法运算,然后根据运算结果来决定返回值。
如果传入给出strcmp()的参数是数字呢?

$array=[1,2,3];
var_dump(strcmp($array,'123')); //null,在某种意义上null也就是相当于false

资料链接:PHP弱类型安全问题总结

另附他人已做贴出的writeup
这里写图片描述

<think>嗯,用户想了解CTF竞赛中PHP弱类型比较的原理与应用,包括原理、示例和漏洞利用。首先,我需要回顾一下PHP弱类型的基本概念。PHP弱类型语言,变量类型由上下文决定,比较时可能自动转换类型,导致一些非预期的结果。这在CTF题目中常被用来设计漏洞点。 根据引用[1],PHP中的==和===的区别是关键。==是松散比较,只比较值,不比较类型,而===严格比较值和类型。例如,0 == "0"为真,但0 === "0"为假。接下来需要找一些例子,比如字符串和数字比较时的情况,比如"123a"会被转换成123,而无法转换的字符串如"abc"会被转为0。这可能引发漏洞,比如md5('240610708')的哈希值以0e开头,会被视为科学计数法的0,导致两个不同的字符串哈希在==比较下相等。 另外,引用[2]提到strcmp函数的漏洞,当比较字符串和数组时,PHP5.3之前会返回0,导致绕过验证。例如,提交password[]=xxx,$_POST['password']变成数组,strcmp返回0,从而通过检查。虽然新版本修复了,但旧系统可能仍受影响。 还要考虑其他函数,如in_array和switch语句,它们可能因为类型转换导致问题。例如,in_array默认不严格检查类型,0可能匹配到第一个元素为字符串的情况。switch也会将参数转换为整数,导致匹配错误。 漏洞利用方面,需要结合CTF题目中的常见场景,比如登录验证、哈希比较等。例如,通过构造特定输入绕过条件判断,或者利用数组绕过strcmp检查。此外,md5碰撞也是一个常见点,比如0e开头的哈希值被当作0处理。 现在需要组织这些知识点,分成原理、示例和漏洞利用三个部分。确保每个部分都有具体的例子,并引用相关的参考文献。同时,生成相关问题时要围绕PHP弱类型比较的其他函数、防御方法、其他CTF中的应用等。</think>### CTFPHP弱类型比较的原理与应用 #### 一、原理 PHP弱类型比较的核心在于其松散类型系统**允许不同类型变量在比较时自动转换**。例如: - **松散比较(`==`)**:仅比较值的等价性,忽略类型差异[^1] - **严格比较(`===`)**:同时检查值和类型是否一致 当比较**字符串与数字**时,PHP会将字符串转换为数字: - 字符串`"123a"`转换为`123` - 字符串`"abc"`转换为`0` 特殊比较场景: $$ \begin{cases} "0e12345" == "0e67890" \quad (\text{科学计数法视为0}) \\ "123" == 123 \quad (\text{字符串转数字}) \\ null == false == 0 \quad (\text{空值等价性}) \end{cases} $$ #### 二、典型示例 1. **哈希碰撞绕过** ```php if ($_GET['a'] != $_GET['b'] && md5($_GET['a']) == md5($_GET['b'])) { echo "Flag: CTF{weak_type_123}"; } ``` - 构造输入`a=240610708`和`b=QNKCDZO`,其MD5值均为`0e`开头,会被判定为相等[^1] 2. **数组绕过`strcmp`** ```php if (strcmp($_POST['password'], $real_pwd) == 0) { // 验证通过 } ``` - 提交`password[]=123`,`strcmp`遇到数组参数返回`0`,触发条件成立[^2] 3. **`in_array`类型混淆** ```php $allow_types = ["jpg", "png"]; if (in_array($_GET['type'], $allow_types)) { // 允许操作 } ``` - 输入`type=0`可匹配数组中的字符串`"jpg"`(`"jpg"`转换为数字`0`) #### 三、漏洞利用方法 1. **科学计数法利用** - 构造`0e`开头的字符串实现哈希碰撞 2. **非字符串参数注入** - 向需要字符串的参数提交数组(如`$_POST['key']=array()`) 3. **空值等价性** - 利用`null == 0 == false`绕过逻辑判断 #### 四、防御措施 1. 使用`===`替代`==`进行严格比较 2. 对用户输入强制类型转换:`(string)$_POST['input']` 3. 检查变量类型:`is_string()`、`is_numeric()`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值