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

DNS: fix check for DGA domain #2716

Merged
merged 1 commit into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions example/ndpiReader.c
Original file line number Diff line number Diff line change
Expand Up @@ -5187,12 +5187,12 @@ static void dgaUnitTest() {

for(i=0; non_dga[i] != NULL; i++) {
if(debug) printf("Checking non DGA %s\n", non_dga[i]);
assert(ndpi_check_dga_name(ndpi_str, NULL, (char*)non_dga[i], 1, 1) == 0);
assert(ndpi_check_dga_name(ndpi_str, NULL, (char*)non_dga[i], 1, 1, 0) == 0);
}

for(i=0; dga[i] != NULL; i++) {
if(debug) printf("Checking DGA %s\n", non_dga[i]);
assert(ndpi_check_dga_name(ndpi_str, NULL, (char*)dga[i], 1, 1) == 1);
assert(ndpi_check_dga_name(ndpi_str, NULL, (char*)dga[i], 1, 1, 0) == 1);
}

ndpi_exit_detection_module(ndpi_str);
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_dga.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (name) {
memcpy(name, data, size);
name[size] = '\0';
ndpi_check_dga_name(ndpi_struct, ndpi_flow, name, 1, 1);
ndpi_check_dga_name(ndpi_struct, ndpi_flow, name, 1, 1, 0);
ndpi_free(name);
}

Expand Down
3 changes: 2 additions & 1 deletion src/include/ndpi_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -1227,7 +1227,8 @@ extern "C" {
/* DGA */
int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
struct ndpi_flow_struct *flow,
char *name, u_int8_t is_hostname, u_int8_t check_subproto);
char *name, u_int8_t is_hostname, u_int8_t check_subproto,
u_int8_t flow_fully_classified);

/* Serializer (supports JSON, TLV, CSV) */

Expand Down
5 changes: 3 additions & 2 deletions src/lib/ndpi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10830,7 +10830,8 @@ static int ndpi_is_vowel(char c) {

int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
struct ndpi_flow_struct *flow,
char *name, u_int8_t is_hostname, u_int8_t check_subproto) {
char *name, u_int8_t is_hostname, u_int8_t check_subproto,
u_int8_t flow_fully_classified) {

/* Get domain name if ndpi_load_domain_suffixes(..) has been called */
name = (char*)ndpi_get_host_domain(ndpi_str, name);
Expand Down Expand Up @@ -10863,7 +10864,7 @@ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
)
return(0);

if(flow && (flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN))
if(flow && (flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN || flow_fully_classified))
return(0); /* Ignore DGA check for protocols already fully detected */

if(check_subproto &&
Expand Down
6 changes: 4 additions & 2 deletions src/lib/protocols/dns.c
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,8 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
ndpi_get_current_time(flow));
}

ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 0, ret.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN);

if(!ndpi_struct->cfg.dns_subclassification_enabled)
ret.proto.app_protocol = NDPI_PROTOCOL_UNKNOWN;

Expand All @@ -830,8 +832,6 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
else
ret.proto.master_protocol = NDPI_PROTOCOL_DNS;

ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 0);

/* Category is always NDPI_PROTOCOL_CATEGORY_NETWORK, regardless of the subprotocol */
flow->category = NDPI_PROTOCOL_CATEGORY_NETWORK;
}
Expand All @@ -854,6 +854,8 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
return; /* The response will set the verdict */
}

if(strlen(flow->host_server_name) > 0)

flow->protos.dns.num_queries = (u_int8_t)dns_header.num_queries,
flow->protos.dns.num_answers = (u_int8_t) (dns_header.num_answers + dns_header.authority_rrs + dns_header.additional_rrs);

