Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an heuristic to detect/ignore some anomalous TCP ACK packets #1948

Merged
merged 1 commit into from
Apr 25, 2023

Conversation

IvanNardi
Copy link
Collaborator

@IvanNardi IvanNardi commented Apr 18, 2023

In some networks, there are some anomalous TCP flows where the smallest
ACK packets have some kind of zero padding.
It looks like the IP and TCP headers in those frames wrongly consider the
0x00 Ethernet padding bytes as part of the TCP payload.
While this kind of packets is perfectly valid per-se, in some conditions
they might be treated by the TCP reassembler logic as (partial) overlaps,
deceiving the classification engine.
Add an heuristic to detect these packets and to ignore them, allowing
correct detection/classification.

This heuristic is configurable. Default value:

  • in the library, it is disabled
  • in ndpiReader and in the fuzzers, it is enabled (to ease testing)

Credit to @vel21ripn for the initial patch.

Close #1946

@IvanNardi IvanNardi mentioned this pull request Apr 18, 2023
@IvanNardi IvanNardi marked this pull request as draft April 18, 2023 09:38
@IvanNardi
Copy link
Collaborator Author

Still a proof-of-concept. Some notes:

  • it works for all kinds of TCP traffic
  • the check is strict enough that it is never triggered with the test traces

Missing:

  • configuration to enable/disable
  • example

@vel21ripn
Copy link
Contributor

I selected 3 good traffic examples for testing #1498.
Look in the "padding" branch of my repository in the utils/tcp_check_seq/samples_for_tests directory.

@IvanNardi
Copy link
Collaborator Author

I selected 3 good traffic examples for testing #1498. Look in the "padding" branch of my repository in the utils/tcp_check_seq/samples_for_tests directory.

I quickly tested the traces in your repository and it seems this patch works, IMO.
Do you agree?

@vel21ripn
Copy link
Contributor

Yes! Your version works better.
You need to rename the traffic sample files for the tests and add them to the rest of the tests.

@IvanNardi
Copy link
Collaborator Author

@vel21ripn , thanks for the confirmation
I'll push a complete version

@IvanNardi IvanNardi changed the title WIP - Issue 1946 Add an heuristic to detect/ignore some anomalous TCP ACK packets Apr 20, 2023
@IvanNardi IvanNardi marked this pull request as ready for review April 20, 2023 18:50
@vel21ripn
Copy link
Contributor

I found another option for incorrect packet processing.

12:41:28.015038 IP 194.226.199.103.62580 > 217.69.139.59.443: Flags [S], seq 4211199516, win 8192, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
12:41:28.025503 IP 217.69.139.59.443 > 194.226.199.103.62580: Flags [S.], seq 1907400742:1907400744, ack 4211199517, win 14100, options [mss 1410], length 2
12:41:29.574311 IP 217.69.139.59.443 > 194.226.199.103.62580: Flags [S.], seq 1907400742:1907400744, ack 4211199517, win 14100, options [mss 1410], length 2
12:41:29.574986 IP 194.226.199.103.62580 > 217.69.139.59.443: Flags [.], seq 1:3, ack 1, win 64860, length 2

SYN+ACK with length 2

The second packet (syn+ack) gets into the non-empty packet handler.
This patch fixes the error, but perhaps there is a more accurate version.

diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 12efcee..0837b83 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -5617,6 +5617,10 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str,
          if(flow->num_processed_pkts > 1)
            flow->next_tcp_seq_nr[1 - packet->packet_direction] = ntohl(tcph->ack_seq);
        }
