Git Product home page Git Product logo

mercury's Introduction

Mercury: network metadata capture and analysis

This package contains two programs for fingerprinting network traffic and capturing and analyzing packet metadata: mercury, a Linux application that leverages the modern Linux kernel's high-performance networking capabilities (AF_PACKET and TPACKETv3), which is described below, and pmercury, a portable python application. There is also a User's Guide. While mercury is used in some production applications, please consider this software as a 'beta'. The CHANGELOG itemizes changes across different versions.

Overview

Mercury reads network packets, identifies metadata of interest, and writes out the metadata in JSON format. Alternatively, mercury can write out the packets that contain the metadata in the PCAP file format. Mercury can scale up to high data rates (40Gbps on server-class hardware); it uses zero-copy ring buffers to acquire packets, and packets are processed by independent worker threads. The amount of memory consumed by the ring buffers, and the number of worker threads, are configurable; this makes it easy to scale up (but be wary of using too much memory).

Mercury produces fingerprint strings for TLS, DTLS, SSH, HTTP, TCP, and other protocols; these fingerprints are formed by carefully selecting and normalizing metadata extracted from packets (as documented here). Fingerprint strings are reported in the "fingerprint" object in the JSON output. Optionally, mercury can perform process identification based on those fingerprints and the destination context; these results are reported in the "analysis" object.

Contents

Building and installing mercury

Mercury itself has minimal dependencies other than a g++ or llvm build environment, but to run the automated tests and ancillary programs in this package, you will need to install additional packages, as in the following Debian/Ubuntu example:

sudo apt install g++ jq git zlib1g-dev tcpreplay valgrind python3-pip libssl-dev clang
pip3 install jsonschema

To build mercury, in the root directory, run

./configure
make

to build the package (and check for the programs and python modules required to test it). TPACKETv3 is present in Linux kernels newer than 3.2.

Installation

In the root directory, edit mercury.cfg with the network interface you want to capture from, then run

./configure
make

sudo make install MERCURY_CFG=mercury.cfg

to install mercury and create and start a systemd service. If you don't want the mercury systemd service to be installed, then instead run

sudo make install-nosystemd

The default file and directory locations are

  • /usr/local/bin/mercury for the executable
  • /usr/local/share/mercury for the resource files
  • /usr/local/var/mercury for the output files
  • /etc/mercury/mercury.cfg for the configuration file
  • /etc/systemd/system/mercury.service for the systemd unit file

