CTF Web的数组巧用

发布于:2025-07-04 ⋅ 阅读:(22) ⋅ 点赞:(0)

PHP数组绕过intval和preg_match的CTF技巧

原题目

<?php
include("flag.php"); // 引入flag文件,flag变量在这里定义
show_source("index.php"); // 显示index.php文件的源码(方便选手查看)

// 判断是否通过GET方式传入了pangoulin参数
if(isset($_GET['pangoulin'])){
    $pangoulin = $_GET['pangoulin']; // 获取pangoulin参数的值

    // 检查pangoulin中是否包含数字(0-9),如果有则终止程序并输出提示
    if(preg_match("/[0-9]/", $pangoulin)){
        die("no no no!"); // 包含数字则直接退出
    }

    // 判断pangoulin转换为整数后是否为真(非0),如果为真则输出flag
    if(intval($pangoulin)){
        echo $flag; // 满足条件,输出flag
    }
}

参数传递与数字过滤 :题目要求通过GET传递pangoulin参数,但参数值不能包含数字字符(0-9),否则会被preg_match拦截并终止脚本。

intval判断逻辑 intval($pangoulin)需要返回非零值才能输出flag。常规字符串(如"abc")经intval转换结果为0,无法满足条件。

数组参数在PHP中的独特特性

使用数组形式传递参数(如?pangoulin[]=value)时,PHP会将$_GET['pangoulin']自动解析为数组类型。这种特性在表单处理或API参数传递中较为常见。

数组参数的强制转换问题

调用intval()对数组参数进行强制转换时,结果会固定返回1。这是PHP的类型转换机制决定的,数组转换为整数时总是返回1(非空数组)或0(空数组)。

// 示例:intval对数组的转换
$val = intval(['a', 'b']); // 结果为1
$emptyVal = intval([]);     // 结果为0

preg_match对数组参数的响应

preg_match()函数接收到数组参数时,PHP会生成Warning级别错误,但脚本会继续执行。这与函数预期接收字符串参数的行为不符,但不会像Fatal Error那样终止程序。

// 示例:preg_match对数组的响应
preg_match('/\d+/', ['a', 'b']); 
// 输出:Warning: preg_match() expects parameter 2 to be string, array given

安全建议

处理用户输入时应显式检查变量类型,避免因自动类型转换导致逻辑漏洞。使用is_array()filter_input()函数验证参数类型:

// 类型检查示例
if (is_array($_GET['pangoulin'])) {
    // 处理数组逻辑
}

// 使用过滤器验证
$value = filter_input(INPUT_GET, 'pangoulin', FILTER_DEFAULT, FILTER_REQUIRE_SCALAR);
if ($value === null) {
    // 非标量参数处理
}

实战利用方法 构造请求URL为:?pangoulin[]=

  • 参数变为空数组
  • 绕过数字检测
  • intval返回1触发flag输出

题目流程图

技术原理总结

  • PHP数组传参需在参数名后加[]
  • 类型转换特性:intval(array)→1
  • preg_match对非字符串参数的容错处理
// 关键代码逻辑示例
if(isset($_GET['pangoulin'])){
    $param = $_GET['pangoulin'];
    if(preg_match("/[0-9]/", $param)) die("Blocked");
    if(intval($param)) echo $flag;
}

典型应用场景 该技巧适用于需要同时满足

  • 参数值不能包含特定字符
  • 需要参数经类型转换后为真值 的CTF题目突破场景。