网站被入侵后清理了一遍,过几天又发现新马。原因多半是清理不彻底——只删了明面上的文件,藏在图片里、伪装成正常库文件的WebShell没揪出来。人工逐个文件看?几千个文件看到眼瞎。让AI写个扫描脚本,按特征全盘扫一遍,是效率最高的做法。
先想清楚WebShell长什么样。一句话木马的核心特征:执行代码的危险函数(eval、assert、system、exec、shell_exec、passthru)+ 接收外部输入($_POST、$_REQUEST、$_GET、$_COOKIE)+ 常见变形(base64_decode、str_rot13、字符串拼接、create_function)。光查扩展名没用——攻击者会把马改成.jpg、.png甚至没有扩展名。所以扫描要按内容特征来。
把特征告诉AI,让它写扫描脚本。提示词里明确:扫描目录、要匹配的特征、输出要求。下面这个Python脚本就是典型的AI产物,你只要理解它的思路——正则匹配高危函数组合,命中就打印文件路径和行号。
# webshell_scan.py —— 按内容特征扫描上传目录
import os, re
SCAN_DIR = "/var/www/html/uploads"
# 高危特征:危险函数 + 可变参数/编码变形
patterns = [
re.compile(r'(eval|assert)\s*\(\s*\$_(POST|REQUEST|GET|COOKIE)', re.I),
re.compile(r'(system|exec|shell_exec|passthru|popen)\s*\(\s*\$_(POST|REQUEST|GET|COOKIE)', re.I),
re.compile(r'base64_decode\s*\(\s*["\']', re.I),
re.compile(r'@\s*(eval|assert)\s*\(', re.I),
re.compile(r'create_function\s*\(', re.I),
]
for root, dirs, files in os.walk(SCAN_DIR):
for f in files:
path = os.path.join(root, f)
try:
with open(path, 'rb') as fp:
data = fp.read()
except Exception:
continue
# 跳过真正的图片文件
if data[:3] == b'\xff\xd8\xff' or data[:8] == b'\x89PNG\r\n\x1a\n':
continue
try:
text = data.decode('utf-8', errors='ignore')
except Exception:
continue
for i, pat in enumerate(patterns):
m = pat.search(text)
if m:
line = text[:m.start()].count('\n') + 1
print(f"[!] {path}:{line} 命中特征{i+1}: {m.group()[:60]}")
break
扫描结果要人工复核,AI写的特征正则可能有误报——比如某些正常代码里也有base64_decode(微信支付回调验签就常用)。命中列表拿出来,逐个打开看上下文,确认是马再删。删之前先备份,万一误删了正常文件还有退路。
另外两个维度别漏:一是文件修改时间,入侵时间点之后被改动的文件全部重点查;二是上传目录的权限,WebShell多半是从上传漏洞进来的,扫完马顺手把上传目录的脚本执行权限禁了(Nginx下location配置deny php),不然明天还会有一批新马等你扫。
# Nginx:uploads目录禁止执行PHP(WebShell最常见入口)
location ~ ^/uploads/.*\.(php|php5|phtml|asp|aspx|jsp|cgi|pl)$ {
deny all;
return 403;
}
# 定时扫描(每天凌晨4点)
0 4 * * * python3 /root/webshell_scan.py >> /var/log/webshell_scan.log 2>&1
A5创业网 版权所有