From f51d7d89475f7b3e041cb8269f54506a2f7273ad Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 19 Mar 2020 09:00:29 +0100 Subject: [PATCH] fuzz: check tcp splitting evasions in protocol detection --- .../fuzz/fuzz_applayerprotodetectgetproto.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/tests/fuzz/fuzz_applayerprotodetectgetproto.c b/src/tests/fuzz/fuzz_applayerprotodetectgetproto.c index 71202ce3df..8fb0609e85 100644 --- a/src/tests/fuzz/fuzz_applayerprotodetectgetproto.c +++ b/src/tests/fuzz/fuzz_applayerprotodetectgetproto.c @@ -24,6 +24,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) Flow *f; TcpSession ssn; bool reverse; + AppProto alproto; + AppProto alproto2; if (size < HEADER_LEN) { return 0; @@ -50,7 +52,21 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) f->protoctx = &ssn; f->protomap = FlowGetProtoMapping(f->proto); - AppLayerProtoDetectGetProto(alpd_tctx, f, data+HEADER_LEN, size-HEADER_LEN, f->proto, data[0], &reverse); + alproto = AppLayerProtoDetectGetProto(alpd_tctx, f, data+HEADER_LEN, size-HEADER_LEN, f->proto, data[0], &reverse); + if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED && f->proto == IPPROTO_TCP) { + /* If we find a valid protocol : + * check that with smaller input + * we find the same protocol or ALPROTO_UNKNOWN. + * Otherwise, we have evasion with TCP splitting + */ + for (size_t i = 0; i < size-HEADER_LEN; i++) { + alproto2 = AppLayerProtoDetectGetProto(alpd_tctx, f, data+HEADER_LEN, i, f->proto, data[0], &reverse); + if (alproto2 != ALPROTO_UNKNOWN && alproto2 != alproto) { + printf("Assertion failure : With input length %"PRIuMAX", found %s instead of %s\n", (uintmax_t) i, AppProtoToString(alproto2), AppProtoToString(alproto)); + abort(); + } + } + } UTHFreeFlow(f); return 0;