From a422f60a9a5feddeb0597bdf7d3e4b6c869cd204 Mon Sep 17 00:00:00 2001 From: _Frky <3105926+Frky@users.noreply.github.com> Date: Thu, 23 Dec 2021 11:03:40 +0100 Subject: [PATCH] Add test to emphasis bug in HTTP FSM --- src/proto/mod.rs | 30 +++++++++++++++++++++++++++++ test/src/all.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/src/proto/mod.rs b/src/proto/mod.rs index 9000eca..291002b 100644 --- a/src/proto/mod.rs +++ b/src/proto/mod.rs @@ -285,4 +285,34 @@ mod tests { }; } } + + #[test] + fn test_proto_repl_http() { + /* ensure that HTTP FSM does not answer until completion of request + * (at least headers) */ + let mut client_info = ClientInfo::new(); + let test_ip_addr = Ipv4Addr::new(3, 2, 1, 0); + client_info.ip.src = Some(IpAddr::V4(test_ip_addr)); + client_info.port.src = Some(65000); + let masscanned_ip_addr = Ipv4Addr::new(0, 1, 2, 3); + let mut ips = HashSet::new(); + ips.insert(IpAddr::V4(masscanned_ip_addr)); + /* Construct masscanned context object */ + let masscanned = Masscanned { + synack_key: [0, 0], + mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"), + iface: None, + ip_addresses: Some(&ips), + }; + /***** TEST COMPLETE REQUEST *****/ + let payload = b"GET / HTTP/1.1\r\n\r\n"; + if let None = repl(&payload.to_vec(), &masscanned, &mut client_info) { + panic!("expected an answer, got nothing"); + } + /***** TEST INCOMPLETE REQUEST *****/ + let payload = b"GET / HTTP/1.1\r\n"; + if let Some(_) = repl(&payload.to_vec(), &masscanned, &mut client_info) { + panic!("expected no answer, got one"); + } + } } diff --git a/test/src/all.py b/test/src/all.py index c73d65b..214a249 100644 --- a/test/src/all.py +++ b/test/src/all.py @@ -537,6 +537,56 @@ def test_ipv4_tcp_http(): assert tcp.payload.load.startswith(b"HTTP/1.1 401 Unauthorized\n") +@test +def test_ipv4_tcp_http_incomplete(): + sport = 24595 + dports = [80, 443, 5000, 53228] + for dport in dports: + seq_init = int(RandInt()) + syn = ( + Ether(dst=MAC_ADDR) + / IP(dst=IPV4_ADDR) + / TCP(flags="S", sport=sport, dport=dport, seq=seq_init) + ) + syn_ack = srp1(syn, timeout=1) + assert syn_ack is not None, "expecting answer, got nothing" + check_ip_checksum(syn_ack) + assert TCP in syn_ack, "expecting TCP, got %r" % syn_ack.summary() + syn_ack = syn_ack[TCP] + assert syn_ack.flags == "SA", "expecting TCP SA, got %r" % syn_ack.flags + ack = ( + Ether(dst=MAC_ADDR) + / IP(dst=IPV4_ADDR) + / TCP( + flags="A", + sport=sport, + dport=dport, + seq=seq_init + 1, + ack=syn_ack.seq + 1, + ) + ) + _ = srp1(ack, timeout=1) + req = ( + Ether(dst=MAC_ADDR) + / IP(dst=IPV4_ADDR) + / TCP( + flags="PA", + sport=sport, + dport=dport, + seq=seq_init + 1, + ack=syn_ack.seq + 1, + ) + # purposedly incomplete request (missing additionnal ending \r\n) + / Raw("GET / HTTP/1.1\r\n") + ) + resp = srp1(req, timeout=1) + assert resp is not None, "expecting an answer, got none" + check_ip_checksum(resp) + assert TCP in resp, "expecting TCP, got %r" % resp.summary() + tcp = resp[TCP] + assert tcp.flags == "A", "expecting TCP flag A, got {}".format(tcp.flags) + + @test def test_ipv6_tcp_http(): sport = 24592