使用 Zeek 和 Python 分析网络流量

2023-04-21 00:00:00 分析 网络流量 Zeek
  1. 使用 Zeek 分析网络流量
    首先,安装 Zeek(原名Bro),可以从官网 https://www.zeek.org/get-zeek 下载安装包,或使用包管理工具进行安装。
    接着,通过命令行启动 Zeek 并指定要分析的网络接口或抓包文件,例如:
$ zeek -r pcap.pcap

这将加载默认的分析脚本并开始分析 pcap.pcap 的流量。如果需要自定义脚本,可以编辑或新建 *.zeek 文件并在启动时指定:

$ zeek -r pcap.pcap custom-script.zeek

为了方便查看分析结果,可以使用 Zeek 的日志功能将结果输出到文件。例如,以下代码将把 HTTP、DNS 和 SSL/TLS 流量的详细信息输出到对应的日志文件中:

@load policy/tuning/defaults.zeek
@load protocols/http/logs.zeek
@load protocols/dns/logs.zeek
@load protocols/ssl/logs.zeek
redef LogAscii::use_json=T;
event bro_init() {
    Log::default_rotation_interval = 24hr;
    Log::default_disk_space = 1GB;
}
event http_reply(c: connection, f: http_reply_frame) {
    Log::write_json(HTTP::LOG, [$c$id, f$http_status_code, f$http_message]);
}
event dns_reply(c: connection, msg: dns_msg) {
    for (answer in msg$answers) {
        Log::write_json(DNS::LOG, [$c$id, answer$dns$atype, answer$dns$answer]);
    }
}
event ssl_established(c: connection) {
    Log::write_json(SSL::LOG, [$c$id, c$client$subject, c$client$certificate_chain, c$client$ja3_hash]);
}

注意,要使用 JSON 格式输出日志,需要在 policy/tuning/defaults.zeek 中增加以下配置:

redef LogAscii::use_json=T;
global LogAscii::json_timestamps = JSON::TS_ISO8601_STRFMT;
global LogAscii::separator = "\t";
global LogAscii::empty_field = "(empty)";

分析结果保存在对应的 *.log 文件中,可以使用 Python 或其他脚本语言进行后续处理。
2. 使用 Python 分析 Zeek 日志
Zeek 日志使用 Tab-separated values (TSV) 格式,可以使用 Python 中的 pandas 和其它库进行分析和可视化。以下代码可以将 HTTP 访问次数最多的前 10 个网站输出到控制台:

import pandas as pd
http_logs = pd.read_csv("http.log", sep="\t", comment="#", header=None,
    names=["ts", "uid", "id.orig_h", "id.orig_p", "id.resp_h", "id.resp_p",
           "trans_depth", "method", "host", "uri", "referrer", "user_agent",
           "request_body_len", "response_body_len", "status_code", "status_msg",
           "info_code", "info_msg", "filename", "tags", "username", "password",
           "proxied", "orig_fuids", "orig_mime_types", "resp_fuids", "resp_mime_types",
           "missed_bytes"])
top_hosts = http_logs.groupby("host").size().reset_index(name="count")
top_hosts = top_hosts.sort_values("count", ascending=False).head(10)
print(top_hosts)

输出:

                        host  count
69             www.baidu.com     20
33    114.114.114.114:443,   16
67     www.sogou.com:443,   16
10         47.95.115.12:443,   14
50    analytics.google.com,   14
110       www.w3.org:443,   14
37         www.aliyun.com,   13
48       vlqgtqullduq4nia4s1jwc2yl7gzejksbwzyfz7o.com,   13
3              114.114.114.114     11
85      cdnres.touclick.com,   11

类似地,可以使用 pandas 或 matplotlib 等库进行二次分析和可视化,例如绘制 HTTP 访问次数最多的前 10 个网站的柱状图:

import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.bar(top_hosts["host"], top_hosts["count"])
ax.set_xlabel("Website")
ax.set_ylabel("HTTP Requests")
ax.set_title("Top 10 Most Accessed Websites")
plt.xticks(rotation=45, ha="right")
plt.tight_layout()
plt.show()

http-top-hosts.png
当然,还可以根据实际需求使用 pandas 及其它库进行更高级的数据分析和可视化。

相关文章