在网络安全应急响应(Incident Response)中,现场环境往往复杂且受限。安全工程师需要在不破坏现场证据的前提下,快速收集系统状态、分析日志并定位恶意文件。
虽然有许多成熟的 EDR 和商业工具,但在紧急情况下,轻量级、可定制的 Python 或 Shell 脚本往往是最好用的“瑞士军刀”。本文提供三个应急响应中最常用的实战脚本示例。
场景一:系统信息“快照”收集 (System Info Collector)
目标:快速获取当前系统的进程列表、网络连接、用户信息和计划任务,用于后续离线分析。 特点:使用 Python 标准库 subprocess,无需安装 psutil,兼容性强。
import subprocess
import os
import datetime
def run_command(cmd, description):
print(f"[*] 正在收集: {description}...")
try:
# 使用 shell=True 允许使用管道符,但需注意安全风险(此处为内部工具,相对可控)
result = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return f"\n=== {description} ===\n" + result.decode('utf-8', errors='ignore')
except subprocess.CalledProcessError as e:
return f"\n=== {description} (ERROR) ===\n" + str(e.output)
def collect_linux_info():
report = f"系统信息收集报告 - 时间: {datetime.datetime.now()}\n"
# 1. 当前登录用户
report += run_command("w", "当前登录用户")
# 2. 异常网络连接 (关注 ESTABLISHED 和 LISTEN)
# -p: 显示进程PID, -n: 不解析域名 (加速)
report += run_command("netstat -antlp", "网络连接与对应进程")
# 3. 进程列表 (按 CPU/内存排序)
report += run_command("ps -aux --sort=-pcpu | head -20", "Top 20 CPU 占用进程")
# 4. 检查定时任务
report += run_command("cat /etc/crontab", "系统级 Crontab")
report += run_command("ls -la /var/spool/cron/", "用户级 Crontab 目录")
# 5. 检查最近修改的敏感文件 (如 /etc/passwd, /etc/shadow)
# 查找 7 天内修改过的 /etc 下的文件
report += run_command("find /etc -type f -mtime -7 2>/dev/null", "最近7天修改的配置")
# 保存报告
filename = f"ir_report_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
with open(filename, "w") as f:
f.write(report)
print(f"\n[+] 收集完成,报告已保存至: {filename}")
if __name__ == "__main__":
if os.name == 'posix':
collect_linux_info()
else:
print("此示例脚本主要针对 Linux 环境,Windows 建议使用 PowerShell 或 WMIC。")
场景二:Web 日志攻击特征分析 (Log Analyzer)
目标:从海量的 Web 访问日志(Apache/Nginx)中筛选出 SQL 注入、XSS 或 Webshell 连接的痕迹。 特点:基于正则匹配,快速定位攻击源 IP。
import re
import sys
# 定义常见的攻击特征正则
ATTACK_PATTERNS = {
'SQL_Injection': r"(union.*select|select.*from|information_schema|waitfor.*delay|sleep\()",
'XSS': r"(<script>|alert\(|javascript:|onerror=)",
'Webshell_Connect': r"(cmd=|eval\(|whoami|exec\(|system\()",
'Directory_Traversal': r"(\.\./\.\./|/etc/passwd|c:\\windows)",
'Struts2_RCE': r"(org\.apache\.struts2|ognl)"
}
def analyze_log(log_file):
print(f"[*] 开始分析日志文件: {log_file}")
suspicious_count = 0
ip_stats = {}
try:
with open(log_file, 'r', encoding='utf-8', errors='ignore') as f:
for line in f:
# 简单的 Nginx/Apache 日志解码
# 假设格式: IP - - [Date] "Request" Status Bytes ...
# 这里只做简单的全文匹配,实际场景可精细化解析
is_suspicious = False
for attack_type, pattern in ATTACK_PATTERNS.items():
if re.search(pattern, line, re.IGNORECASE):
print(f"[!] 发现疑似 {attack_type} 攻击:")
print(f" {line.strip()[:200]}...") # 只打印前200字符
is_suspicious = True
suspicious_count += 1
break # 一行只报一次
if is_suspicious:
# 尝试提取 IP (简单正则,匹配行首 IP)
ip_match = re.match(r"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})", line)
if ip_match:
ip = ip_match.group(1)
ip_stats[ip] = ip_stats.get(ip, 0) + 1
except FileNotFoundError:
print("[-] 错误:找不到日志文件。")
return
print(f"\n[*] 分析结束。共发现 {suspicious_count} 条可疑记录。")
if ip_stats:
print("\n[+] 可疑 IP TOP 5:")
sorted_ips = sorted(ip_stats.items(), key=lambda x: x[1], reverse=True)[:5]
for ip, count in sorted_ips:
print(f" IP: {ip} - 触发次数: {count}")
if __name__ == "__main__":
# 使用方式: python log_analyzer.py /var/log/nginx/access.log
if len(sys.argv) < 2:
print("Usage: python log_analyzer.py <logfile_path>")
else:
analyze_log(sys.argv[1])
场景三:Webshell 与变动文件扫描 (File Scanner)
目标:扫描 Web 目录,找出最近被修改的文件(可能是攻击者上传的马)以及包含危险函数的文件。 特点:结合时间戳和文件内容特征。
import os
import time
# 配置扫描目录和敏感扩展名
SCAN_DIR = "/var/www/html" # 修改为实际 Web 根目录
EXTENSIONS = ['.php', '.jsp', '.asp', '.aspx']
# 危险函数特征 (PHP示例)
WEBSHELL_SIGNATURES = [
b'eval($_POST',
b'system($_GET',
b'shell_exec',
b'base64_decode',
b'assert('
]
def scan_files(directory):
print(f"[*] 开始扫描目录: {directory}")
print(f"[*] 查找最近 24 小时内修改过的脚本文件...")
now = time.time()
one_day_ago = now - (24 * 60 * 60)
for root, dirs, files in os.walk(directory):
for filename in files:
filepath = os.path.join(root, filename)
_, ext = os.path.splitext(filename)
if ext.lower() not in EXTENSIONS:
continue
try:
# 1. 检查文件修改时间 (mtime)
file_stats = os.stat(filepath)
mtime = file_stats.st_mtime
if mtime > one_day_ago:
print(f"[Time] 最近修改: {filepath} (时间: {time.ctime(mtime)})")
# 2. 检查文件内容特征
with open(filepath, 'rb') as f:
content = f.read()
for sig in WEBSHELL_SIGNATURES:
if sig in content:
print(f"[Danger] 发现危险特征 '{sig.decode()}': {filepath}")
break
except Exception as e:
print(f"[-] 无法读取文件: {filepath} - {e}")
if __name__ == "__main__":
if os.path.exists(SCAN_DIR):
scan_files(SCAN_DIR)
else:
print(f"[-] 目录不存在: {SCAN_DIR}")
应急响应工具箱推荐
除了上述自编脚本,以下现成工具也是应急响应的标准配置:
- Sysinternals Suite (Windows):
Process Explorer: 查看进程层级、加载的 DLL。Autoruns: 最全的启动项检查工具。TCPView: 实时查看端口连接。
- BusyBox (Linux):
- 如果系统命令(如
ls,ps)被植入 rootkit 替换了,上传一个静态编译的 busybox 可以使用干净的指令集。
- 如果系统命令(如
- GScan / Chkrootkit / Rkhunter:
- Linux 自动化排查脚本,能自动检测 rootkit 和常见的后门配置。
- Wireshark / Tcpdump:
- 全流量抓包分析,用于捕捉 C2(Command & Control)通信流量。
结语
工具只是辅助,核心在于分析思路。在执行上述脚本时,请务必注意:
- 最小化影响:不要在业务高峰期运行高负载扫描。
- 证据保全:任何操作前,最好对关键日志和文件进行哈希备份。
- 隔离优先:确认主机受陷后,第一时间断网(物理拔线或虚拟隔离)是防止扩散的最有效手段。
发表回复