+        if(tcph->syn) {
+           NDPI_LOG_DBG2(ndpi_str, "TCP SYN with zero padding. Ignored\n");
+          packet->tcp_retransmission = 1;
+        }
       } else if(packet->payload_packet_len > 0) {
        /* check tcp sequence counters */
        if(tcp_ack_padding(packet)) {

@IvanNardi
Copy link
Collaborator Author

I found another option for incorrect packet processing.

12:41:28.015038 IP 194.226.199.103.62580 > 217.69.139.59.443: Flags [S], seq 4211199516, win 8192, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
12:41:28.025503 IP 217.69.139.59.443 > 194.226.199.103.62580: Flags [S.], seq 1907400742:1907400744, ack 4211199517, win 14100, options [mss 1410], length 2
12:41:29.574311 IP 217.69.139.59.443 > 194.226.199.103.62580: Flags [S.], seq 1907400742:1907400744, ack 4211199517, win 14100, options [mss 1410], length 2
12:41:29.574986 IP 194.226.199.103.62580 > 217.69.139.59.443: Flags [.], seq 1:3, ack 1, win 64860, length 2

SYN+ACK with length 2

The second packet (syn+ack) gets into the non-empty packet handler. This patch fixes the error, but perhaps there is a more accurate version.

diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 12efcee..0837b83 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -5617,6 +5617,10 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str,
          if(flow->num_processed_pkts > 1)
            flow->next_tcp_seq_nr[1 - packet->packet_direction] = ntohl(tcph->ack_seq);
        }
+        if(tcph->syn) {
+           NDPI_LOG_DBG2(ndpi_str, "TCP SYN with zero padding. Ignored\n");
+          packet->tcp_retransmission = 1;
+        }
       } else if(packet->payload_packet_len > 0) {
        /* check tcp sequence counters */
        if(tcp_ack_padding(packet)) {

@vel21ripn , are you able to share a pcap with this new pattern?

@vel21ripn
Copy link
Contributor

I found an even more interesting example of traffic.
Look in the "padding" branch of my repository in the utils/tcp_check_seq/samples_syn_retrans directory.

@IvanNardi
Copy link
Collaborator Author

I found an even more interesting example of traffic. Look in the "padding" branch of my repository in the utils/tcp_check_seq/samples_syn_retrans directory.

In vel21ripn@6f0c659 there are not SYN-ACK packets with len != 0...
(yes, these 2 traces are not properly classified because of issues with the reassembler code, but it seems another, unrelated issue compared to #1946)

@vel21ripn
Copy link
Contributor

I added a sample traffic with syn+ack+padding

@IvanNardi
Copy link
Collaborator Author

I added a sample traffic with syn+ack+padding

Pushed a new version handling the SYN/ACK case

@IvanNardi
Copy link
Collaborator Author

Even the other 2 traces seems working now

In some networks, there are some anomalous TCP flows where the smallest
ACK packets have some kind of zero padding.
It looks like the IP and TCP headers in those frames wrongly consider the
0x00 Ethernet padding bytes as part of the TCP payload.
While this kind of packets is perfectly valid per-se, in some conditions
they might be treated by the TCP reassembler logic as (partial) overlaps,
deceiving the classification engine.
Add an heuristic to detect these packets and to ignore them, allowing
correct detection/classification.

This heuristic is configurable. Default value:
* in the library, it is disabled
* in `ndpiReader` and in the fuzzers, it is enabled (to ease testing)

Credit to @vel21ripn for the initial patch.

Close ntop#1946
@sonarcloud
Copy link

sonarcloud bot commented Apr 21, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

Copy link
Collaborator

@utoni utoni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! :)

@IvanNardi
Copy link
Collaborator Author

@vel21ripn , what do you think? Can we merge this PR?

@vel21ripn
Copy link
Contributor

Yes.

@IvanNardi IvanNardi merged commit 8934f7b into ntop:dev Apr 25, 2023
34 checks passed
@IvanNardi IvanNardi deleted the issue-1946 branch April 25, 2023 17:25
vel21ripn added a commit to vel21ripn/nDPI that referenced this pull request Apr 28, 2023
Fix for pre ntop#1948

Fix bytes order for SHA-1 output

Changed logic guessed_protocol.
We use guessed_protocol_id as app_protocol if it is not excluded.
If guessed_protocol_id_by_ip is found, it will be used as
app_protocol if not already defined, otherwise it can be used as
master_protocol if not already defined.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TLS not detected
3 participants