Expand Down
2 changes: 1 addition & 1 deletion src/lib/protocols/fastcgi.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ static void ndpi_search_fastcgi(struct ndpi_detection_module_struct *ndpi_struct
strlen(flow->host_server_name),
&ret_match, NDPI_PROTOCOL_FASTCGI, 1);
ndpi_check_dga_name(ndpi_struct, flow,
flow->host_server_name, 1, 0);
flow->host_server_name, 1, 0, 0);
if(ndpi_is_valid_hostname((char *)packet->host_line.ptr,
packet->host_line.len) == 0) {
char str[128];
Expand Down
2 changes: 1 addition & 1 deletion src/lib/protocols/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
ndpi_http_parse_subprotocol(ndpi_struct, flow, hostname_just_set);

if(hostname_just_set && strlen(flow->host_server_name) > 0) {
ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 0);
ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 0, 0);
}

ndpi_check_http_header(ndpi_struct, flow);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/protocols/netbios.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ static void ndpi_int_netbios_add_connection(struct ndpi_detection_module_struct
(u_int)(packet->payload_packet_len - off), name, sizeof(name)-1) > 0) {
ndpi_hostname_sni_set(flow, (const u_int8_t *)name, strlen((char *)name), NDPI_HOSTNAME_NORM_ALL);

ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 1);
ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 1, 0);
}

if(sub_protocol == NDPI_PROTOCOL_UNKNOWN)
Expand Down
2 changes: 1 addition & 1 deletion src/lib/protocols/quic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1464,7 +1464,7 @@ void process_chlo(struct ndpi_detection_module_struct *ndpi_struct,
flow->protos.tls_quic.client_hello_processed = 1; /* Allow matching of custom categories */

ndpi_check_dga_name(ndpi_struct, flow,
flow->host_server_name, 1, 0);
flow->host_server_name, 1, 0, 0);

if(ndpi_is_valid_hostname((char *)&crypto_data[tag_offset_start + prev_offset],
len) == 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/protocols/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -2813,7 +2813,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
ndpi_set_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST, sni);
}