The output file directory is owned by the user mercury; this user is created by the 'make install' target, which must be run as root. The installation prefix /usr/local/ can be changed by running ./configure with the --prefix argument, for instance `--prefix=$HOME'. If you want to install the program somewhere in your home directory, you probably don't want to create the user mercury; you should use the 'make install-nonroot' target, which does not create a user, does not install anything into /etc, and does not install a systemd unit.

The easiest way to run mercury in capture mode is using systemd; the OS automatically starts the mercury systemd unit after each boot, and halts it when the OS is shut down. To check its status, run

systemctl status mercury

and the output should contain 'active (running)'. To view the log (stderr) output from the mercury unit, run

sudo journalctl -u mercury

To uninstall mercury, run

sudo make uninstall

which will remove the mercury program, resources directory, user, group, and systemd related files. The directory containing capture files will be retained, but its owner will be changed to root, to avoid unintentional data loss. All captured data files are retained across successive installs and uninstalls, and must be manually deleted.

Compile-time options

To create a debugging version of mercury, use the make debug-mercury target in the src/ subdirectory. Be sure to run make clean first.

There are compile-time options that can tune mercury for your hardware. Each of these options is set via a C/C++ preprocessor directive, which should be passed as an argument to "make" through the OPTFLAGS variable. Frst run make clean to remove the previous build, then run make "OPTFLAGS=". This runs make, telling it to pass to the C/C++ compiler. The available compile time options are:

  • -DDEBUG, which turns on debugging, and
  • -FBUFSIZE=16384, which sets the fwrite/fread buffer to 16,384 bytes (for instance). If multiple compile time options are used, then they must be passed to make together in the OPTFLAGS string, e.g. "OPTFLAGS=-DDEBUG -DFBUFSIZE=16384".

Running mercury

mercury: packet metadata capture and analysis
./src/mercury [INPUT] [OUTPUT] [OPTIONS]:
INPUT
   [-c or --capture] capture_interface   # capture packets from interface
   [-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
   --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
   --tcp-reassembly                      # reassemble tcp data 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
   [-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 with Linux AF_PACKET
   using a separate ring buffer for each worker thread.  "[-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.

   "[-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:
      dhcp              DHCP discover message
      dns               DNS messages
      dtls              DTLS clientHello, serverHello, and certificates
      http              HTTP request and response
      http.request      HTTP request
      http.response     HTTP response
      iec               IEC 60870-5-104
      mdns              multicast DNS
      nbns              NetBIOS Name Service
      openvpn_tcp       OpenVPN over TCP
      quic              QUIC handshake
      ssh               SSH handshake and KEX
      smb               SMB v1 and v2
      stun              STUN messages
      ssdp              SSDP (UPnP)
      tcp               TCP headers
      tcp.message       TCP initial message
      tls               TLS clientHello, serverHello, and certificates
      tls.client_hello  TLS clientHello
      tls.server_hello  TLS serverHello
      tls.certificates  TLS serverCertificates
      wireguard         WG handshake initiation message
      all               all of the above
      <no option>       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.

   --tcp-reassembly enables the tcp reassembly
   This option allows mercury to keep track of tcp segment state and 
   and reassemble these segments based on the application in tcp 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].

   "[-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.

   [-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.

SYSTEM

The directories used by the default install are as follows. Run mercury --help to see if the directories on your system differ.

   Resource files used in analysis: /usr/local/share/mercury
   Systemd service output:          /usr/local/var/mercury
   Systemd service configuration    /etc/mercury/mercury.cfg

EXAMPLES

   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

Ethics

Mercury is intended for defensive network monitoring, security research and forensics. Researchers, administrators, penetration testers, and security operations teams can use these tools to protect networks, detect vulnerabilities, and benefit the broader community through improved awareness and defensive posture. As with any packet monitoring tool, Mercury could potentially be misused. Do not run it on any network of which you are not the owner or the administrator.

Credits

Mercury and this package was developed by David McGrew, Brandon Enright, Blake Anderson, Lucas Messenger, Adam Weller, Andrew Chi, Shekhar Acharya, Anastasiia-Mariia Antonyk, Oleksandr Stepanov, Vigneshwari Viswanathan, and Apoorv Raj, with input from Brian Long, Bill Hudson, and others. Pmercury was developed by Blake Anderson, with input from others.

Acknowledgments

This package includes GeoLite2 data created by MaxMind, available from https://www.maxmind.com.

We make use of Mozilla's Public Suffix List which is subject to the terms of the Mozilla Public License, v. 2.0.

This package directly incorporates some software made by other developers, to make the package easier to build, deploy, and run. We are grateful to the copyright holders for making their excellent software available under licensing terms that allow its redistribution.

mercury's People

Contributors

andrewchi avatar arunkayambu avatar banderson84 avatar bmenrigh avatar davidmcgrew avatar hardaker avatar sheachar avatar shubrajp avatar vigneshwariv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mercury's Issues

Please support "Linux Netfilter NFLOG"

I captured packets through following codes on Android devices
`
iptables -A OUTPUT -p udp --dport 53 -j CONNMARK --set-mark ${userId}

iptables -A OUTPUT -m owner --uid-owner ${userId} -j CONNMARK --set-mark ${userId}

iptables -A INPUT -m connmark --mark ${userId} -j NFLOG --nflog-group ${userId}

iptables -A OUTPUT -m connmark --mark ${userId} -j NFLOG --nflog-group ${userId}

