Phil Young [Mon, 1 Jun 2020 15:01:06 +0000 (11:01 -0400)]
Napatech: Change to use separate FlowStream handle for each thread
Previously a single handle to the FlowStream (which is used to program
flows to the card) was shared between the threads. This resulted
in contention between the threads where sometimes programming the flow would
silently fail.
Jason Ish [Mon, 4 May 2020 17:42:47 +0000 (11:42 -0600)]
fileinfo: use addr info cache for address logging (jsonbuilder prep)
This is to prepare for JsonBuilder conversion where we can't
overwrite an already set value. Here we prepare the addresses
to be logged in a struct, overwite with XFF if needed, then
log.
Jason Ish [Sun, 15 Mar 2020 17:05:16 +0000 (11:05 -0600)]
alert/eve: convert to jsonbuilder
Convert alert Eve logging JsonBuilder. Currently
makes heavy use of JsonBuilder being able to log Jansson's json_t
which is a temporary measure until all protocols loggers can be
converted to JsonBuilder.
New functions that replace Jansson versions with JsonBuilder
variations use "Eve" instead of "JSON".
Jason Ish [Tue, 7 Jan 2020 19:08:29 +0000 (13:08 -0600)]
jsonbuilder: new module for generating json
JsonBuilder is a Rust module for creating JSON output. Unlike
Jansson, the final JSON string is built up as items are added,
instead of building up an object tree and rendering it when
done.
The idea is to create a more efficient JSON serializer instead
of a flexible one.
Jason Ish [Sun, 15 Mar 2020 15:50:45 +0000 (09:50 -0600)]
flow/eve: separate flow and app_proto logging (jsonbuilder prep)
Currently the flow logger also logs app_proto information,
but not to the flow object, but instead to the root object
of the log record.
Refactor into 2 separate methods, one for the app_proto
and one for the flow, to make this more clear, as well
as make it easier to refactor for JsonBuilder as JsonBuilder
can only write to the currently open object.
Jason Ish [Fri, 13 Mar 2020 19:25:56 +0000 (13:25 -0600)]
eve/fivetuple: use intermediate address struct (jsonbuilder prep)
Currently alert logging relies on the ability to change existing
values in the json_t structure to overwrite addresses with xff
data. This feature is also used for the "target" logging.
As we can't do this with JsonBuilder, create a new struct to
hold the 5 tuple, with the values swapped as needed, and
overwritten with XFF data if needed. This struct will now
be used to write out the 5 tuple, as well as cache the information
for log fields to be written out later on in the log path.
Philippe Antoine [Tue, 26 May 2020 06:46:24 +0000 (08:46 +0200)]
ssh: handles incomplete record after banner
To signal incomplete data, we must return the number of
consumed bytes. When we get a banner and some records, we have
to take into account the number of bytes already consumed by
the banner parsing before reaching an incomplete record.
Jeff Lucovsky [Wed, 6 May 2020 12:10:44 +0000 (08:10 -0400)]
detect/pcre: Use the keyword context for JIT stack
When PCRE `jit` is available, store the JIT stack in the keyword context
instead of on a global id. This ensures proper cleanup and
re-initialization over a rule reload.
Jason Ish [Tue, 28 Apr 2020 16:29:17 +0000 (10:29 -0600)]
github actions: extract repo/branch names from PR message
Create a "prep" build that parses libhtp, suricata-update and
suricata-verify repo and branch information from the pull
request message and turn these into artifacts that are
used by the builders
All the dead code in C after the Rust implementation is hereby removed.
Invalid/migrated tests have also been deleted.
All the function calls in C have been replaced with appropriate calls to
Rust functions. Same has been done for smb/detect.rs as a part of this
migration.
This parser rewrites the DCE/RPC protocol implementation of Suricata
in Rust. More tests have been added to improve the coverage and some
fixes have been made to the tests already written in C. Most of the
valid tests from C have been imported to Rust.
File anatomy
src/dcerpc.rs
This file contains the implementation of single transactions in DCE/RPC
over TCP. It takes care of REQUEST, RESPONSE, BIND and BINDACK business
logic before and after the data parsing. DCERPCState holds the state
corresponding to a particular transaction and handles all important
aspects. It also defines any common structures and constants required
for DCE/RPC parsing irrespective of the carrier protocol.
src/dcerpc_udp.rs
This file contains the implementation of single transactions in DCE/RPC
over UDP. It takes care of REQUEST and RESPONSE parsing. It borrows the
Request and Response structs from src/dcerpc.rs.
src/detect.rs
This file contains the implementation of dce_iface and opnum detect
keywords. Both the parsing and the matching is taken care of by
functions in this file. Tests have been rewritten with the test data
from C.
src/parser.rs
This file contains all the nom parsers written for DCERPCRequest,
DCERPCResponse, DCERPCBind, DCERPCBindAck, DCERPCHeader, DCERPCHdrUdp.
It also implements functions to assemble and convert UUIDs. All the
fields have their endianness defined unless its an 8bit field or an
unusable one, then it's little endian but it won't make any difference.
src/mod.rs
This file contains all the modules of dcerpc folder which should be
taken into account during compilation.
Function calls
This is a State-wise implementation of the protocol for single
transaction only i.e. a valid state object is required to parse any
record. Function calls start with the app layer parser in C which
detects the application layer protocol to be DCE/RPC and calls the
appropriate functions in C which in turn make a call to these functions
in Rust using FFI. All the necessary information is passed from C to the
parsers and handlers in Rust.
Implementation
When a batch of input comes in, there is an analysis of whether the
input header and the direction is appropriate. Next check is about the
size of fragment. If it is as defined by the header, process goes
through else the data is buffered and more data is awaited. After this,
type of record as indicated by the header is checked. A call to the
appropriate handler is made. After the handling, State is updated with
the latest information about whatever record came in.
AppLayerResult::ok() is returned in case all went well else
AppLayerResult::err() is returned indicating something went wrong.
Victor Julien [Sun, 5 Apr 2020 12:35:29 +0000 (14:35 +0200)]
decode: cleanup packet properly on bad packets
In case of bad IPv4, TCP or UDP, the per packet ip4vars/tcpvars/udpvar
structures would not be cleaned up because the cleanup depends on the
'header' pointer being set, but the error handling would unset that.
This could mean these structures were already filled with values before
the error was detected. As packets were recycled, the next packet decoding
would use this unclean structure.
To make things worse these structures are part of unions. IPv4/IPv6 and
TCP/ICMPv4/ICMPv6 share the same memory location.
LibFuzzer+UBSAN found this both locally and in Oss-Fuzz:
decode-ipv6.c:654:9: runtime error: load of value 6, which is not a valid value for type 'bool'
#0 0x6146f0 in DecodeIPV6 /src/suricata/src/decode-ipv6.c:654:9
#1 0x617e96 in DecodeNull /src/suricata/src/decode-null.c:70:13
#2 0x9dd8a4 in DecodePcapFile /src/suricata/src/source-pcap-file.c:412:9
#3 0x4c8ed2 in LLVMFuzzerTestOneInput /src/suricata/src/tests/fuzz/fuzz_sigpcap.c:158:25
#4 0x457e51 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:556:15
#5 0x457575 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:470:3
#6 0x459917 in fuzzer::Fuzzer::MutateAndTestOne() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:698:19
#7 0x45a6a5 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:830:5
#8 0x448728 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:824:6
#9 0x472552 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:19:10
#10 0x7ff0d097b82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#11 0x41bde8 in _start (/out/fuzz_sigpcap+0x41bde8)
Victor Julien [Mon, 20 Apr 2020 05:06:31 +0000 (07:06 +0200)]
ssl: support multi-frag certificate assembly
Support reassembling multi-frag certificates. For this the cert queuing
code is changed to queue just the cert, not entire tls record.
Improve message tracking. Better track where a message starts and ends
before passing data around.
Add wrapper macros to check for 'impossible' conditions that are activate
in debug validation mode. This helps fuzzers find input that might trigger
these conditions, if they exist.
Victor Julien [Sun, 19 Apr 2020 09:56:58 +0000 (11:56 +0200)]
ssl: improve 'first cert' check to avoid leaks
In some error conditions, or potentially in case of multiple 'certificate'
records, the extracted subject, issuerdn and serial could be overwritten
without freeing the original memory.
Victor Julien [Fri, 3 Apr 2020 15:03:47 +0000 (17:03 +0200)]
ssl: fix handshake cert buffer sizing
'trec' buffer was not grown properly when it was checked as too small.
After this it wasn't checked again so that copying into the buffer could
overflow it.