PHP作为跨平台语言,其内置函数在两个系统上名称虽同,但底层调用和表现差异巨大。理解这些差异是安全开发和高阶漏洞利用的关键。
🪟 一、 Windows 环境下的 PHP 系统交互
1. 核心特征
- 底层 Shell :
cmd.exe(命令提示符)或powershell.exe。 - 路径分隔符 :
\(反斜杠),但 PHP 内部也兼容/。 - 权限模型 :PHP 进程(如 IIS 的应用程序池)常以高权限账户(如
NT AUTHORITY\SYSTEM)运行,权限边界模糊,极易掩盖权限问题。 - 命令语法:遵循 DOS/CMD 语法,命令不区分大小写。
2. 常用命令与代码示例
| 功能 | Linux 命令 | Windows 命令 | PHP 代码示例 (Windows) |
|---|---|---|---|
| 列出目录 | ls |
dir |
exec('dir', $output); |
| 查看文件内容 | cat |
type |
echo shell_exec('type C:\boot.ini'); |
| 查看网络配置 | ifconfig |
ipconfig |
system('ipconfig /all'); |
| 查看当前用户 | whoami |
whoami |
echo exec('whoami'); |
| 进程列表 | ps aux |
tasklist |
passthru('tasklist'); |
| 新建目录 | mkdir |
mkdir / md |
system('mkdir C:\test'); |
| 删除文件 | rm |
del |
exec('del C:\tmp\log.txt'); |
3. Windows 下的特殊函数与技巧
-
启动程序 :使用
start命令可以启动新窗口运行程序,不阻塞当前 PHP 脚本。phpexec('start calc.exe'); // 打开计算器 exec('start /B notepad.exe'); // 后台启动记事本 -
COM 对象:Windows 独有,可调用系统组件,功能极其强大。
php// 调用 WScript.Shell 执行命令 $wsh = new COM('WScript.Shell'); $exec = $wsh->exec('cmd /c dir'); echo $exec->StdOut->ReadAll();
4. Windows 特有危险函数与注意点
COM类 :极度危险。允许实例化 Windows 组件,不仅能执行命令,还能操作注册表、文件系统、WMI 等,是 Windows 下权限维持和提权的利器。exec()/system()等的 Shell 调用 :在 Windows 下,PHP 会隐式调用cmd /c来执行命令。这意味着传入的字符串会经过cmd.exe解析,Windows 的转义符是^而非\,这导致很多在 Linux 下有效的转义方式(如\')在 Windows 下失效,易引发命令注入。proc_open():在 Windows 下,若需绕过cmd.exe直接启动程序,需设置bypass_shell选项,否则进程默认由 cmd 包装。
🐧 二、 Linux 环境下的 PHP 系统交互
1. 核心特征
- 底层 Shell :
/bin/bash或/bin/sh。 - 路径分隔符 :
/(正斜杠)。 - 权限模型 :严格的多用户权限模型。PHP 进程通常以低权限用户(如
www-data,nginx,apache)运行,权限限制极其严格 ,文件权限(chmod/chown)是常见故障点。 - 命令语法:遵循 Bash 语法,命令严格区分大小写。
2. 常用命令与代码示例
| 功能 | Windows 命令 | Linux 命令 | PHP 代码示例 (Linux) |
|---|---|---|---|
| 列出目录 | dir |
ls -la |
exec('ls -la', $output); |
| 查看文件内容 | type |
cat |
echo file_get_contents('/etc/passwd'); |
| 查看网络配置 | ipconfig |
ifconfig / ip a |
system('ifconfig'); |
| 查看当前用户 | whoami |
id / whoami |
echo exec('id'); |
| 进程列表 | tasklist |
ps aux |
passthru('ps aux'); |
| 查找文件 | dir /s |
find / -name "*.php" |
exec('find / -name "*.php"', $out); |
3. Linux 下的特殊函数与技巧
-
POSIX 扩展函数 :Linux 独有,用于获取和操作进程、用户、组信息。
phpecho posix_getuid(); // 获取当前进程 UID echo posix_getpwuid(posix_geteuid())['name']; // 获取用户名 -
pcntl扩展 :进程控制扩展,可创建子进程、处理信号。默认不启用,启用后非常危险 。phppcntl_exec('/bin/bash', ['-c', 'id']); // 执行命令
4. Linux 特有危险函数与注意点
pcntl_exec():极度危险 。直接在当前进程空间执行指定程序,不经过 shell,可绕过一些基于cmd.exe的检测规则,是高级 Webshell 常用的功能。posix_*系列函数 :极度危险 。如posix_kill()可发送信号终止进程,posix_setuid()可尝试修改进程运行用户(提权尝试)。生产环境强烈建议禁用。symlink():软链接函数。在 Linux 下,利用竞争条件或目录遍历,可绕过open_basedir限制读取敏感文件。putenv():危险 。虽然本身不执行命令,但在特定 Linux 环境下(如与mail()函数配合),可通过修改LD_PRELOAD环境变量劫持进程,实现无disable_functions限制的命令执行(经典的 LD_PRELOAD 提权/绕过技术)。
☠️ 三、 跨平台通用危险函数深度解析
无论在哪个系统,以下函数都是安全审计和攻击者首选的目标,必须极度谨慎使用。
| 函数/类别 | 危险等级 | 行为描述 & 跨平台差异 | 安全建议 |
|---|---|---|---|
system() |
🔴 高 | 执行命令并直接输出 结果。Windows 下调用 cmd /c,Linux 下调用 /bin/sh -c。 |
禁用或严格白名单 |
exec() |
🔴 高 | 执行命令,返回最后一行,可选数组获取全部输出。 | 禁用或严格白名单 |
shell_exec() |
🔴 高 | 执行命令,返回完整输出字符串。 | 禁用或严格白名单 |
passthru() |
🔴 高 | 执行命令,原始二进制流直接输出。常用于下载恶意程序。 | 禁用 |
| 反引号 (`````) | 🔴 高 | shell_exec() 的语法糖,极易被忽略。echo \whoami`;` |
禁用 shell_exec 即可禁用此功能 |
eval() |
🟠 极高 | 代码执行,不是命令执行。将字符串作为 PHP 代码执行,是 Webshell 的核心。 | 绝对禁止 |
assert() |
🟠 极高 | 原为断言,在 PHP 7.2 前可将字符串作为 PHP 代码执行,是 eval 的常见替代品。 |
绝对禁止 |
preg_replace() |
🟡 中 | /e 修饰符(PHP < 7.0)会将替换字符串作为 PHP 代码执行。 |
禁用 /e 修饰符,升级 PHP 版本 |
create_function() |
🟡 中 | 创建匿名函数,内部使用 eval,易被利用。 |
禁用,使用闭包替代 |
call_user_func() call_user_func_array() |
🟡 中 | 回调函数,若回调名和参数可控,可间接调用危险函数(如 system)。 |
严格校验回调函数名 |
🛡️ 四、 跨平台开发安全实践总结
- 路径处理 :永远使用
DIRECTORY_SEPARATOR常量或统一使用/(PHP 在 Windows 下兼容)。 - 判断系统 :使用
PHP_OS_FAMILY(PHP 7.2+) 或DIRECTORY_SEPARATOR判断系统,执行不同代码。 - 输入过滤 :绝对不要 将
$_GET/$_POST直接传入危险函数。使用escapeshellarg()和escapeshellcmd(),但需注意 Windows 下的转义符差异。 - 最小权限 :
- Linux :确保
www-data等用户只有必要目录的读写权限。 - Windows :务必 将 IIS/Apache 服务账户从
SYSTEM降权为普通用户。
- Linux :确保
- 函数禁用 :在生产环境
php.ini中,通过disable_functions禁用上述所有 🔴 和 🟠 级别的危险函数。 - 避免调用系统命令 :能用 PHP 原生函数(如
scandir,unlink,file_get_contents)完成的,绝不调用系统命令。
理解这些差异和危险函数的底层逻辑,是写出健壮跨平台代码、以及进行高级安全攻防的基础。