nohup tcpdump -i nflog:${userId} -w ${pcapPath} > /dev/null 2>&1 &
`
but I cannot analyse this pcap, because the packet wrapped by "Linux Netfilter NFLOG".

[Patch] Support for overriding default compilers

Summary

I have been working on building Mercury for Amazon Linux 2 (AL2). AL2 has GCC, but is an older version that doesn't support C++17 standards. This requires me to install GCC10 instead:

yum install gcc10 gcc10-c++

The problem that emerges is that GCC10 for AL2 (and likely other RHEL based distros) doesn't install GCC10 as /usr/bin/gcc, but rather /usr/bin/gcc10-gcc (also applies to g++) as well.

The solution for this is to override CC, CPP, and CXX during make, however there are a handful of places in checked in Makefiles which assumes uses g++ directly rather than the CXX variable.

make CC=/usr/bin/gcc10-gcc CPP=/usr/bin/gcc10-cpp CXX=/usr/bin/gcc10-c++ V=s

Solution

I have include the patch for updating Makefiles to use the build time compiler and not static paths. Also uploaded here.

diff --git a/src/Makefile.in b/src/Makefile.in
index 85c1bb2..9154890 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -225,7 +225,7 @@ libmerc_driver:
 #
 
 intercept.so: intercept.cc libmerc.a
-	g++ -std=c++17 -Wall -Wno-narrowing intercept.cc libmerc/pkt_proc.cc -D_GNU_SOURCE -I/usr/include/nspr/ -fPIC -shared -lssl -lnspr4 -lgnutls libmerc/libmerc.a -o intercept.so
+	$(CXX) -std=c++17 -Wall -Wno-narrowing intercept.cc libmerc/pkt_proc.cc -D_GNU_SOURCE -I/usr/include/nspr/ -fPIC -shared -lssl -lnspr4 -lgnutls libmerc/libmerc.a -o intercept.so
 
 # special targets
 #
diff --git a/src/libmerc/lctrie/Makefile b/src/libmerc/lctrie/Makefile
index bbc45e7..5bc2b5a 100644
--- a/src/libmerc/lctrie/Makefile
+++ b/src/libmerc/lctrie/Makefile
@@ -12,7 +12,6 @@ clean:
 	rm -f lctrie_test
 	rm -f liblctrie.a
 
-CC     = g++
 CFLAGS = -g -ggdb -std=c++11 -Wall -O3 -fPIC # -Wno-sign-compare
 LDFLAGS = -g -ggdb -O3
 LDLIBS =
@@ -23,7 +22,7 @@ DEPDIR := .d
 $(shell mkdir -p $(DEPDIR) >/dev/null)
 DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
 
-COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+COMPILE.c = $(CXX) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
 COMPILE.cc = $(CXX) $(DEPFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
 POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
 

Please let me know if you have any questions.

cert_analyze

cert_analyze command line
What command should I enter to extract the certificate characteristics of the pcap file?
Thank you.

Configure shouldn't be doing installs

If you just run ./configure as a regular user it fails because:

Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: '/usr/local/lib64/python3.7'
Consider using the `--user` option or check the permissions.

In general, configure scripts should actually modify the system or other envornments. Maybe move that to make?

"Null/Loopback" protocol captures not supported in "pmercury" or "mercury"

When capturing on a tunnel interface (at least on a MAC), the L2 header information is set to Null (more details below)...

https://wiki.wireshark.org/NullLoopback

See example below...
"null": {
"null.family": "2"
}

% tshark -T json -i utun0
Capturing on 'USB 10/100/1000 LAN: en7'
[
  {
    "_index": "packets-2021-05-12",
    "_type": "doc",
    "_score": null,
    "_source": {
      "layers": {
        "frame": {
          "frame.interface_id": "0",
          "frame.interface_id_tree": {
            "frame.interface_name": "en7",
            "frame.interface_description": "USB 10/100/1000 LAN"
          },
          "frame.encap_type": "1",
          "frame.time": "May 12, 2021 11:54:07.695295000 MST",
          "frame.offset_shift": "0.000000000",
          "frame.time_epoch": "1620845647.695295000",
          "frame.time_delta": "0.000000000",
          "frame.time_delta_displayed": "0.000000000",
          "frame.time_relative": "0.000000000",
          "frame.number": "1",
          "frame.len": "1514",
          "frame.cap_len": "1514",
          "frame.marked": "0",
          "frame.ignored": "0",
          "frame.protocols": "null:ip:tcp:data"
        },
        "null": {
          "null.family": "2"
        },
        "ip": {
          "ip.version": "4",
          "ip.hdr_len": "20",
          "ip.dsfield": "0x00000002",
          "ip.dsfield_tree": {
            "ip.dsfield.dscp": "0",
            "ip.dsfield.ecn": "2"
          },
          "ip.len": "1500",
          "ip.id": "0x00006391",
          "ip.flags": "0x00000040",
          "ip.flags_tree": {
            "ip.flags.rb": "0",
            "ip.flags.df": "1",
            "ip.flags.mf": "0"
          },
          ...

buffer overflow when accessing std::vector

Hi,

While running AddressSanitizer on a real traffic I hit the following crash:

READ of size 8 at 0x6030036242c8 thread T0 (ntdp-builtin)                                                                                                                                                            
    #0 0x7f379598c744 in std::vector<os_information, std::allocator<os_information> >::data() /usr/include/c++/8/bits/stl_vector.h:1056
    #1 0x7f379597db7e in fingerprint_data::perform_analysis(char const*, char const*, unsigned short) ../../src/engine/features/mercury/dp/analysis.h:433
    #2 0x7f379597f194 in classifier::perform_analysis(char const*, char const*, char const*, unsigned short) ../../src/engine/features/mercury/dp/analysis.h:832
    #3 0x7f379597f595 in classifier::analyze_fingerprint_and_destination_context(fingerprint const&, destination_context const&, analysis_result&) ../../src/engine/features/mercury/dp/analysis.h:842
    #4 0x7f3795988e89 in do_analysis::operator()(tls_client_hello&) ../../src/engine/features/mercury/dp/pkt_proc.cc:716
    #5 0x7f3795993701 in bool std::__invoke_impl<bool, do_analysis, tls_client_hello&>(std::__invoke_other, do_analysis&&, tls_client_hello&) /usr/include/c++/8/bits/invoke.h:60
    #6 0x7f379598e8c2 in std::__invoke_result<do_analysis, tls_client_hello&>::type std::__invoke<do_analysis, tls_client_hello&>(do_analysis&&, tls_client_hello&) /usr/include/c++/8/bits/invoke.h:95
    #7 0x7f379598ae78 in std::__detail::__variant::__gen_vtable_impl<std::__detail::__variant::_Multi_array<bool (*)(do_analysis&&, std::variant<std::monostate, http_request, http_response, tls_client_hello, tls_server_hello_and_certificate, ssh_init_packet, ssh_kex_init, smtp_client, smtp_server, unknown_initial_packet>&)>, std::tuple<std::variant<std::monostate, http_request, http_response, tls_client_hello, tls_server_hello_and_certificate, ssh_init_packet, ssh_kex_init, smtp_client, smtp_server, unknown_initial_packet>&>, std::integer_sequence<unsigned long, 3ul> >::__visit_invoke(do_analysis&&, std::variant<std::monostate, http_request, http_response, tls_client_hello, tls_server_hello_and_certificate, ssh_init_packet, ssh_kex_init, smtp_client, smtp_server, unknown_initial_packet>&) /usr/include/c++/8/variant:830
    #8 0x7f379598b0f7 in decltype(auto) std::visit<do_analysis, std::variant<std::monostate, http_request, http_response, tls_client_hello, tls_server_hello_and_certificate, ssh_init_packet, ssh_kex_init, smtp_client, smtp_server, unknown_initial_packet>&>(do_analysis&&, std::variant<std::monostate, http_request, http_response, tls_client_hello, tls_server_hello_and_certificate, ssh_init_packet, ssh_kex_init, smtp_client, smtp_server, unknown_initial_packet>&) /usr/include/c++/8/variant:1386

Memory was allocated here:

0x6030036242c8 is located 0 bytes to the right of 24-byte region [0x6030036242b0,0x6030036242c8)
allocated by thread T1 here:                                                                                                                                                                                         
    #0 0x7f3795f0fd30 in operator new(unsigned long) (/lib/x86_64-linux-gnu/libasan.so.5+0xead30)
    #1 0x7f379585d5f3 in __gnu_cxx::new_allocator<std::vector<os_information, std::allocator<os_information> > >::allocate(unsigned long, void const*) /usr/include/c++/8/ext/new_allocator.h:111
    #2 0x7f3795855ac1 in std::allocator_traits<std::allocator<std::vector<os_information, std::allocator<os_information> > > >::allocate(std::allocator<std::vector<os_information, std::allocator<os_information> > >&, unsigned long) (../lib/libntdp.so+0x368ac1)
    #3 0x7f379584a323 in std::_Vector_base<std::vector<os_information, std::allocator<os_information> >, std::allocator<std::vector<os_information, std::allocator<os_information> > > >::_M_allocate(unsigned long) (../lib/libntdp.so+0x35d323)
    #4 0x7f379583c85c in std::vector<os_information, std::allocator<os_information> >* std::vector<std::vector<os_information, std::allocator<os_information> >, std::allocator<std::vector<os_information, std::allocator<os_information> > > >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<std::vector<os_information, std::allocator<os_information> > const*, std::vector<std::vector<os_information, std::allocator<os_information> >, std::allocator<std::vector<os_information, std::allocator<os_information> > > > > >(unsigned long, __gnu_cxx::__normal_iterator<std::vector<os_information, std::allocator<os_information> > const*, std::vector<std::vector<os_information, std::allocator<os_information> >, std::allocator<std::vector<os_information, std::allocator<os_information> > > > >, __gnu_cxx::__normal_iterator<std::vector<os_information, std::allocator<os_information> > const*, std::vector<std::vector<os_information, std::allocator<os_information> >, std::allocator<std::vector<os_information, std::allocator<os_information> > > > >) (../lib/libntdp.so+0x34f85c)
    #5 0x7f379582b67d in std::vector<std::vector<os_information, std::allocator<os_information> >, std::allocator<std::vector<os_information, std::allocator<os_information> > > >::operator=(std::vector<std::vector<os_information, std::allocator<os_information> >, std::allocator<std::vector<os_information, std::allocator<os_information> > > > const&) (../lib/libntdp.so+0x33e67d)
    #6 0x7f379581b8a3 in fingerprint_data::operator=(fingerprint_data const&) (../lib/libntdp.so+0x32e8a3)
    #7 0x7f379581e763 in classifier::process_fp_db_line(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, float, float, bool) (../lib/libntdp.so+0x331763)
    #8 0x7f379581fe3a in classifier::classifier(encrypted_compressed_archive&, float, float, bool) (../lib/libntdp.so+0x332e3a)
    #9 0x7f379580ef4b in analysis_init_from_archive(int, char const*, unsigned char const*, enc_key_type, float, float, bool) ../../src/engine/features/mercury/dp/analysis.cc:49
    #10 0x7f379589e092 in mercury::mercury(libmerc_config const*, int) ../../src/engine/features/mercury/dp/pkt_proc.h:42
    #11 0x7f3795893bbb in mercury_init ../../src/engine/features/mercury/dp/libmerc.cc:49

Seems like the issue hits here:
os_info_data = process_os_info_vector[index_max].data();

where index_max is hitting just at the end:
0x6030036242c8 is located 0 bytes to the right of 24-byte region

Big Sur Mac Support Documentation

Any guidance compiling this for Big Sur, I get compiling errors, but I was able to compile and install Cisco Joy just fine, what are the dependencies I am missing for Mercury?

reassembled PDU Parse error

Hello, in the PMercury project when TLS1.2 is parsed, the method in the readable field will be retrieved incorrectly.
12
34

Support Python 3.9

Looks like due to pypcap not supporting it, it can't be compiled with python3.9:

pynetwork/pypcap#102

Is there any plans to work around this to get python3.9 support for pmercury?

Unable to install latest pypi versions of pmercury on ARM platforms

Looks like the way the latest versions were uploaded to pypi don't make it compatible with other platforms like it did it earlier versions:

#21 [linux/arm64 5/5] RUN pip3 install --no-cache-dir -r requirements.txt
#21 11.99 ERROR: Could not find a version that satisfies the requirement pmercury==0.4.3.16 (from -r requirements.txt (line 2)) (from versions: 0.1.0.0, 0.1.1.0, 0.1.3.1, 0.2.0.1, 0.2.1.2, 0.2.1.3)

It would useful to be able to install this on ARM like it used to be.

Mercury in capture mode can have high CPU utilization after suspend

After resuming from a suspend, mercury may cause high CPU utilization, in cases where it was running in capture mode before the suspend operation. Workarounds:

  1. Don't suspend while mercury is running, or
  2. Restart mercury; if you are using systemctl, as with the default install, you can perform 'sudo systemctl restart mercury'.

Speculation about the root cause: it is possible that the mercury code that uses the AF_PACKET ring buffer(s) shared with the kernel are getting out of sync during the suspend/resume process, and the application code keeps reading through the circular buffer in an attempt to catch up with the kernel.

Inputs into pmercury.protocols.tls.fingerprint()

Hello,

I'm attempting to use the fingerprint function from pmercury.protocols.tls in a python script. Can more documentation be provided about the data, offset, and data_len parameters of the fingerprint functions, e.g. data type? From what I can tell, offset and data_len are integers and data is a list, but I can't tell what's in this list. Are they strings and integers? If so, how do we map what's parsed from a PCAP into inputs to the fingerprint function? Better yet, map string input fields from sources like Zeek's conn.log, ssl.log, or x509.log? Ideally, I would understand what fields and their formats the fingerprint function is appending to c and context. My goal is to pipeline input into this function, but without more documentation, I can't anticipate what the format of the data input needs to be to ensure the function doesn't output a faulty fingerprint.

TLS fingerprint format

in doc/npf.md it is stated that:

The "tls/1" fingerprint format is

"tls/1" (TLS_Version) (TLS_Ciphersuite) [ QUIC_Extension* ]

and the older "tls" fingerprint format is

"tls/" (TLS_Version) (TLS_Ciphersuite) ((TLS_Extension)*)

but the mercury tool provides fingerprints of these formats:

"tls/1/(0303)...

or

tls/(0303)...

which means that either is the npf.md is wrong, and the format of the tls/1 should be changed to:

"tls/1/" (TLS_Version) (TLS_Ciphersuite) [ QUIC_Extension* ]

or that the resulting fingerprint from the mercury tool is incorrect and should be:

"tls/1(0303)...

I offer to fix the issue in case someone can confirm which is the incorrect one.
(i believe it is the first case, and the npf.md tls/1 format should be changed to "tls/1/" (TLS_Version) ...)

concern regarding TLS extension sorting

I came across this today:

The newer one, "tls/1", sorts the extensions into lexicographic order, to compensate for the randomization of those fields introduced by some TLS clients.

https://github.com/cisco/mercury/blob/main/doc/npf.md#tls

which is concerning. some servers, such as android.googleapis.com, are sensitive to the extension order. This is not theoretical. for example, using these extensions:

&RenegotiationInfoExtension{},
&SNIExtension{},
&UtlsExtendedMasterSecretExtension{},
&SessionTicketExtension{},
&SignatureAlgorithmsExtension{},
&StatusRequestExtension{},
&ALPNExtension{},
&SupportedPointsExtension{},
&SupportedCurvesExtension{},

I get this result:

200 OK

if I swap the first two, I get this:

403 Forbidden

So if extensions are sorted, then an NPF cannot be used to reconstruct the original client hello, which would make it useless for actually making network requests. So imagine this conversation:

A: hello I cannot connect to this server, can anyone help?
B: sure just use tls/1...
A: it doesn't work...
B: ...

Also, this is confusing:

The "tls/1" fingerprint format is

   "tls/1" (TLS_Version) (TLS_Ciphersuite) [ QUIC_Extension* ]

and the older "tls" fingerprint format is

   "tls/" (TLS_Version) (TLS_Ciphersuite) ((TLS_Extension)*)

supposedly tls/1 sorts the extensions, but it also lists QUIC_Extension. does that mean only QUIC hellos can be sorted?

pmercury UnicodeDecodeError: HTTP user-agent (\x99)

{
	'src_ip': 'x.x.x.x',
	'dst_ip': 'x.x.x.x',
	'src_port': 10630,
	'dst_port': 80,
	'protocol': 6,
	'event_start': 1295981648.965332,
	'fingerprints': {
		'http': '(474554)(485454502f312e31)(557365722d4167656e74)(486f7374)(43616368652d436f6e74726f6c3a206e6f2d6361636865)'
	},
	'http': {
		'user_agent': b'Skype\x99 5.0',
		'host': b'ui.skype.com'
	}
}
 
 File "/usr/local/bin/pmercury", line 368, in write_record
    self.out_file_pointer.write('%s\n' % json.dumps(flow_repr))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x99 in position 290: invalid start byte

adduser not available for some distro

the makefile uses adduser --system --no-create-home --group mercury to add a new user mercury and create a same-named group.

adduser is an actual alias for useradd and may not be available in some linux distros (eg. OpenSUSE). This will cause make install to fail.

The equivalent command should be useradd --system --user-group mercury in these distros.

Extracting payload hash from network traffic

I was wondering whether it would be possible to extract payload or the payload hash from network traffic along with the fingerprints using mercury. Are there any options for it? We can do it with tcpdump but it does not give fingerprints. Any pointers will be helpful. Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.