Skip to content

Commit bb917c7

Browse files
davidmcgrewGitHub Enterprise
authored andcommitted
Merge pull request #309 from network-intelligence/dev
Merging Dev into Trunk
2 parents 4c2ebee + fbec988 commit bb917c7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+3078
-1185
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ else
192192
cd resources && $(MAKE) distclean
193193
rm -rf autom4te.cache config.log config.status Makefile_helper.mk
194194
rm -f lib/*.so
195+
-git clean -xf
195196
endif
196197

197198
.PHONY: package-deb

README.md

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,14 @@ GENERAL OPTIONS
104104
--config c # read configuration from file c
105105
[-a or --analysis] # analyze fingerprints
106106
--resources=f # use resource file f
107+
--format=f # report fingerprints with formats(s) f
107108
--stats=f # write stats to file f
108109
--stats-time=T # write stats every T seconds
109110
--stats-limit=L # limit stats to L entries
110111
[-s or --select] filter # select traffic by filter (see --help)
111112
--nonselected-tcp-data # tcp data for nonselected traffic
112113
--nonselected-udp-data # udp data for nonselected traffic
113-
--tcp-reassembly # reassemble tcp data segments
114+
--reassembly # reassemble protocol messages over multiple transport segments
114115
[-l or --limit] l # rotate output file after l records
115116
--output-time=T # rotate output file after T seconds
116117
--dns-json # output DNS as JSON, not base64
@@ -147,27 +148,43 @@ DETAILS
147148
148149
"[-s or --select] f" selects packets according to the metadata filter f, which
149150
is a comma-separated list of the following strings:
151+
arp ARP message
152+
bittorrent Bittorrent Handshake Message, LSD message, DHT message
153+
cdp CDP message
150154
dhcp DHCP discover message
155+
dnp3 DNP3 industrial control message
151156
dns DNS messages
152157
dtls DTLS clientHello, serverHello, and certificates
158+
gre GRE message
153159
http HTTP request and response
154160
http.request HTTP request
155161
http.response HTTP response
162+
icmp ICMP message
156163
iec IEC 60870-5-104
164+
lldp LLDP message
157165
mdns multicast DNS
166+
mysql MySQL Client/Server Protocol
158167
nbns NetBIOS Name Service
168+
nbds NetBIOS Datagram Service
169+
nbss NetBIOS Session Service
159170
openvpn_tcp OpenVPN over TCP
171+
ospf OSPF message
160172
quic QUIC handshake
173+
sctp SCTP message
161174
ssh SSH handshake and KEX
162175
smb SMB v1 and v2
176+
smtp SMTP client and server messages
163177
stun STUN messages
164178
ssdp SSDP (UPnP)
179+
socks SOCKS4,SOCKS5 messages
165180
tcp TCP headers
166181
tcp.message TCP initial message
182+
tcp.syn_ack TCP syn ack message
167183
tls TLS clientHello, serverHello, and certificates
168184
tls.client_hello TLS clientHello
169185
tls.server_hello TLS serverHello
170186
tls.certificates TLS serverCertificates
187+
tofsee Tofsee malware communication
171188
wireguard WG handshake initiation message
172189
all all of the above
173190
<no option> all of the above
@@ -185,10 +202,10 @@ DETAILS
185202
--select filter affects the UDP data written by this option; use
186203
'--select=none' to obtain the UDP data for each flow.
187204
188-
--tcp-reassembly enables the tcp reassembly
189-
This option allows mercury to keep track of tcp segment state and
190-
and reassemble these segments based on the application in tcp payload
191-
205+
--reassembly enables reassembly
206+
This option allows mercury to keep track of tcp or udp segment state and
207+
and reassemble these segments based on the application in payload
208+
192209
"[-u or --user] u" sets the UID and GID to those of user u, so that
193210
output file(s) are owned by this user. If this option is not set, then
194211
the UID is set to SUDO_UID, so that privileges are dropped to those of
@@ -206,6 +223,15 @@ DETAILS
206223
object in the JSON records. This option only works with the option
207224
[-f or --fingerprint].
208225
226+
"--format=f" reports fingerprints with formats(s) f, where f is either a
227+
fingerprint protocol and format like "tls/1", or is a comma separated
228+
list of below fingerprint protocol and format strings.
229+
tls
230+
tls/1
231+
tls/2
232+
quic
233+
quic/1
234+
209235
"[-l or --limit] l" rotates output files so that each file has at most
210236
l records or packets; filenames include a sequence number, date and time.
211237
@@ -224,7 +250,6 @@ DETAILS
224250
--license and --version write their information to stdout, then halt.
225251
226252
[-h or --help] writes this extended help message to stdout.
227-
228253
```
229254

230255
### SYSTEM

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.5.31
1+
2.6.1

doc/CHANGELOG.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,70 @@
11
# CHANGELOG for Mercury
22

3+
## VERSION 2.6.1
4+
* Improved STUN implementation: added test cases, fixed fingerprint
5+
feature nits, renamed variables for consistency with the RFCs, and
6+
simplified the message_type check.
7+
8+
## VERSION 2.6.0
9+
* Added reassembly for QUIC initial messages, to ensure metadata and
10+
fingerprint capture even for very long messages (e.g. due to
11+
quantum-safe cryptography or encrypted client hellos).
12+
* Added the `--reassembly` keyword, which applies to both TCP and
13+
QUIC, and retired the `--tcp-reassembly` option.
14+
* Improved support for the STUN protocol.
15+
* Added support for "classic" (RFC3489) STUN. In classic STUN,
16+
`stun.magic_cookie` field is `false` and the
17+
`stun.transaction_id` field is 16 bytes long. In modern STUN,
18+
the former field is `true` and the latter is 12 bytes long.
19+
* Added a STUN fingerprint that uses data features selected by
20+
automated feature-mining fingerprint.
21+
* The STUN "usage" (STUN/TURN/ICE/etc.) is reported in the new
22+
`stun.usage` field.
23+
* Details are now reported for the STUN
24+
attributes `BANDWIDTH`, `SOURCE-ADDRESS`, `CHANGED-ADDRESS`,
25+
`RESPONSE-ADDRESS`, and `REFLECTED-FROM`.
26+
* The `stun.message_type` field has been renamed to `stun.class`.
27+
* Added new output fields `dns.id`, `ip.version`, `ip.id`, `ip.ttl`
28+
that are present when the `--metadata` option is used.
29+
* Added a `--raw-features=<protocols>` command line option that
30+
specifies which protocols should have a raw feature vector
31+
output. Currently supported options include `bittorrent`,
32+
`smb`, `ssdp`, `stun`, `tls`, `all`, and `none`.
33+
* Refactored HTTP header processing, enabling
34+
* Non-standard delimeters are accepted, and their value is reported.
35+
* HTTP 0.9 is accepted.
36+
* With the `--metadata` option, all of the headers are output
37+
using an object to represent each key/value pair. This
38+
simplifies the processing of header keys that appear more than
39+
once in an HTTP request or response.
40+
* Added the first 512 bytes of the HTTP Body to `http` JSON records
41+
* Added BSD Loopback support for GENEVE.
42+
* Improved `tofsee` message format checking and `--stats` reporting.
43+
* Fixed the UTF-8 fuzz test seed file locations.
44+
* Changes to fingerprint and destination statistics output (`--stats`)
45+
* Removed source IP address (`src_ip`) anonymization in stats file output.
46+
* When processing a PCAP file, stats now uses lossless (blocking)
47+
processing of events. This enables the stats test to be
48+
deterministic, avoiding occasional spurious failures during `make test`.
49+
* Increased stats message queue size from 256 to 512.
50+
* Stats aggregator now uses adaptive sleep time.
51+
* Makefile addition: pre-clean the `test/` directory before
52+
running the stats test. This prevents leftover files in the
53+
test directory from throwing off the counts of mercury JSON
54+
output vs. mercury stats output.
55+
* The `--select=all` configuration option now actually selects all
56+
protocols, including layer 2 protocols like ARP.
57+
* Added the `event_start` timestamp field to layer 2 JSON records.
58+
* Improved signal handling for code safety.
59+
* TLS ALPN GREASE is now normalized to `0x0a0a (\n\n)`.
60+
* In `libmerc`, truncated fingerprints now have a `fingerprint_status`
61+
set to `fingerprint_status_unlabeled`.
62+
* Added informational messages to `libmerc`: resource file load time,
63+
total number of loaded fingerprints, and the end time of a telemetry
64+
stats dump.
65+
* Moved `hasher` to `crypto_engine.h`, so that it is more accesible.
66+
67+
368
## Version 2.5.31
469
* Mercury now outputs `tls.client.certs` and `tls.undetermined.certs`
570
as well as `tls.server.certs`, for TLS version 1.2 and earlier.

doc/npf.md

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
**Draft**
44

5-
December 6, 2022
6-
75
David McGrew (Editor)
86

97

@@ -381,6 +379,33 @@ An example of a OPENVPN fingerprint is
381379
openvpn/(06)(03)(0400)(14)(0301)(c014c00ac022c0210039003800880087c00fc00500350084c012c008c01cc01b00160013c00dc003000ac013c009c01fc01e00330032009a009900450044c00ec004002f00960041c011c007c00cc002000500040015001200090014001100080006000300ff)((000b000403000102)(000a00340032000e000d0019000b000c00180009000a00160017000800060007001400150004000500120013000100020003000f00100011)(0023)(000f000101))
382380
```
383381

382+
## STUN
383+
384+
The STUN fingerprint is formed from the messages of the "classic STUN" (RFC 3489) or modern STUN (RFC 8489) protocol. The fingerprint format is
385+
```
386+
"stun/1/" (class)(method)(magic)((attribute)*)
387+
```
388+
where the elements are defined as
389+
- `class` (string, one byte) is the (RFC 8489) class field
390+
- `method` (string, two bytes) is the (RFC 8489) method field
391+
- `magic` (string, one byte) is 01 if the Magic Cookie is present, and 00 otherwise. The former indicates modern STUN, the latter classic STUN.
392+
- `attribute` (string, variable length) contains the type field, and optionally the length and data fields, of an attribute, in the order that they appear in the message. The attribute types included in this field, and the extent of the data included, are as per the following table:
393+
```
394+
USERNAME type
395+
MESSAGE_INTEGRITY type
396+
XOR_MAPPED_ADDRESS type
397+
0x8007 type
398+
MS_VERSION type
399+
SOFTWARE type
400+
FINGERPRINT type
401+
MS_APP_ID type_length_data
402+
MS_IMPLEMENTATION_VERSION type_length_data
403+
0xc003 type
404+
GOOG_NETWORK_INFO type
405+
0xdaba type
406+
```
407+
408+
384409

385410
#### Truncated Fingerprints
386411

mercury

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ _mercury()
4141
fi
4242

4343
if [[ "$cur" == -* ]]; then
44-
COMPREPLY=( $( compgen -W '--analysis --buffer --capture --certs-json --config --directory --dns-json --fingerprint --format --help --license --limit --metadata --nonselected-tcp-data --nonselected-udp-data --output-time --read --resources --select --stats --stats-limit --stats-time --tcp-reassembly --threads --user --verbose --version --write' -- "$cur") )
44+
COMPREPLY=( $( compgen -W '--analysis --buffer --capture --certs-json --config --directory --dns-json --fingerprint --format --help --license --limit --metadata --nonselected-tcp-data --nonselected-udp-data --output-time --read --resources --select --stats --stats-limit --stats-time --reassembly --threads --user --verbose --version --write' -- "$cur") )
4545
# COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) )
4646
return 0
4747
fi

mercury.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,5 @@ verbosity = 0
5858
# set tls fingerprint format
5959
format = tls/1
6060

61-
# select tcp reassembly, for complete certificate chains
62-
tcp-reassembly
61+
# select reassembly, for complete certificate chains
62+
reassembly

src/Makefile.in

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,19 +333,19 @@ MSV ="-DMERCURY_SEMANTIC_VERSION=$(major),$(minor),$(patch)"
333333
.PHONY: increment-patchlevel increment-minor-version increment-major-version
334334
increment-patchlevel:
335335
echo $(major).$(minor).$(shell expr $(patch) + 1) > ../VERSION
336-
git add ../VERSION
336+
git add ../VERSION ../doc/CHANGELOG.md
337337
git commit -m "incrementing patchlevel"
338338
git tag -a $(major).$(minor).$(shell expr $(patch) + 1) -m "\"patchlevel increment\""
339339

340340
increment-minor-version:
341341
echo $(major).$(shell expr $(minor) + 1).0 > ../VERSION
342-
git add ../VERSION
342+
git add ../VERSION ../doc/CHANGELOG.md
343343
git commit -m "incrementing minor version"
344344
git tag -a $(major).$(shell expr $(minor) + 1).0 -m "\"minor version increment\""
345345

346346
increment-major-version:
347347
echo $(shell expr $(major) + 1).0.0 > ../VERSION
348-
git add ../VERSION
348+
git add ../VERSION ../doc/CHANGELOG.md
349349
git commit -m "incrementing major version"
350350
git tag -a $(shell expr $(major) + 1).0.0 -m "\"major version increment\""
351351

src/af_packet_v3.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ void ring_limits_init(struct ring_limits *rl, float frac); // defined below
128128
* sig_close_flag and the packet worker threads will watch
129129
* sig_close_workers.
130130
*/
131-
extern int sig_close_flag; /* Watched by the stats tracking thread, defined in signal_handling.c */
131+
extern volatile sig_atomic_t sig_close_flag; /* Watched by the stats tracking thread, defined in signal_handling.c */
132132
static int sig_close_workers = 0; /* Packet proccessing var */
133133