if(ndpi_check_dga_name(ndpi_struct, flow, sni, 1, 0)) {
if(ndpi_check_dga_name(ndpi_struct, flow, sni, 1, 0, 0)) {
#ifdef DEBUG_TLS
printf("[TLS] SNI: (DGA) [%s]\n", sni);
#endif
Expand Down
4 changes: 2 additions & 2 deletions tests/cfgs/default/result/nintendo.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ JA Host Stats:
12 UDP 192.168.12.114:52119 -> 52.10.205.177:34343 [proto: 265/AmazonAWS][IP: 265/AmazonAWS][Encrypted][Confidence: Match by IP][FPC: 265/AmazonAWS, Confidence: IP address][DPI packets: 1][cat: Cloud/13][1 pkts/730 bytes -> 0 pkts/0 bytes][Goodput ratio: 94/0][< 1 sec][Risk: ** Susp Entropy **** Unidirectional Traffic **][Risk Score: 20][Risk Info: No server to client traffic / Entropy: 7.623 (Encrypted or Random?)][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,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]
13 ICMP 151.6.184.98:0 -> 192.168.12.114:0 [proto: 81/ICMP][IP: 0/Unknown][ClearText][Confidence: DPI][FPC: 81/ICMP, Confidence: DPI][DPI packets: 1][cat: Network/14][9 pkts/630 bytes -> 0 pkts/0 bytes][Goodput ratio: 40/0][0.60 sec][bytes ratio: 1.000 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 75/0 316/0 130/0][Pkt Len c2s/s2c min/avg/max/stddev: 70/0 70/0 70/0 0/0][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 100,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,0,0,0,0]
14 UDP 192.168.12.114:55915 <-> 35.158.74.61:10025 [proto: 265/AmazonAWS][IP: 265/AmazonAWS][Encrypted][Confidence: Match by IP][FPC: 265/AmazonAWS, Confidence: IP address][DPI packets: 7][cat: Cloud/13][5 pkts/290 bytes <-> 5 pkts/290 bytes][Goodput ratio: 27/27][0.06 sec][bytes ratio: 0.000 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 1/1 4/3 2/1][Pkt Len c2s/s2c min/avg/max/stddev: 58/58 58/58 58/58 0/0][Plen Bins: 100,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,0,0,0,0]
15 UDP 192.168.12.114:18874 <-> 192.168.12.1:53 [proto: 5/DNS][IP: 0/Unknown][ClearText][Confidence: DPI][FPC: 5/DNS, Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/110 bytes <-> 1 pkts/281 bytes][Goodput ratio: 61/85][0.03 sec][Hostname/SNI: e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com][54.192.27.217][Risk: ** Susp DGA Domain name **** Risky Domain Name **][Risk Score: 150][Risk Info: e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com / DGA Name Query with no Error Code][PLAIN TEXT (fb203858ebc)][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]
16 UDP 192.168.12.114:51035 <-> 192.168.12.1:53 [proto: 5/DNS][IP: 0/Unknown][ClearText][Confidence: DPI][FPC: 5/DNS, Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/110 bytes <-> 1 pkts/281 bytes][Goodput ratio: 61/85][< 1 sec][Hostname/SNI: e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com][54.192.27.8][Risk: ** Susp DGA Domain name **** Risky Domain Name **][Risk Score: 150][Risk Info: e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com / DGA Name Query with no Error Code][PLAIN TEXT (fb203858ebc)][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]
15 UDP 192.168.12.114:18874 <-> 192.168.12.1:53 [proto: 5/DNS][IP: 0/Unknown][ClearText][Confidence: DPI][FPC: 5/DNS, Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/110 bytes <-> 1 pkts/281 bytes][Goodput ratio: 61/85][0.03 sec][Hostname/SNI: e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com][54.192.27.217][PLAIN TEXT (fb203858ebc)][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]
16 UDP 192.168.12.114:51035 <-> 192.168.12.1:53 [proto: 5/DNS][IP: 0/Unknown][ClearText][Confidence: DPI][FPC: 5/DNS, Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/110 bytes <-> 1 pkts/281 bytes][Goodput ratio: 61/85][< 1 sec][Hostname/SNI: e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com][54.192.27.8][PLAIN TEXT (fb203858ebc)][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]
17 UDP 192.168.12.114:52119 -> 35.158.74.61:33335 [proto: 173/Nintendo][IP: 265/AmazonAWS][ClearText][Confidence: DPI][FPC: 173/Nintendo, Confidence: DPI][DPI packets: 1][cat: Game/8][3 pkts/354 bytes -> 0 pkts/0 bytes][Goodput ratio: 64/0][0.00 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,100,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,0,0]
18 UDP 192.168.12.114:55915 -> 35.158.74.61:33335 [proto: 265/AmazonAWS][IP: 265/AmazonAWS][Encrypted][Confidence: Match by IP][FPC: 265/AmazonAWS, Confidence: IP address][DPI packets: 3][cat: Cloud/13][3 pkts/318 bytes -> 0 pkts/0 bytes][Goodput ratio: 60/0][0.00 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][PLAIN TEXT (NATTestId)][Plen Bins: 0,0,100,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,0,0]
19 UDP 192.168.12.114:55915 -> 52.10.205.177:34343 [proto: 265/AmazonAWS][IP: 265/AmazonAWS][Encrypted][Confidence: Match by IP][FPC: 173/Nintendo, Confidence: DNS][DPI packets: 1][cat: Cloud/13][1 pkts/298 bytes -> 0 pkts/0 bytes][Goodput ratio: 86/0][< 1 sec][Risk: ** Susp Entropy **** Unidirectional Traffic **][Risk Score: 20][Risk Info: No server to client traffic / Entropy: 6.886 (Compressed Executable?)][Plen Bins: 0,0,0,0,0,0,0,0,100,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]
Expand Down
2 changes: 1 addition & 1 deletion tests/dga/dga_evaluate.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ int main(int argc, char **argv) {
while(fgets(buffer, sizeof(buffer), fd) != NULL) {
char *hostname = strtok(buffer, "\n");

if(ndpi_check_dga_name(ndpi_str, NULL, hostname, 1, 1)) {
if(ndpi_check_dga_name(ndpi_str, NULL, hostname, 1, 1, 0)) {
if(verbose)
printf("%10s\t%s\n", "[DGA]", hostname);

Expand Down
Loading