本文目录导读:

在 CTF(Capture The Flag,夺旗赛)中,PHP 通常出现在 Web 安全 类别中,PHP 因其语法灵活、函数丰富,且历史包袱重(弱类型、魔术方法等),成为了 Web 题目中出题率最高的语言。
如果你想在 CTF 中玩转 PHP,需要掌握以下几个核心维度的知识和技巧:
基础篇:PHP 弱类型与类型混淆
这是 PHP 独有的“坑”,也是最常见的考点。
- 松散比较()与严格比较()
- 利用 的漏洞:
"0e123" == "0e456"均为科学计数法,比较时按 0 处理,结果为真。 - 数值与字符串:
123 == "123abc"在 PHP 7 之前为真(字符串转为数字)。
- 利用 的漏洞:
- 哈希比较绕过(Magic Hashes)
- 寻找
0e开头的字符串,使其 MD5 或 SHA1 值为0e开头,从而绕过md5($a) == md5($b)的比较(QNKCDZO的 MD5 是0e930933...)。
- 寻找
- 数组与布尔值
in_array($input, [1, 2, 3])$input是0或"abc",因为松散比较,可能返回 true。- 如果函数需要字符串,传入数组会导致
TypeError或返回NULL,可利用sha1($_GET['a'])接收数组返回 NULL 绕过判断。
进阶篇:PHP 反序列化漏洞
这是 CTF 中的重头戏(PHP Pop Chain,属性链)。
- 核心魔术方法:
__construct,__destruct,__toString,__call,__get,__set,__isset,__unset,__sleep,__wakeup,__invoke。 - 常见考点:
- CVE-2016-7124:当序列化字符串中表示对象属性个数的值大于真实的属性个数时,会跳过
__wakeup()执行。 - POP 链构造:不直接找危险函数(如
eval,system),而是通过多个类的魔术方法拼接出一条调用链,最终触发危险函数。 - Phar 反序列化:利用
phar://协议,在文件操作函数(如file_get_contents,include)上触发反序列化,不需要unserialize()函数。
- CVE-2016-7124:当序列化字符串中表示对象属性个数的值大于真实的属性个数时,会跳过
- 技巧:使用
phpggc工具直接生成针对主流框架(Laravel, ThinkPHP 等)的反序列化 Payload。
核心篇:PHP 代码审计与变量覆盖
CTF 经常给出一段源码,要求利用代码逻辑漏洞。
- 变量覆盖(Variable Override)
extract($_GET)或parse_str()函数可以直接覆盖已有的变量。$$key = $value的动态变量名覆盖。
- 代码执行与命令执行
eval(),assert(),preg_replace()配合/e修正符(PHP 7 已移除,老题见),call_user_func(),array_map()等函数。
- 文件包含(LFI/RFI)
include $_GET['page'];配合 PHP 伪协议 读取源码或执行命令:php://filter/convert.base64-encode/resource=flag.php(读取源码)data://text/plain,<?php phpinfo();?>(执行代码,需 allow_url_include)php://input(POST 数据当代码执行)
- 禁用函数绕过
disable_functions禁用了system,exec等,可以尝试:- 使用
pcntl_exec()(如果存在)。 - 利用
LD_PRELOAD环境变量 +putenv()+mail()/error_log()加载恶意.so文件。 - 利用
FFI(PHP 7.4+ 拓展)直接调用 C 函数。
- 使用
进阶篇:PHP 特性与配置绕过
md5()函数数组绕过$_GET['a']传数组,md5($_GET['a'])会报错返回NULL,如果判断是if(md5($a) === md5($b)),传两个不同的数组即可绕过。
is_numeric()绕过is_numeric("1e3")为 true。- 将 , , 等字符配合使用绕过弱类型判断。
- 结尾绕过(%00 截断)
- 老版本 PHP 5.3 之前,
include("flag.php%00.jpg")会截断%00后的内容。
- 老版本 PHP 5.3 之前,
- 空格与换行符
- 在某些正则表达式检测中,
\n(换行符)可能导致正则匹配失效( 修饰符的行为)。 - 利用
%0a等 URL 解码漏洞绕过后端 WAF。
- 在某些正则表达式检测中,
实操篇:CTF 中的解题步骤
- 信息收集:
- 查看响应头(
X-Powered-By),尝试访问robots.txt,www.zip,index.php.bak,.git泄露。
- 查看响应头(
- 源码获取:
- 如果题目是 PHP,优先考虑备份文件(
.bak,.swp,.php~)。 - 利用
phpinfo()查看配置(disable_functions,open_basedir,allow_url_include)。
- 如果题目是 PHP,优先考虑备份文件(
- 参数爆破:
- 使用
dirsearch或ffuf扫描目录。 - 使用
burpsuite的Intruder模块爆破变量名(如?cmd=,?file=,?code=)。
- 使用
- 利用与反弹:
- 根据审计结果构造 Payload。
- 拿权限(GetShell)后:虽然拿到了 shell,但如果权限不足,需要提权。
- 读文件:如果只有
phpinfo(),尝试读取/proc/self/environ,/proc/self/cmdline获取环境变量。 - 中间人/代理:利用 PHP 的
mail()或error_log()配合LD_PRELOAD绕过禁用函数(这是最经典的提权手法)。
常用工具与资源
- Burp Suite:抓包改包必备。
- CyberChef:加解密、编码转换。
- PHPGGC:生成主流框架反序列化字符串。
- 蚁剑/哥斯拉:用于连接 WebShell,支持绕过禁用函数插件。
- 本地环境:使用
docker搭建 PHP 环境,推荐使用php:7.0-apache或php:5.6-apache等老版本容器,方便复现各种老漏洞。
给新手的建议
- 从简单题开始:找一套经典的 PHP 基础题(如攻防世界、BUUCTF 的 web 入门题),先学会用
php://filter读源码。 - 把笔用起来:PHP 的 Pop 链(属性链)很绕,画思维导图或写代码打印,一步步调试。
- 跟着 Writeup 学:看到一个不懂的 Payload,第一时间拿到本地环境
docker跑一遍,打断点看变量值。 - 关注最新 CVE:老版本的 PHP 漏洞(如
CVE-2019-11043)在 CTF 中偶尔也会出现,值得保持关注。
需要我具体演示某一种题型的解题过程吗?比如一个典型的 “弱类型比较绕过” 或 “PHP反序列化” 的代码示例?
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播