134134
static double time_elapsed(struct timespec *ts) {
@@ -265,10 +265,14 @@ void *stats_thread_func(void *statst_arg) {
265265
exit(255);
266266
}
267267

268-
/**
268+
/*
269269
* Enable all signals so that this thread shuts down first
270270
*/
271271
enable_all_signals();
272+
/* Block USR1 though since that's only for recovering
273+
* stalled threads
274+
*/
275+
disable_bt_signal();
272276

273277
int duration = 0, socket_drops = 0, zero_drops = 0;
274278

@@ -615,6 +619,18 @@ int af_packet_rx_ring_fanout_capture(struct thread_storage *thread_stor) {
615619

616620
fprintf(stderr, "[PACKET PROCESSOR] Thread %d with pthread id %lu (PID %u) started...\n", thread_stor->tnum, thread_stor->tid, thread_stor->kpid);
617621

622+
623+
/* Enable the bt signal for this thread which must be done before
624+
* sigsetjmp since that saves the signal mask and the siglongjmp
625+
* restores it.
626+
*
627+
* There is a brief window of time after we enable this signal
628+
* but before we call sigsetjmp() where if USR1 is recieved
629+
* the signal handler will be unable to locate the longjmp
630+
* environment and will call abort().
631+
*/
632+
enable_bt_signal();
633+
618634
/* Save this execution context so that we can restore the thread back
619635
* to this point if it stalls during packet processing.
620636
*/
@@ -628,6 +644,7 @@ int af_packet_rx_ring_fanout_capture(struct thread_storage *thread_stor) {
628644

629645
__sync_synchronize(); /* enforce memory ordering */
630646
global_thread_stall[thread_stor->tnum].used = 1;
647+
631648
} else {
632649
/* This branch of the if means a siglongjump was just performed
633650
* from our signal handler and execution is being restored
@@ -645,6 +662,7 @@ int af_packet_rx_ring_fanout_capture(struct thread_storage *thread_stor) {
645662
}
646663

647664
fprintf(stderr, "[PACKET PROCESSOR] Thread %d with pthread id %lu (PID %u) resumed execution from stall...\n", thread_stor->tnum, thread_stor->tid, thread_stor->kpid);
665+
648666
}
649667

650668
/*

src/cert_analyze.cc

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -20,59 +20,10 @@
2020
#include "libmerc/x509.h"
2121
#include "libmerc/base64.h"
2222
#include "libmerc/rapidjson/document.h"
23-
#include <openssl/evp.h>
24-
23+
#include "libmerc/crypto_engine.h"
2524

2625
// certificate hashing
2726

28-
class hasher {
29-
EVP_MD_CTX *mdctx;
30-
31-
public:
32-
33-
hasher() : mdctx{nullptr} { }
34-
35-
~hasher() {
36-
// EVP_MD_CTX_free() is preferred in v1.1.1, but unavailable in earlier versions
37-
EVP_MD_CTX_destroy(mdctx);
38-
}
39-
40-
constexpr static size_t output_size = 20;
41-
42-
void hash_buffer(const unsigned char *message, size_t message_len, unsigned char *digest, unsigned int digest_len) {
43-
44-
if ((unsigned int)EVP_MD_size(EVP_sha1()) > digest_len) {
45-
handleErrors();
46-
}
47-
48-
if (mdctx == NULL) {
49-
// EVP_MD_CTX_new() is preferred in v1.1.1, but unavailable in earlier versions
50-
if ((mdctx = EVP_MD_CTX_create()) == NULL) {
51-
handleErrors();
52-
}
53-
}
54-
55-
if (1 != EVP_DigestInit_ex(mdctx, EVP_sha1(), NULL)) {
56-
handleErrors();
57-
}
58-
59-
if (1 != EVP_DigestUpdate(mdctx, message, message_len)) {
60-
handleErrors();
61-
}
62-
63-
unsigned int tmp_len;
64-
if (1 != EVP_DigestFinal_ex(mdctx, digest, &tmp_len)) {
65-
handleErrors();
66-
}
67-
68-
}
69-
70-
void handleErrors() {
71-
fprintf(stderr, "error: EVP hash failure\n");
72-
}
73-
};
74-
75-
7627
void fprint_sha1_hash(FILE *f, const void *buffer, unsigned int len) {
7728

7829
class hasher h;

0 commit comments

Comments
 (0)