Deploys and configures Zeek to passively monitor network traffic, generate structured logs like conn.log and dns.log, detect anomalies, and create custom scripts for threat hunting.
npx claudepluginhub killvxk/cybersecurity-skills-zhThis skill uses the workspace's default tool permissions.
- 在关键网络节点部署被动网络安全监控,实现持续可见性
Deploys Zeek to capture, parse, and analyze network traffic metadata from protocols like HTTP, DNS, TLS, SSH for threat detection, anomaly identification, and forensics on Linux servers.
Deploys and configures Zeek for passive network traffic analysis, structured log generation, anomaly detection, and custom scripts for threat hunting and incident response.
Deploys and configures Zeek to passively analyze network traffic, generate structured logs like conn/dns/http/ssl, detect anomalies, and script custom threat detections for incident response.
Share bugs, ideas, or general feedback.
不适用场景:替代可主动拦截流量的内联 IDS/IPS;在无 TLS 检测的情况下监控加密载荷;在更适合主机端代理的终端上使用。
zeek --version)# 在 Ubuntu/Debian 上安装 Zeek
sudo apt install -y zeek
# 或从源码安装以获取最新版本
git clone --recursive https://github.com/zeek/zeek
cd zeek && ./configure --prefix=/opt/zeek && make -j$(nproc) && sudo make install
export PATH=/opt/zeek/bin:$PATH
# 配置监控接口
sudo vi /opt/zeek/etc/node.cfg
# /opt/zeek/etc/node.cfg
[zeek]
type=standalone
host=localhost
interface=eth1
# 配置本地网络定义
sudo vi /opt/zeek/etc/networks.cfg
# /opt/zeek/etc/networks.cfg
10.0.0.0/8 内部
172.16.0.0/12 内部
192.168.0.0/16 内部
# 禁用 NIC 卸载以实现准确的数据包捕获
sudo ethtool -K eth1 rx off tx off gro off lro off tso off gso off
# 部署 Zeek
sudo zeekctl deploy
# 验证 Zeek 是否运行
sudo zeekctl status
# Zeek 在 /opt/zeek/logs/current/ 中生成结构化日志文件
ls /opt/zeek/logs/current/
# 关键日志文件:
# conn.log - 所有网络连接(TCP、UDP、ICMP)
# dns.log - DNS 查询和响应
# http.log - HTTP 请求和响应
# ssl.log - SSL/TLS 握手详情
# files.log - 网络上观察到的文件传输
# notice.log - 来自 Zeek 检测脚本的告警
# weird.log - 协议异常和错误
# x509.log - X.509 证书详情
# smtp.log - SMTP 邮件事务
# ssh.log - SSH 连接详情
# 使用 zeek-cut 选列查看连接日志
cat /opt/zeek/logs/current/conn.log | zeek-cut ts id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes
# 查看 DNS 日志
cat /opt/zeek/logs/current/dns.log | zeek-cut ts id.orig_h query qtype_name answers
# 查看 HTTP 日志
cat /opt/zeek/logs/current/http.log | zeek-cut ts id.orig_h host uri method status_code user_agent
# 创建自定义检测脚本目录
sudo mkdir -p /opt/zeek/share/zeek/site/custom-detections
DNS 隧道检测脚本:
# /opt/zeek/share/zeek/site/custom-detections/dns-tunneling.zeek
@load base/frameworks/notice
module DNSTunneling;
export {
redef enum Notice::Type += {
DNS_Tunneling_Detected,
DNS_Long_Query
};
# 阈值:时间窗口内每个源的唯一查询数
const query_threshold: count = 200 &redef;
const time_window: interval = 5min &redef;
const max_query_length: count = 50 &redef;
}
# 按源 IP 跟踪查询计数
global dns_query_counts: table[addr] of count &create_expire=5min &default=0;
event dns_request(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count)
{
local src = c$id$orig_h;
# 检查异常长的域名查询(base64 编码数据)
if ( |query| > max_query_length )
{
NOTICE([
$note=DNS_Long_Query,
$msg=fmt("来自 %s 的异常长 DNS 查询:%s(%d 字符)", src, query, |query|),
$src=src,
$identifier=cat(src, query)
]);
}
# 按源跟踪查询量
dns_query_counts[src] += 1;
if ( dns_query_counts[src] == query_threshold )
{
NOTICE([
$note=DNS_Tunneling_Detected,
$msg=fmt("可能的 DNS 隧道:%s 在 %s 内发送了 %d 个查询", src, time_window, query_threshold),
$src=src,
$identifier=cat(src)
]);
}
}
信标检测脚本:
# /opt/zeek/share/zeek/site/custom-detections/beacon-detection.zeek
@load base/frameworks/notice
@load base/frameworks/sumstats
module BeaconDetection;
export {
redef enum Notice::Type += {
Possible_Beaconing
};
const beacon_threshold: count = 50 &redef;
const observation_window: interval = 1hr &redef;
}
event zeek_init()
{
local r1 = SumStats::Reducer(
$stream="beacon.connections",
$apply=set(SumStats::SUM)
);
SumStats::create([
$name="detect-beaconing",
$epoch=observation_window,
$reducers=set(r1),
$threshold_val(key: SumStats::Key, result: SumStats::Result) = {
return result["beacon.connections"]$sum;
},
$threshold=beacon_threshold + 0.0,
$threshold_crossed(key: SumStats::Key, result: SumStats::Result) = {
NOTICE([
$note=Possible_Beaconing,
$msg=fmt("可能的信标行为:%s 在 %s 内建立了 %d 次连接",
key$str, result["beacon.connections"]$sum, observation_window),
$identifier=key$str
]);
}
]);
}
event connection_state_remove(c: connection)
{
if ( c$id$resp_h !in Site::local_nets )
{
local key = fmt("%s->%s:%d", c$id$orig_h, c$id$resp_h, c$id$resp_p);
SumStats::observe("beacon.connections", [$str=key], [$num=1]);
}
}
# 将自定义脚本添加到 local.zeek
sudo tee -a /opt/zeek/share/zeek/site/local.zeek << 'EOF'
# 自定义检测脚本
@load custom-detections/dns-tunneling.zeek
@load custom-detections/beacon-detection.zeek
# 启用额外的协议分析器
@load protocols/ftp/software
@load protocols/http/software
@load protocols/smtp/software
@load protocols/ssh/detect-bruteforcing
@load protocols/ssl/validate-certs
@load protocols/ssl/log-hostcerts-only
@load protocols/dns/detect-external-names
# 启用文件提取
@load frameworks/files/extract-all-files
# 启用 Intel 框架用于威胁情报
@load frameworks/intel/seen
@load frameworks/intel/do_notice
EOF
# 重新加载 Zeek 配置
sudo zeekctl deploy
# 验证脚本加载无误
sudo zeekctl diag
# 查找长时间连接(可能的 C2)
cat /opt/zeek/logs/current/conn.log | zeek-cut ts id.orig_h id.resp_h id.resp_p duration | \
awk '$5 > 3600 {print $0}' | sort -t$'\t' -k5 -rn | head -20
# 查找高数据传输量的连接
cat /opt/zeek/logs/current/conn.log | zeek-cut ts id.orig_h id.resp_h orig_bytes resp_bytes | \
awk '$4 > 100000000 || $5 > 100000000 {print $0}'
# 识别罕见 User-Agent(潜在恶意软件)
cat /opt/zeek/logs/current/http.log | zeek-cut user_agent | sort | uniq -c | sort -n | head -20
# 查找自签名或过期证书
cat /opt/zeek/logs/current/ssl.log | zeek-cut ts id.orig_h id.resp_h server_name validation_status | \
grep -v "ok"
# 检测 DGA 模式的 DNS 查询(新注册域名)
cat /opt/zeek/logs/current/dns.log | zeek-cut ts id.orig_h query | \
awk -F'\t' '{n=split($3,a,"."); if(length(a[n-1]) > 10) print $0}'
# 查找 SSH 暴力破解尝试
cat /opt/zeek/logs/current/ssh.log | zeek-cut ts id.orig_h id.resp_h auth_success | \
grep "F" | awk '{print $2}' | sort | uniq -c | sort -rn | head -10
# 识别异常端口使用
cat /opt/zeek/logs/current/conn.log | zeek-cut id.resp_p proto service | \
sort | uniq -c | sort -rn | head -50
# 配置 JSON 日志输出以便 SIEM 摄入
sudo tee /opt/zeek/share/zeek/site/json-logs.zeek << 'EOF'
@load policy/tuning/json-logs.zeek
redef LogAscii::use_json = T;
EOF
# 通过 Filebeat 将日志转发到 Elastic
# /etc/filebeat/filebeat.yml
sudo tee /etc/filebeat/filebeat.yml << 'EOF'
filebeat.inputs:
- type: log
enabled: true
paths:
- /opt/zeek/logs/current/*.log
json.keys_under_root: true
json.add_error_key: true
fields:
source: zeek
fields_under_root: true
output.elasticsearch:
hosts: ["https://elastic-siem:9200"]
index: "zeek-%{+yyyy.MM.dd}"
username: "elastic"
password: "${ES_PASSWORD}"
EOF
sudo systemctl enable --now filebeat
# 设置日志轮转
sudo tee /etc/cron.d/zeek-logrotate << 'EOF'
0 0 * * * root /opt/zeek/bin/zeekctl cron
EOF
# 监控 Zeek 健康状态
sudo zeekctl status
sudo zeekctl netstats
| 术语 | 定义 |
|---|---|
| 网络安全监控器(Network Security Monitor) | 被动分析工具,观察网络流量并生成结构化元数据日志,不改变或拦截流量 |
| Zeek 脚本(Zeek Script) | 用 Zeek 领域特定语言编写的事件驱动脚本,处理网络事件并生成通知、日志和指标 |
| 连接日志(conn.log) | 核心 Zeek 日志,记录每个观察到的连接,包含源/目标 IP、端口、协议、持续时间和字节计数 |
| Notice 框架(Notice Framework) | 当检测脚本识别到可疑活动时,Zeek 用于生成告警的子系统,输出到 notice.log |
| SumStats 框架(SumStats Framework) | Zeek 中的统计分析框架,用于跟踪时间窗口内的指标,实现基于阈值的异常检测 |
| Intel 框架(Intel Framework) | Zeek 模块,将观察到的网络指标与威胁情报 feeds 进行匹配,并在匹配时生成告警 |
背景:威胁情报报告指出,某特定威胁行为者对被入侵主机使用 60 秒间隔的 HTTPS 信标。SOC 团队需要分析 Zeek 日志,在承载 2 Gbps 流量的企业网络中识别任何表现出此模式的主机。
方法:
常见陷阱:
## Zeek 网络异常检测报告
**传感器**:zeek-sensor-01(10.10.1.250)
**监控接口**:eth1(来自 Core-SW1 的 SPAN 端口)
**分析周期**:2024-03-15 00:00 至 2024-03-16 00:00 UTC
**记录的连接总数**:2,847,392
### 检测到的异常
| 通知类型 | 来源 | 目标 | 详情 |
|-------------|--------|-------------|---------|
| DNS_Tunneling_Detected | 10.10.3.45 | 8.8.8.8 | 5 分钟内向 suspect-domain.xyz 发出 847 次查询 |
| Possible_Beaconing | 10.10.5.12 | 203.0.113.50:443 | 62 次连接,平均间隔 59.8 秒 |
| SSL::Invalid_Server_Cert | 10.10.8.22 | 198.51.100.33:443 | 自签名证书,CN=localhost |
| SSH::Password_Guessing | 45.33.32.156 | 10.10.20.11:22 | 30 分钟内 487 次失败尝试 |
### 建议
1. 隔离 10.10.3.45 并调查 DNS 隧道恶意软件
2. 在防火墙封锁 203.0.113.50 并对 10.10.5.12 进行取证镜像
3. 调查 198.51.100.33 上的自签名 TLS 证书
4. 封锁 45.33.32.156 并强制执行仅 SSH 密钥认证