php网站经常被上传恶意脚本文件,通过文件修改时间来寻找webshll可以快速排查后门文件,以下是通过定时检测网站文件修改时间来处理攻击者上传shell脚本的一种方式
注意:
此脚本需在cli模式下运行
如:此脚本在/www目录下的文件checkfile.php中
创建文件夹 /www/isolation
/www/isolation/
添加守护进程,启动命令如下
php checkfile.php
程序会将检测到的文件备份到指定文件夹后删除,并生成日志文件记录检测到的时间和文件路径
脚本代码如下:
<?php
/*
* @Author: lhpanda 1147675304@qq.com
* @Date: 2023-08-12 21:53:35
* @LastEditors: lhpanda 1147675304@qq.com
* @LastEditTime: 2023-08-15 11:31:58
* @FilePath: checkfile.php
* @Description: 检查指定目录及其子目录下指定时间之后创建的指定类型的文件
* Copyright (c) 2023 by lhpanda email: 1147675304@qq.com, All Rights Reserved.
*/
// 检查的目录
$path = [
"/www/wwwroot/xxx/",
"/www/wwwroot/ccc/",
"/www/wwwroot/yyy/",
];
$nocheckpath = [
"/www/wwwroot/xxx/s",
"/www/wwwroot/ccc/s",
"/www/wwwroot/yyy/s"
];
// 检查的文件类型,多种类型用数组
// $type = "*.php";
$type = ["*.php", "*.js"];
// 开始时间
$time = time();
// 是否删除检测到的文件
$isdel = true;
// 日志
$logfile = "/www/checkfile.log";
// 文件隔离目录
$isolationpath = "/www/isolation/";
// 有威胁检测间隔时间
$warsleeptime = 10;
$sleeptime = 10 * 60;
// 无危险检测间隔时间
/**
* @description: 文件搜索
* @param {**} $path 路径
* @param {**} $type 文件类型
* @param {**} $files 储存搜索的结果
* @param {**} $nocheckpath 排除的目录
* @return {**} void
*/
function myreadfile(string $path, array $type, array &$files, array $nocheckpath): void
{
//如果是目录则继续
if (is_dir($path)) {
foreach ($type as $v) {
$files[$path . $v] = glob($path . $v);
}
//扫描一个文件夹内的所有文件夹和文件并返回数组
$p = scandir($path);
foreach ($p as $val) {
//排除目录中的.和..
if ($val != "." && $val != "..") {
//如果是目录并且不是排除的目录则递归子目录,继续操作
if (is_dir($path . $val) && !in_array($path . $val, $nocheckpath)) {
myreadfile($path . $val . '/', $type, $files, $nocheckpath);
}
}
}
}
}
/**
* @description: 文件夹不存在则创建
* @param {**} $dir 路径
* @return {**} void
*/
function folder(string $dir)
{
if (!file_exists($dir)) {
mkdir($dir, 0757, true);
}
}
while (1) {
// 开始扫描的时间
$checktime = time();
$warn = false;
// 存放检测到的文件
$files = [];
foreach ($path as $v) {
myreadfile($v, $type, $files, $nocheckpath);
}
$endtime = time();
// 打开日志文件
$file = fopen($logfile, "a");
// 写入分隔符
fwrite($file, "\r\n======扫描时间:" . date("Y-m-d H:i:s", $checktime) . "======耗时:" . ($endtime - $checktime) . "秒======共扫描到" . count($files) . "个文件======\r\n");
foreach ($files as $val) {
foreach ($val as $v) {
if (filemtime($v) > $time) {
// 只操作文件
if (!is_dir($v)) {
$warn = true;
$content = "检测到新文件" . $v;
folder($isolationpath . $checktime);
// 文件备份
if (copy($v, $isolationpath . $checktime . "/" . basename($v))) {
$content .= "-----------成功备份";
if ($isdel) {
// 删除文件
if (unlink($v)) {
$content .= "-----------成功删除原文件";
} else {
$content .= "-----------原文件删除失败";
}
}
} else {
$content .= "未能成功备份";
}
// 写入日志
fwrite($file, $content . "\r\n");
}
}
}
}
// 关闭日志文件
fclose($file);
// 有威胁时
if ($warn) {
sleep($warsleeptime);
}
// 无威胁时
else {
sleep($sleeptime);
}
}