cisco/mercury

GitHub: cisco/mercury

Mercury 是一款高性能网络数据包元数据捕获与分析工具,支持多协议指纹生成与 JSON 输出,能够在高速网络环境中进行可扩展的实时流量监控。

Stars: 517 | Forks: 87

# Mercury:网络元数据捕获与分析 本软件包包含两个用于识别网络流量指纹以及捕获和分析数据包元数据的程序:**mercury**,一个适用于 Linux 和 macOS 的独立应用程序;以及 [**pmercury**](python/README.md),一个可移植的 Python 应用程序。在 Linux 上,mercury 利用内核高性能的 AF_PACKET TPACKETv3 捕获路径;在 macOS 上,mercury 通过 libpcap 支持接口捕获。此外,这里还有一份[用户指南](https://github.com/cisco/mercury/wiki/Using-Mercury)。虽然 mercury 已被用于某些生产环境中,但请将此软件视为“测试版”。[更新日志](doc/CHANGELOG.md) 详细列出了不同版本间的变更。 ## 概述 Mercury 读取网络数据包,识别感兴趣的元数据,并以 JSON 格式输出这些元数据。或者,mercury 也可以将包含元数据的数据包以 PCAP 文件格式输出。Mercury 能够扩展以适应高数据速率(在服务器级硬件上可达 40Gbps);它使用零拷贝环形缓冲区来获取数据包,并且数据包由独立的工作线程处理。环形缓冲区消耗的内存量以及工作线程的数量都是可配置的;这使得扩展变得容易(但要注意不要使用过多的内存)。 Mercury 为 TLS、DTLS、SSH、HTTP、TCP 等协议生成指纹字符串;这些指纹是通过对从数据包中提取的元数据进行仔细筛选和规范化而形成的(详见[此处](doc/npf.md)文档)。指纹字符串会在 JSON 输出的 "fingerprint" 对象中报告。可选地,mercury 可以根据这些指纹和目标上下文执行进程识别;这些结果将在 "analysis" 对象中报告。 # 目录 * [构建与安装 mercury](#building-and-installing-mercury) * [安装说明](#installation) * [编译时选项](#compile-time-options) * [运行 mercury](#running-mercury) * [详细信息](#details) * [系统](#system) * [示例](#examples) * [道德规范](#ethics) * [贡献](#credits) * [致谢](#acknowledgments) ## 构建与安装 mercury Mercury 本身除了 g++ 或 llvm 构建环境外,几乎没有其他依赖项,但要运行本软件包中的自动化测试和辅助程序,您需要安装额外的软件包,如以下 Debian/Ubuntu 示例所示: ``` sudo apt install g++ jq git zlib1g-dev tcpreplay valgrind python3-pip libssl-dev clang sudo apt install libxsimd-dev # optional: enables SIMD-accelerated classification python3 -m pip install --upgrade pip python3 -m pip install --upgrade jsonschema cryptography Cython wheel setuptools ``` 要构建 mercury,请在根目录下运行 ``` ./configure make ``` 来构建软件包(并检查测试所需的程序和 Python 模块)。TPACKETv3 存在于 3.2 版本以上的 Linux 内核中。 目前在 macOS Apple Silicon 上构建 mercury 仍处于实验阶段。独立的 mercury 可以在 macOS 上读取 pcap 文件并使用 libpcap 从网络接口进行捕获。 当前的 macOS 实时捕获后端仅支持单个捕获 线程。以下操作已在搭载 M2 芯片且通过下方的 Homebrew 命令安装了 Python 3.13.2 的 Mac 上进行了测试。 ``` brew install python openssl zlib brew install xsimd # optional: enables SIMD-accelerated classification brew install cmake # optional: libmerc can be also built with CMake mkdir -p ~/.envs python3 -m venv ~/.envs/merc source ~/.envs/merc/bin/activate python3 -m pip install --upgrade pip python3 -m pip install --upgrade jsonschema cryptography Cython wheel setuptools ./configure && make make cython ``` 在运行时依赖方面,`mercury` 独立二进制文件应该只需要: - [zlib](https://zlib.net) - [OpenSSL](https://www.openssl.org/) 随附的 [Dockerfile](Dockerfile) 提供了一个在 Debian 上的可用示例。 下面列出的辅助工具等可能需要其他软件包。 - [pmercury](python/README.md) 及相关工具:Python 3.9+ 以及若干 pip 软件包。 - `batch_gcd`:[GNU Multiple Precision Arithmetic Library (GMP)](https://gmplib.org/) ### 安装说明 在根目录下,根据需要查看 `mercury.cfg`,然后运行 ``` ./configure make sudo make install MERCURY_CFG=mercury.cfg ``` 以安装 mercury 并创建、启动 systemd 服务。如果您不想安装 mercury systemd 服务,请改为运行 ``` sudo make install-nosystemd ``` 默认的 `mercury.cfg` 通过设置 `capture=auto` 启用捕获模式,并在运行时于 Linux 上自动检测网络接口。要强制指定特定接口,请改设 `capture=`。 默认的文件和目录位置如下 * __/usr/local/bin/mercury__ 用于存放可执行文件 * __/usr/local/share/mercury__ 用于存放资源文件 * __/usr/local/var/mercury__ 用于存放输出文件 * __/etc/mercury/mercury.cfg__ 用于存放配置文件 * __/etc/systemd/system/mercury.service__ 用于存放 systemd unit 文件 输出文件目录归用户 **mercury** 所有;该用户由 'make install' 目标创建,且此命令必须以 root 身份运行。可以通过使用 --prefix 参数运行 ./configure 来更改安装前缀 **/usr/local/**,例如 `--prefix=$HOME`。如果您想将程序安装在您的主目录下的某个位置,您可能不希望创建 mercury 用户;您应该使用 'make install-nonroot' 目标,该目标不会创建用户,不会将任何内容安装到 /etc 中,也不会安装 systemd unit。 使用 systemd 是在捕获模式下运行 mercury 最简单的方法;操作系统会在每次启动后自动启动 mercury systemd unit,并在操作系统关闭时停止它。要检查其状态,请运行 ``` systemctl status mercury ``` 并且输出应包含 'active (running)'。要查看 mercury unit 的日志输出(主要是 stderr),请运行 ``` sudo journalctl -u mercury ``` Mercury 的 stdout 和 stderr 会以标识符 `mercury` 发送到 systemd journal;在 journald 条目被 syslog/rsyslog 转发或导入的系统中(如默认的 RHEL/Alma 日志设置),这些消息也会出现在 `/var/log/messages` 中。要跳过 journald/syslog 并将 stdout 和 stderr 直接重定向到文件,请运行 `sudo systemctl edit mercury` 并添加 ``` [Service] StandardOutput=append:/var/log/mercury.log StandardError=inherit ``` 然后执行 `sudo systemctl restart mercury`。请注意,Mercury 的 JSON 输出文件会写入工作目录(默认为 `/usr/local/var/mercury`)下,并且不受这些设置的影响。 要卸载 mercury,请运行 ``` sudo make uninstall ``` 这将删除 mercury 程序、资源目录、用户、组以及 systemd 相关文件。包含捕获文件的目录将被保留,但其所有者将更改为 root,以避免无意中的数据丢失。所有捕获的数据文件在连续安装和卸载过程中都会被保留,必须手动删除。 ### 编译时选项 要创建 mercury 的调试版本,请使用 **BUILD_TYPE=Debug**(以及可选的 sanitizer)进行构建,例如 `make -j BUILD_TYPE=Debug SANITIZE=address`。每个变体都有其自己的 `build//` 树,因此无需在变体之间执行 `make clean`。有关变体标志的完整列表,请参阅 `make help`。 有一些编译时选项可以针对您的硬件调优 mercury。这些选项均通过 C/C++ 预处理指令进行设置,该指令应通过 OPTFLAGS 变量作为参数传递给 "make"。运行 **make "OPTFLAGS="** 将 传递给 C/C++ 编译器。可用的编译时选项有: * -DDEBUG,用于开启调试,以及 * -FBUFSIZE=16384,用于将 fwrite/fread 缓冲区设置为 16,384 字节(举例)。 如果使用了多个编译时选项,则它们必须在 OPTFLAGS 字符串中一起传递给 make,例如 "OPTFLAGS=-DDEBUG -DFBUFSIZE=16384"。 ## 运行 mercury ``` mercury: packet metadata capture and analysis build/RelWithDebInfo/bin/mercury [INPUT] [OUTPUT] [OPTIONS]: INPUT [-c or --capture] | auto # capture from , or auto-detect with "auto" [-r or --read] read_file # read packets from file no input option # read packets from standard input OUTPUT [-f or --fingerprint] json_file_name # write JSON fingerprints to file [-w or --write] pcap_file_name # write packets to PCAP/MCAP file no output option # write JSON fingerprints to stdout --capture OPTIONS [-b or --buffer] b # set RX_RING size to (b * PHYS_MEM) [-t or --threads] [num_threads | cpu] # set number of threads [-u or --user] u # set UID and GID to those of user u [-d or --directory] d # set working directory to d GENERAL OPTIONS --config c # read configuration from file c [-a or --analysis] # analyze fingerprints --resources=f # use resource file f --format=f # report fingerprints with formats(s) f --stats=f # write stats to file f --stats-time=T # write stats every T seconds --stats-limit=L # limit stats to L entries [-s or --select] filter # select traffic by filter (see --help) --nonselected-tcp-data # tcp data for nonselected traffic --nonselected-udp-data # udp data for nonselected traffic --reassembly # reassemble protocol messages over multiple transport segments [-l or --limit] l # rotate output file after l records --output-time=T # rotate output file after T seconds --dns-json # output DNS as JSON, not base64 --certs-json # output certs as JSON, not base64 --metadata # output more protocol metadata in JSON --raw-features # select protocols to write out raw features string(see --help) --http-headers=mode # controls reporting of HTTP headers in L7 metadata (all or non-sensitive) --http-body-max=N # report up to N bytes of the HTTP body (max 2048 bytes) --network-behavioral-detections # perform network behavioral detections --minimize-ram # minimize the ram usage of mercury library --crypto-assess[=policy] # perform cryptographic security assessment --exposed-creds # detect exposed credentials in enabled protocols --quic-trial-decryption # try all known QUIC initial salts for unknown versions [-v or --verbose] # additional information sent to stderr --license # write license information to stdout --version # write version information to stdout [-h or --help] # extended help, with examples DETAILS "[-c or --capture] c" captures packets from interface c using the platform live-capture backend. On Linux, mercury uses AF_PACKET with a separate ring buffer for each worker thread. On macOS, mercury uses libpcap for interface capture and currently supports a single capture thread. Use "-c auto" to auto-detect a capture interface (Linux only); it picks the active, non-loopback interface that has received the most packets. "[-t or --thread] t" sets the number of worker threads to t, if t is a positive integer; if t is "cpu", then the number of threads will be set to the number of available processors. "[-b or --buffer] b" sets the total size of all ring buffers to (b * PHYS_MEM) where b is a decimal number between 0.0 and 1.0 and PHYS_MEM is the available memory; USE b < 0.1 EXCEPT WHEN THERE ARE GIGABYTES OF SPARE RAM to avoid OS failure due to memory starvation. "[-f or --fingerprint] f" writes a JSON record for each fingerprint observed, which incorporates the flow key and the time of observation, into the file f. With [-a or --analysis], fingerprints and destinations are analyzed and the results are included in the JSON output. "--stats=f" writes compressed JSON lines with per-source-IP aggregates. Example (single line shown pretty-printed): { "src_ip":"192.0.2.10", "libmerc_init_time":"2026-01-26T18:34:11Z", "libmerc_version":"1.4.3", "resource_version":"2025-11-18", "build_number":12345, "git_commit_id":"abc123", "device_info":{ "cert_labels":[{"common_name":"example.com","count":3}], "snmp_labels":[{"oid":"1.3.6.1.2.1.1.5.0","count":2}] }, "fingerprints":[{"str_repr":"tls/2(0303...)", "sessions":[{"user_agent":"ua", "dest_info":[{"dst":"(sni)(203.0.113.7)(443)","count":3}]}]}] } "[-w or --write] w" writes packets to the file w, in PCAP format. With the option [-s or --select], packets are filtered so that only ones with fingerprint metadata are written. "[r or --read] r" reads packets from the file r, in PCAP format. if neither -r nor -c is specified, then packets are read from standard input, in PCAP format. "[-s or --select] f" selects packets according to the metadata filter f, which is a comma-separated list of the following strings: arp ARP message bittorrent Bittorrent Handshake Message, LSD message, DHT message cdp CDP message dhcp DHCP discover message dnp3 DNP3 industrial control message dns DNS messages dtls DTLS clientHello, serverHello, and certificates ftp FTP request and response ftp.request FTP request ftp.response FTP response gre GRE message http HTTP request and response http.request HTTP request http.response HTTP response icmp ICMP message iec IEC 60870-5-104 lldp LLDP message ldap LDAP imap IMAP request and response imap.request IMAP request imap.response IMAP response kerberos Kerberos v5 mdns multicast DNS mysql MySQL Client/Server Protocol nbns NetBIOS Name Service nbds NetBIOS Datagram Service nbss NetBIOS Session Service openvpn_tcp OpenVPN over TCP ospf OSPF message quic QUIC handshake redis Redis request and response redis.request Redis request redis.response Redis response sctp SCTP message ssh SSH handshake and KEX (client and server) ssh.client SSH handshake and KEX (only client) ssh.server SSH handshake and KEX (only server) smb SMB v1 and v2 smtp SMTP client and server messages snmp SNMP messages socks SOCKS4,SOCKS5 messages ssdp SSDP (UPnP) stun STUN messages syslog SYSLOG (BSD and IETF) tacacs TACACS+ telnet Telnet (RFC 854/855) tcp TCP headers tcp.message TCP initial message tcp.syn_ack TCP syn ack message tls TLS clientHello, serverHello, and certificates tls.client_hello TLS clientHello tls.server_hello TLS serverHello tls.certificates TLS serverCertificates tofsee Tofsee malware communication wireguard WG handshake initiation message geneve Geneve encapsulation vxlan VXLAN encapsualtion all all of the above all of the above none none of the above --nonselected-tcp-data writes the first TCP Data field in a flow with nonzero length, for *non*-selected traffic, into JSON. This option provides a view into the TCP data that the --select option does not recognize. The --select filter affects the TCP data written by this option; use '--select=none' to obtain the TCP data for each flow. --nonselected-udp-data writes the first UDP Data field in a flow with nonzero length, for *non*-selected traffic, into JSON. This option provides a view into the UDP data that the --select option does not recognize. The --select filter affects the UDP data written by this option; use '--select=none' to obtain the UDP data for each flow. --reassembly enables reassembly This option allows mercury to keep track of tcp or udp segment state and and reassemble these segments based on the application in payload "[-u or --user] u" sets the UID and GID to those of user u, so that output file(s) are owned by this user. If this option is not set, then the UID is set to SUDO_UID, so that privileges are dropped to those of the user that invoked sudo. A system account with username mercury is created for use with a mercury daemon. "[-d or --directory] d" sets the working directory to d, so that all output files are written into that location. When capturing at a high data rate, a high performance filesystem and disk should be used, and NFS partitions should be avoided. "--config c" reads configuration information from the file c. [-a or --analysis] performs analysis and reports results in the "analysis" object in the JSON records. This option only works with the option [-f or --fingerprint]. "--format=f" reports fingerprints with formats(s) f, where f is either a fingerprint protocol and format like "tls/1", or is a comma separated list of below fingerprint protocol and format strings. tls tls/1 tls/2 quic quic/1 "[-l or --limit] l" rotates output files so that each file has at most l records or packets; filenames include a sequence number, date and time. --dns-json writes out DNS responses as a JSON object; otherwise, that data is output in base64 format, as a string with the key "base64". --certs-json writes out certificates as JSON objects; otherwise, that data is output in base64 format, as a string with the key "base64". --metadata writes out additional metadata into the protocol JSON objects. --raw-features selects protocols to write out raw features string into the protocol JSON object which can be comma separated list of following strings: bittorrent Bittorrent Handshake Message, LSD message, DHT message smb SMB v2, v3 messages ssdp SSDP (UPnP) stun Stun messages tls TLS clientHello all All of the above none None of the above None of the above --http-headers=mode controls which HTTP headers are reported in L7 metadata. non-sensitive report all headers except sensitive ones (cookie, authorization, proxy-authorization, etc.) all report all headers including sensitive ones --http-body-max=N reports up to N bytes of the HTTP body as hex. N is required and must be between 0 and 2048. If this option is not specified, HTTP bodies are not captured. --network-behavioral-detections performs analysis on packets, sessions, and sets of sessions independent of the core mercury analysis functionality. These are not driven by the resources file. An example detection includes detecting residential proxies. --minimize-ram minimizes the ram usage of mercury library by reducing classifer features and minimizing the maximum reassembly segments. [-v or --verbose] writes additional information to the standard error, including the packet count, byte count, elapsed time and processing rate, as well as information about threads and files. --license and --version write their information to stdout, then halt. [-h or --help] writes this extended help message to stdout. ``` ### 系统 默认安装使用的目录如下。运行 **mercury --help** 以 查看您系统上的目录是否有所不同。 ``` Resource files used in analysis: /usr/local/share/mercury Systemd service output: /usr/local/var/mercury Systemd service configuration /etc/mercury/mercury.cfg ``` ### 示例 ``` mercury -c auto # auto-detect iface, metadata to stdout mercury -c eth0 -w foo.pcap # capture from eth0, write to foo.pcap mercury -c eth0 -w foo.pcap -t cpu # as above, with one thread per CPU mercury -c eth0 -w foo.mcap -t cpu -s # as above, selecting packet metadata mercury -r foo.mcap -f foo.json # read foo.mcap, write fingerprints mercury -r foo.mcap -f foo.json -a # as above, with fingerprint analysis mercury -c eth0 -t cpu -f foo.json -a # capture and analyze fingerprints ``` ## 道德规范 Mercury 旨在用于防御性网络监控、安全研究和取证。研究人员、管理员、渗透测试人员和安全运营团队可以使用这些工具来保护网络、检测漏洞,并通过提升安全意识和防御态势来造福更广泛的社区。与任何数据包监控工具一样,Mercury 也有可能被滥用。**请勿在您不是所有者或管理员的任何网络上运行它**。 ## 致谢 本软件包包含由 MaxMind 创建的 GeoLite2 数据,可从 [https://www.maxmind.com](https://www.maxmind.com) 获取。 我们使用了 Mozilla 的 [Public Suffix List](https://publicsuffix.org/list/),其受 [Mozilla Public License, v. 2.0](https://mozilla.org/MPL/2.0/) 条款约束。 本软件包直接整合了其他开发者制作的一些软件, 以使软件包更易于构建、部署和运行。我们 对版权所有者表示感激,感谢他们允许在可重新分发的 许可条款下提供其优秀的软件。 * RapidJSON [https://github.com/cisco/mercury/blob/main/src/libmerc/rapidjson/license.txt](src/libmerc/rapidjson/license.txt); 此软件包的版权所有者为 2015 THL A29 Limited, a Tencent company, 以及 Milo Yip。 * lctrie [https://github.com/cisco/mercury/tree/main/src/libmerc/lctrie](src/libmerc/lctrie); 此软件包的版权所有者为 2016-2017 Charles Stewart
标签:AF_PACKET, Bash脚本, C/C++, Python, 事务性I/O, 元数据提取, 安全测试工具, 恶意活动检测, 无后门, 网络协议指纹, 网络流量分析, 请求拦截, 进程保护, 逆向工具, 防御绕过