diff --git a/CHANGES b/CHANGES index c0e6ada5f4..15bb9ff761 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,23 @@ +2.4-10 | 2015-06-25 07:11:17 -0700 + + * Correct a name used in a header identifier (Justin Azoff) + +2.4-8 | 2015-06-24 07:50:50 -0700 + + * Restore the --load-seeds cmd-line option and enable the short + options -G/-H for --load-seeds/--save-seeds. (Daniel Thayer) + +2.4-6 | 2015-06-19 16:26:40 -0700 + + * Generate protocol confirmations for Modbus, making it appear as a + confirmed service in conn.log. (Seth Hall) + + * Put command line options in alphabetical order. (Daniel Thayer) + + * Removing dead code for no longer supported -G switch. (Robin + Sommer) (Robin Sommer) + 2.4 | 2015-06-09 07:30:53 -0700 * Release 2.4. diff --git a/VERSION b/VERSION index 6b4950e3de..f9a814dbf7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.4 +2.4-10 diff --git a/aux/btest b/aux/btest index 80b42ee3e4..0e2da116a5 160000 --- a/aux/btest +++ b/aux/btest @@ -1 +1 @@ -Subproject commit 80b42ee3e4503783b6720855b28e83ff1658c22b +Subproject commit 0e2da116a5e29baacaecc6daac7bc4bc9ff387c5 diff --git a/src/analyzer/protocol/modbus/modbus-analyzer.pac b/src/analyzer/protocol/modbus/modbus-analyzer.pac index c9b0861428..5a862b7604 100644 --- a/src/analyzer/protocol/modbus/modbus-analyzer.pac +++ b/src/analyzer/protocol/modbus/modbus-analyzer.pac @@ -47,6 +47,42 @@ %} +refine connection ModbusTCP_Conn += { + %member{ + // Fields used to determine if the protocol has been confirmed or not. + bool confirmed; + bool orig_pdu; + bool resp_pdu; + %} + + %init{ + confirmed = false; + orig_pdu = false; + resp_pdu = false; + %} + + function SetPDU(is_orig: bool): bool + %{ + if ( is_orig ) + orig_pdu = true; + else + resp_pdu = true; + + return true; + %} + + function SetConfirmed(): bool + %{ + confirmed = true; + return true; + %} + + function IsConfirmed(): bool + %{ + return confirmed && orig_pdu && resp_pdu; + %} +}; + refine flow ModbusTCP_Flow += { function deliver_message(header: ModbusTCP_TransportHeader): bool @@ -62,6 +98,21 @@ refine flow ModbusTCP_Flow += { return true; %} + function deliver_ModbusTCP_PDU(message: ModbusTCP_PDU): bool + %{ + // We will assume that if an entire PDU from both sides + // is successfully parsed then this is definitely modbus. + connection()->SetPDU(${message.is_orig}); + + if ( ! connection()->IsConfirmed() ) + { + connection()->SetConfirmed(); + connection()->bro_analyzer()->ProtocolConfirmation(); + } + + return true; + %} + # EXCEPTION function deliver_Exception(header: ModbusTCP_TransportHeader, message: Exception): bool %{ diff --git a/src/analyzer/protocol/modbus/modbus-protocol.pac b/src/analyzer/protocol/modbus/modbus-protocol.pac index a79e4dccf5..e5b92169b4 100644 --- a/src/analyzer/protocol/modbus/modbus-protocol.pac +++ b/src/analyzer/protocol/modbus/modbus-protocol.pac @@ -64,6 +64,8 @@ type ModbusTCP_PDU(is_orig: bool) = record { true -> request: ModbusTCP_Request(header); false -> response: ModbusTCP_Response(header); }; +} &let { + deliver: bool = $context.flow.deliver_ModbusTCP_PDU(this); } &length=header.len+6, &byteorder=bigendian; type ModbusTCP_TransportHeader = record { diff --git a/src/input/readers/sqlite/SQLite.h b/src/input/readers/sqlite/SQLite.h index f4cae7d01f..5d82bc55f1 100644 --- a/src/input/readers/sqlite/SQLite.h +++ b/src/input/readers/sqlite/SQLite.h @@ -1,7 +1,7 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef INPUT_READERS_POSTGRES_H -#define INPUT_READERS_POSTGRES_H +#ifndef INPUT_READERS_SQLITE_H +#define INPUT_READERS_SQLITE_H #include "config.h" @@ -50,5 +50,5 @@ private: } } -#endif /* INPUT_READERS_POSTGRES_H */ +#endif /* INPUT_READERS_SQLITE_H */ diff --git a/src/main.cc b/src/main.cc index be38f6ca39..2ef6aa50b6 100644 --- a/src/main.cc +++ b/src/main.cc @@ -181,8 +181,8 @@ void usage() fprintf(stderr, " -r|--readfile | read from given tcpdump file\n"); fprintf(stderr, " -s|--rulefile | read rules from given file\n"); fprintf(stderr, " -t|--tracefile | activate execution tracing\n"); - fprintf(stderr, " -w|--writefile | write to given tcpdump file\n"); fprintf(stderr, " -v|--version | print version and exit\n"); + fprintf(stderr, " -w|--writefile | write to given tcpdump file\n"); fprintf(stderr, " -x|--print-state | print contents of state file\n"); fprintf(stderr, " -z|--analyze | run the specified policy file analysis\n"); #ifdef DEBUG @@ -190,6 +190,8 @@ void usage() #endif fprintf(stderr, " -C|--no-checksums | ignore checksums\n"); fprintf(stderr, " -F|--force-dns | force DNS\n"); + fprintf(stderr, " -G|--load-seeds | load seeds from given file\n"); + fprintf(stderr, " -H|--save-seeds | save seeds to given file\n"); fprintf(stderr, " -I|--print-id | print out given ID\n"); fprintf(stderr, " -J|--set-seed | set the random number seed\n"); fprintf(stderr, " -K|--md5-hashkey | set key for MD5-keyed hashing\n"); @@ -211,8 +213,6 @@ void usage() fprintf(stderr, " -X | print contents of state file as XML\n"); #endif fprintf(stderr, " --pseudo-realtime[=] | enable pseudo-realtime for performance evaluation (default 1)\n"); - fprintf(stderr, " --load-seeds | load seeds from given file\n"); - fprintf(stderr, " --save-seeds | save seeds to given file\n"); #ifdef USE_IDMEF fprintf(stderr, " -n|--idmef-dtd | specify path to IDMEF DTD file\n"); @@ -549,7 +549,7 @@ int main(int argc, char** argv) opterr = 0; char opts[256]; - safe_strncpy(opts, "B:e:f:I:i:J:K:n:p:R:r:s:T:t:U:w:x:X:z:CFNPSWabdghvQ", + safe_strncpy(opts, "B:e:f:G:H:I:i:J:K:n:p:R:r:s:T:t:U:w:x:X:z:CFNPQSWabdghv", sizeof(opts)); #ifdef USE_PERFTOOLS_DEBUG @@ -584,6 +584,10 @@ int main(int argc, char** argv) dump_cfg = true; break; + case 'h': + usage(); + break; + case 'i': interfaces.append(optarg); break; @@ -605,10 +609,19 @@ int main(int argc, char** argv) g_trace_state.TraceOn(); break; + case 'v': + fprintf(stderr, "%s version %s\n", prog, bro_version()); + exit(0); + break; + case 'w': writefile = optarg; break; + case 'x': + bst_file = optarg; + break; + case 'z': if ( streq(optarg, "notice") ) do_notice_analysis = 1; @@ -619,6 +632,10 @@ int main(int argc, char** argv) } break; + case 'B': + debug_streams = optarg; + break; + case 'C': override_ignore_checksums = 1; break; @@ -690,13 +707,8 @@ int main(int argc, char** argv) do_watchdog = 1; break; - case 'h': - usage(); - break; - - case 'v': - fprintf(stderr, "%s version %s\n", prog, bro_version()); - exit(0); + case 'X': + broxygen_config = optarg; break; #ifdef USE_PERFTOOLS_DEBUG @@ -709,9 +721,6 @@ int main(int argc, char** argv) break; #endif - case 'x': - bst_file = optarg; - break; #if 0 // broken case 'X': bst_file = optarg; @@ -719,10 +728,6 @@ int main(int argc, char** argv) break; #endif - case 'X': - broxygen_config = optarg; - break; - #ifdef USE_IDMEF case 'n': fprintf(stderr, "Using IDMEF XML DTD from %s\n", optarg); @@ -730,10 +735,6 @@ int main(int argc, char** argv) break; #endif - case 'B': - debug_streams = optarg; - break; - case 0: // This happens for long options that don't have // a short-option equivalent. diff --git a/testing/btest/Baseline/scripts.base.protocols.modbus.events/conn.log b/testing/btest/Baseline/scripts.base.protocols.modbus.events/conn.log new file mode 100644 index 0000000000..484c5a0223 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.modbus.events/conn.log @@ -0,0 +1,18 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2015-06-19-21-05-46 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +1093521678.945447 CXWv6p3arKYeMETxOg 10.0.0.57 2387 10.0.0.3 502 tcp - 0.000493 0 0 SF - - 0 FafA 2 80 2 80 (empty) +1093521953.490353 CCvvfg3TEfuqmmG4bh 10.0.0.57 2579 10.0.0.8 502 tcp modbus 23.256631 24 0 SF - - 0 ShADaFf 6 272 5 208 (empty) +1093521681.696827 CjhGID4nQcgTWjvg4c 10.0.0.57 2578 10.0.0.3 502 tcp modbus 385.694948 112 138 S3 - - 0 ShADdf 20 920 12 626 (empty) +1093522326.102435 CsRx2w45OKnoww6xl4 10.0.0.9 3082 10.0.0.3 502 tcp modbus 177.095534 72 69 SF - - 0 ShADdFaf 16 720 9 437 (empty) +1093522946.554059 CRJuHdVW0XPVINV8a 10.0.0.57 2585 10.0.0.8 502 tcp - 76.561880 926 0 SF - - 0 ShADafF 8 1254 7 288 (empty) +1093523065.562221 CPbrpk1qSsw6ESzHV4 10.0.0.8 502 10.0.0.57 4446 tcp - 155.114237 128 0 SF - - 0 ShADaFf 16 776 15 608 (empty) +1153491879.610371 C6pKV8GSxOnSLghOa 192.168.66.235 2582 166.161.16.230 502 tcp - 2.905078 0 0 S0 - - 0 S 2 96 0 0 (empty) +1153491888.530306 CIPOse170MGiRM1Qf4 192.168.66.235 2582 166.161.16.230 502 tcp modbus 85.560847 1692 1278 S1 - - 0 ShADad 167 8380 181 8522 (empty) +1342774499.588269 C7XEbhP654jzLoe3a 10.1.1.234 51411 10.10.5.85 502 tcp modbus 2100.811351 237936 4121200 S2 - - 0 ShADdaF 39659 2300216 20100 5166412 (empty) +#close 2015-06-19-21-05-51 diff --git a/testing/btest/scripts/base/protocols/modbus/events.bro b/testing/btest/scripts/base/protocols/modbus/events.bro index a5fe26be9c..fe748fa3dc 100644 --- a/testing/btest/scripts/base/protocols/modbus/events.bro +++ b/testing/btest/scripts/base/protocols/modbus/events.bro @@ -5,6 +5,8 @@ # @TEST-EXEC: cat ${DIST}/src/analyzer/protocol/modbus/events.bif | grep "^event modbus_" | wc -l >total # @TEST-EXEC: echo `cat covered` of `cat total` events triggered by trace >coverage # @TEST-EXEC: btest-diff coverage +# @TEST-EXEC: btest-diff conn.log + event modbus_message(c: connection, headers: ModbusHeaders, is_orig: bool) {