CTF中的PHP特性函数(中)

本文介绍了PHP中的一些特性,如intval的数字转换和字符串截取功能,如何在CTF挑战中利用这些特性绕过限制。还讨论了strpos的字符串查找、sha1的弱哈希比较以及如何利用数组进行绕过。同时,文章提到了array_push在数组操作中的应用,以及如何利用类型转换的安全漏洞。

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

前言

上篇文章给大家带来了PHP中最基本的特性,不知道大家学习的怎样了,回顾上文,我们讲了MD5强弱碰撞以及正则匹配的绕过,总体来看还是很简单的,下面给大家带来新的PHP特性讲解,会稍微比上一篇难一些。

intval()

上一篇在最后时简单介绍了一下这个函数,我们看看官方是怎样定义的:

简单来说就是让输入的数字变成整数,下面我们举个例子:

echo intval(1145.14); // 1145
echo intval('114514');// 114514 

可以发现只对有小数点的数字起作用,正常的整数还是照常输出,那么它在CTF中是如何考察的呢,查看下面代码:

if($num==="1145"){die("no no no!");}if(intval($num,0)===1145){echo $flag;} 

要我们强类型传入的不能等于1145,但后面经过intval函数又要等于1145,这不和前面的矛盾了,我们要怎样做呢?

这里介绍一下intval的特性,如果我们在函数里传入字符串,那么该函数就会返回不是数字的字符之前的数字,也就是说我们传入:

sum=1145a 

intval就会判断我们传入的是1145,从而实现了绕过,还有另一种绕过方法:

当base为0时,intval会自动进行进制转换,我们可以传入1145的十六进制形式来绕过。

strpos()

