多数网站都有富文本编辑器,一些较低版本的编辑器自带的止传功能,而这些上传接口很可能带有考虑不周的情况,很有可能会被黑客利用。针对这个情况,要么替换上传文件,要么升级这个编辑器到最新版本。
如果以上都没有效果,建议手动写一个小程序,逐个文件扫描,看看文件中有没有明显的php/asp/asp.net后门代码。下面以 c#为例,展示如何通过正则匹配,查找文件中是不是可能含有可执行后门代码:
using System.Text;
namespace 代码检测
{
/// <summary>
/// 恶意代码检测工具类(支持 PHP/ASP/.NET 可疑代码检测,实例化时指定特征码文件路径)
/// </summary>
public class MaliciousCodeDetector
{
#region php特征码
/// <summary>
/// 预编译正则:匹配PHP代码块内的高危恶意特征
/// 核心规则:仅检测<?/<?php开头的代码块,兼容无?>结尾的场景
/// </summary>
private static string[] phpRegKeys = new[] {
// 1. 系统命令执行类(黑客操控服务器核心)
@"exec\s*\(",
@"system\s*\(",
@"shell_exec\s*\(",
@"passthru\s*\(",
@"`(?:cmd|powershell|whoami|ls|dir|rm|rmdir|cp|mv|echo|cat|bash|sh|python|php)\s*[a-zA-Z0-9_\-\/\\=|&:;,.]{0,50}`", // 反引号执行命令(仅匹配单行,减少误判)
@"proc_open\s*\(",
@"popen\s*\(",
@"pcntl_exec\s*\(",
// 2. 代码执行类(动态执行恶意代码)
@"eval\s*\(",
@"assert\s*\(",
@"create_function\s*\(",
@"call_user_func\s*\(",
@"call_user_func_array\s*\(",
@"array_map\s*\(",
@"preg_replace\s*\/.*e.*\/",
@"mb_ereg_replace\s*\/.*e.*\/",
@"uasort\s*\(",
@"uksort\s*\(",
@"array_filter\s*\(.*\$",
@"phpinfo\s*\(",
// 3. 文件操作类(篡改/上传木马)
@"file_put_contents\s*\(",
@"fwrite\s*\(",
@"move_uploaded_file\s*\(.*\.php",
@"chmod\s*\(",
@"unlink\s*\(",
@"copy\s*\(",
@"glob\s*\(",
// 4. 绕过/隐蔽类(躲避检测)
@"base64_decode\s*\(",
@"urldecode\s*\(",
@"rawurldecode\s*\(",
@"\$_POST\[[^\]]+\]",
@"\$_GET\[[^\]]+\]",
@"\$_COOKIE\[[^\]]+\]",
@"\$_FILES\[[^\]]+\]",
@"php:\/\/input",
@"data:\/\/",
//@"@\w+\s*\(",
@"die\s*\(",
@"exit\s*\(",
// 5. 进阶执行/绕过(高阶后门)
@"extract\s*\(\$_(POST|GET|REQUEST)",
@"parse_str\s*\(\$_(SERVER|POST|GET)",
@"register_shutdown_function\s*\(",
//@"\(\$[a-z]+\)\(\)",
@"function\(\)\{\}\(\)",
@"include\s*\(\$_(GET|POST|REQUEST)",
@"require\s*\(\$_(GET|POST|REQUEST)",
@"auto_prepend_file",
@"auto_append_file",
// 6. 提权/隐蔽通信(远控/窃取数据)
@"posix_getuid\s*\(",
@"posix_setuid\s*\(",
@"chroot\s*\(",
@"putenv\s*\(",
@"socket_create\s*\(",
@"socket_connect\s*\(",
@"fsockopen\s*\(",
@"curl_exec\s*\(.*http",
@"error_log\s*\(.*base64",
@"\$_SESSION\[[^\]]+\]\s*=",
// 7. 变形/混淆(躲避静态检测)
@"chr\(\d+\)\.chr\(\d+",
@"base64_decode\(base64_decode",
@"gzuncompress\(base64_decode",
@"e\/\*.*\*\/v\/\*.*\*\/a\/\*.*\*\/l",
//@"\\x[0-9a-f]{2}",
//@"\\u00[3-7][0-9a-f]",
// 8. 文件/路径绕过(遍历/上传漏洞)
@"php:\/\/filter",
@"zip:\/\/",
@"phar:\/\/",
//@"\.\.\/",//jpg文件中也可能有这样的代码
//@"%00",
@"(?:file_put_contents|fopen)\s*\(\s*[""'].*?\.php\\0[^""']*?[""']", // 文件写入+NULL截断 @"`(?:echo|cat|cp)\s*[^`]*?\.php\\0[^`]*?>`", // 反引号命令+NULL截断
// 9. 日志清理(掩盖攻击痕迹)
@"unlink\s*\(.*log",
@"ftruncate\s*\(.*, 0\)",
@"system\s*\('rm -rf.*log" };
#endregion
#region asp特征码
/// <summary>
/// 预编译正则:覆盖完整/拆分/变形的ASP恶意特征
/// </summary>
private static readonly string[] aspRegKeys = new[] {
// 1. 核心代码执行类(完整+拆分变形)
@"eval\s*\(", // 覆盖Eval所有逐字符拆分变形
@"Execute\s*\(",
@"ExecuteGlobal\s*\(",
// 2. 系统命令执行核心对象/方法(完整+拆分)
@"CreateObject\s*\(",
// 3. 文件操作类(完整+拆分)
// 4. 绕过/隐蔽类
@"URLEncode\s*\(",
@"Replace\s*\(",
@"Request\.Form\s*",
@"Request\.QueryString\s*",
@"On\s+Error\s+Resume\s+Next",
// 5. 变形拼接核心(重点覆盖Chr拼接高危关键字)
// 6. 远程通信/提权/日志清理类
};
#endregion
#region .net特征码
/// <summary>
/// 预编译正则:匹配.NET代码块内的高危恶意特征
/// </summary>
private static readonly string[] dotnetRegexKeys = new[] {
// 1. 代码执行/反射类(.NET核心后门手段)
@"System\.Reflection\s*",
@"Activator\.CreateInstance\s*\(",
@"Assembly\.Load\s*\(",
@"MethodInfo\.Invoke\s*\(",
@"Type\.GetType\s*\(",
@"Eval\s*\(",
@"Execute\s*\(",
@"Request\s*\.",
@"Response",
@"DynamicInvoke\s*\(",
// 2. 系统命令执行类
@"System\.Diagnostics\.Process\s*",
@"Process\.Start\s*\(",
@"cmd\.exe\s*",
@"powershell\.exe\s*",
@"bash\.exe\s*",
// 3. 文件操作类(篡改/上传木马)
@"System\.IO\.File\s*",
@"File\.WriteAllText\s*\(",
@"File\.Create\s*\(",
@"File\.Copy\s*\(",
@"File\.Delete\s*\(",
@"FileStream\s*",
@"StreamWriter\s*",
// 4. 绕过/隐蔽类
@"Base64Decode\s*\(",
@"Convert\.FromBase64String\s*\(",
@"HttpContext\.Current\.Request\s*",
@"Request\.Form\s*",
@"Request\.QueryString\s*",
@"Request\.Cookies\s*",
@"Server\.Execute\s*\(",
@"Server\.Transfer\s*\(",
// 5. 变形/混淆类
//@"Chr\(\d+\)\s*\+\s*Chr\(\d+",
//@"Convert\.ToChar\(\d+\)\s*\+\s*Convert\.ToChar\(\d+",
@"string\.Concat\s*\(",
@"Eval\s*\(",
@"Execute\s*\(",
// 6. 远程通信类(远控/数据窃取)
@"System\.Net\.WebClient\s*",
@"HttpClient\.SendAsync\s*\(",
@"WebRequest\.Create\s*\(",
@"TcpClient\s*",
@"Socket\.Connect\s*\(",
// 7. 提权/日志清理类
@"WindowsIdentity\.Impersonate\s*\(",
@"File\.Delete\s*\(.*\.log\s*",
@"EventLog\.Clear\s*\(",
@"Trace\.Close\s*\("
};
// 匹配.NET代码块结尾(允许无%>/}结尾)
#endregion
/// <summary>
/// 检测指定文件中是否包含可疑代码
/// </summary>
/// <param name="file">文件完整路径</param>
/// <returns>true=检测到可疑代码,false=未检测到</returns>
public bool CodeDetected(string file)
{
// 验证输入参数
if (string.IsNullOrEmpty(file))
{
throw new ArgumentNullException(nameof(file), "文件路径不能为空。");
}
// 检查目标文件是否存在
if (!File.Exists(file))
{
throw new FileNotFoundException("目标检测文件不存在:", file);
}
try
{
// 智能检测文件编码并读取内容
var fileEncoding = DetectFileEncoding(file);
string fileContent = File.ReadAllText(file, fileEncoding);
#region 检测php文件
foreach (var key in phpRegKeys)
{
var regex = RegexCache.GetCachedRegex(@"<\?(php)?.*" + key + @".*\?>");
if (regex.IsMatch(fileContent))
{
System.Diagnostics.Debug.WriteLine(key);
return true;
}
}
#endregion
#region 检测asp文件
foreach(var key in aspRegKeys)
{
var regex = RegexCache.GetCachedRegex(@"<%.*" + key + @".*\%>");
if (regex.IsMatch(fileContent))
{
System.Diagnostics.Debug.WriteLine(key);
return true;
}
}
#endregion
#region 检测.net文件
foreach(var key in dotnetRegexKeys)
{
var regex =RegexCache.GetCachedRegex(@"<%@?.*" + key + @".*\%>");
if (regex.IsMatch(fileContent))
{
System.Diagnostics.Debug.WriteLine(key);
return true;
}
}
#endregion
//// 遍历特征码检测(忽略大小写)
//if (MaliciousPhpRegex.IsMatch(fileContent))
//{
// return true;
//}
//else if (MaliciousAspRegex.IsMatch(fileContent))
//{
// return true;
//}
//else if (MaliciousDotNetRegex.IsMatch(fileContent))
//{
// return true;
//}
return false;
}
catch (UnauthorizedAccessException ex)
{
throw new UnauthorizedAccessException($"无权限读取文件:{file},请检查文件权限。", ex);
}
catch (IOException ex)
{
throw new IOException($"读取目标文件时发生 I/O 错误:{file}", ex);
}
catch (Exception ex)
{
throw new Exception($"检测文件 {file} 时发生异常:", ex);
}
}
/// <summary>
/// 智能检测文件编码(优先识别 BOM,无 BOM 则按 Windows 中文系统默认 ANSI(GBK)处理)
/// </summary>
/// <param name="filePath">文件完整路径</param>
/// <returns>识别到的编码</returns>
private static Encoding DetectFileEncoding(string filePath)
{
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
// 读取文件前 4 字节,用于检测 BOM
var bomBytes = new byte[4];
var readLength = fileStream.Read(bomBytes, 0, 4);
// 检测 UTF-8 BOM (EF BB BF)
if (readLength >= 3 && bomBytes[0] == 0xEF && bomBytes[1] == 0xBB && bomBytes[2] == 0xBF)
{
return Encoding.UTF8;
}
// 检测 UTF-16 LE BOM (FF FE)
if (readLength >= 2 && bomBytes[0] == 0xFF && bomBytes[1] == 0xFE)
{
return Encoding.Unicode;
}
// 检测 UTF-16 BE BOM (FE FF)
if (readLength >= 2 && bomBytes[0] == 0xFE && bomBytes[1] == 0xFF)
{
return Encoding.BigEndianUnicode;
}
// 无 BOM 时:Windows 中文系统默认 ANSI 为 GBK,英文系统为 Windows-1252
// 此处优先适配中文系统,返回 GBK(兼容 GB2312)
return Encoding.GetEncoding("GBK");
}
}
}
}
foreach(var file in Directory.EnumerateFiles("你的网站目录","*.*", SearchOption.AllDirectories){