根据手册可以看到,该函数以及与其类似的函数,作用都是匹配第一个或者最后一个字符,根据该函数特性,题目会经常围绕它作为一个限制头部的点,比如上面那题可能会增加限制:

 if(!strpos($num, "0")){die("no no no!"); 

因为八进制开头通常为0,检测到的话就不能通过进制转换来绕过了。

sha1

该函数的利用以及绕过方法类似于MD5函数,都是运用了PHP特性来做,这里简单看一下:

数组比较

类似于MD5,在SHA1里我们也可以使用数组绕过,具体可以看下面例子:

if(sha1($a)==sha1($b) && $a!=$b){	echo $flag;
} 

可以看到,也是一个弱比较,根据PHP特性sha1函数无法对数组进行处理,,于是我们传入数组来使结果为NULL:

a[]=1
b[]=2 

强类型

与MD5相同,当然也存在强类型比较,我们不能用数组来进行绕过了:

if(sha1($a)===sha1($b) && $a!=$b){	echo $flag;
} 

这里同样有类似于MD5函数的解决方法:

a=aaK1STf//0e7665852665575620768827115962402601
b=aaO8zKZF //0e89257456677279068558073954252716165 

array_push()

可以理解为向数组尾部插入参数,我们看看是如何考察的:

<?php
highlight_file(__FILE__);
$allow = array();
for ($i=36; $i < 0x36d; $i++) { array_push($allow, rand(1,$i));
}
if(isset($_GET['n']) && in_array($_GET['n'], $allow)){file_put_contents($_GET['n'], $_POST['content']);
}
?> 

可以看到题目先向数组里插入随机数,in_array()是搜索数组中是否存在指定的值,根据它的语法:

type会判断类型是否匹配,这就是我们利用的点,因为数组里数据为int型,根据PHP特性比较后字符串会转成int型,也就是说我们传入1.php也是没有问题的,后面有个写入文件操作,正好可以设置一句话木马连接后门,或者进行命令执行:

get:n=1.php
post: content=<?=`tac f*`; 

结语

今天这篇文章可能有的地方不是很好理解,但总体来说还是很简单的,PHP特性很多以至于只能挑出一些著名的来说,喜欢本文的小伙伴希望可以一键三连支持一下。

<think>嗯,用户想了解CTF比赛中与PHP弱类型相关的安全问题及利用方法。从对话历史看,用户之前已经了解过PHP弱类型的基本概念和隐患,现在需要更具体的CTF应用场景。用户引用了5个站内资料,其中引用[2]和[3]特别相关:引用[2]展示了PHP反序列化漏洞的实例,引用[3]则提到in_array()函数的类型转换问题。其他引用虽然涉及PHP安全,但和弱类型关联较弱。 需要重点覆盖CTF中三类典型弱类型漏洞: 1.松散比较导致的验证绕过(如md5碰撞、0e开头的哈希值比较) 2. in_array()和array_search()函数的自动类型转换问题3.反序列化中类型混淆引发的对象注入用户可能正在准备CTF比赛,需要实战案例。应该给出具体漏洞原理和payload构造方法,比如如何利用"0e123"被当作科学计数法0的特性绕过哈希验证。引用[3]提到的SQL注入案例也很典型——当in_array()遇到字符串数字时,会将其转为数字比较,导致"1 unionselect"通过检查。 考虑到CTF的解题特性,还要强调防御方法。比如严格比较运算符(===)的使用、类型声明、intval()强制转换等。可以结合引用[3]的SQL注入案例,说明如何用全等号避免漏洞。 最后需要提醒用户,CTF中这类漏洞常出现在登录验证、权限检查、反序列化入口等位置。payload构造时要特别注意PHP的类型转换规则,比如字符串转数字时截取到第一个非数字字符的特性。</think>在CTF比赛中,PHP弱类型漏洞的利用主要集中在**类型自动转换**和**松散比较**导致的逻辑绕过。以下是关键漏洞类型及利用方法: --- ### 一、哈希比较绕过(经典0e漏洞) **原理**: PHP在松散比较(`==`)时会将`0e`开头的字符串解析为科学计数法的0(即`0 × 10^n`),导致不同内容的哈希值被误判相等。 **利用场景**: - 密码哈希验证、身份令牌校验等场景使用`==`而非`===` **Payload**: ```php // 已知目标哈希值以0e开头(如md5('240610708')=0e462097431906509019562988736854) $input = "0e1137126905"; // 任意0e开头的哈希字符串 if ($input == $_POST['password_hash']) { // 松散比较 bypass_login(); } ``` --- ### 二、`in_array()`/`array_search()`类型混淆 **原理**(引用[3]): `in_array($needle, $haystack)`默认松散比较(第三个参数为`false`),字符串数字如`"1abc"`会被强制转为整数`1`。 **利用场景**: - SQL注入绕过数字白名单检查 ```php // 漏洞代码示例 $allow_types = array(1, 2, 3, 4); if (in_array($_GET['typeid'], $allow_types)) { // 未启用严格模式 $sql = "SELECT * FROM table WHERE typeid=" . $_GET['typeid']; } ``` **Payload**: ``` ?typeid=1%20union%20select%201,2,database()-- // 实际传入字符串"1 union..."被转为整数1,通过检查 ``` --- ### 三、反序列化中的类型混淆(引用[2]) **原理**: 私有属性在序列化后格式为`%00类名%00属性名`,若反序列化时未严格校验类型,可能通过修改序列化字符串注入非法值。 **利用步骤**: 1. 构造恶意序列化数据: ```php class User { private $is_admin = false; } $payload = serialize(new User()); // 输出: O:4:"User":1:{s:10:"Useris_admin";b:0;} ``` 2. 修改属性值为`true`: ```diff - s:10:"Useris_admin";b:0; + s:10:"Useris_admin";b:1; // 将false改为true ``` 3. 触发反序列化后,`$is_admin`变为`true`,获得管理员权限。 --- ### 四、数字与字符串比较漏洞 **原理**: 字符串与数字比较时,字符串会被转为数字(从首位开始到第一个非数字字符截止)。 **Payload**: ```php // 如验证码校验 if ($_POST['captcha'] == 1234) { // 松散比较 grant_access(); } // 输入"1234abcd"会被转为1234,通过验证 ``` --- ### 五、防御措施 1. **严格比较**:始终使用`===`和`!==` 2. **类型声明**:PHP 7+ 使用类型声明 ```php function check(int $typeid) {...} // 强制类型 ``` 3. **启用严格模式**: ```php declare(strict_types=1); // 文件顶部声明 ``` 4. **安全函数配置**: ```php in_array($needle, $haystack, true); // 启用严格模式 ``` 5. **输入过滤**: ```php $id = (int)$_GET['id']; // 强制类型转换 ``` --- ### 六、CTF实战技巧 1. **定位漏洞点**: - 搜索代码中的`==`、`in_array`、`array_search` - 查找未过滤的`unserialize()`输入点 2. **构造Payload**: - 哈希绕过:尝试`0e`开头的已知碰撞值(如`240610708`) - 数字混淆:在数字后拼接字符(如`123abc`) - 序列化攻击:修改私有属性类型或值 > 通过理解PHP类型转换规则(如`"abc"==0`、`"123abc"==123`),可精准构造绕过Payload[^3][^2]。 --- **相关问题**: 1. CTF中如何利用PHP弱类型绕过文件包含漏洞的过滤? 2. 在PHP反序列化漏洞中,弱类型如何影响`__wakeup()`方法的执行逻辑? 3. 如何通过弱类型特性绕过WAF的数字型SQL注入防护? 4. `switch`语句中的弱类型比较可能导致哪些安全问题?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值