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 "Heroes of the Storm" video game signature detection. #1949

Merged
merged 28 commits into from
Apr 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7afae04
Add "HOTS" protocol
nikitamishagin Apr 19, 2023
fbd0983
Remove detection_bitmask
nikitamishagin Apr 19, 2023
0323736
Merge branch 'ntop:dev' into dev
nikitamishagin Apr 19, 2023
a371b35
Fix comment in hots.c
nikitamishagin Apr 20, 2023
301ab75
Fix info massages
nikitamishagin Apr 20, 2023
0d46930
Remove spaces in "hots" protocol name
nikitamishagin Apr 20, 2023
87c4803
Add small comment
nikitamishagin Apr 20, 2023
53a8b27
Remove redundant check of UDP flow
nikitamishagin Apr 20, 2023
00ae3f4
Add a cycle to check ports
nikitamishagin Apr 21, 2023
0c028d5
Fix hots default ports
nikitamishagin Apr 21, 2023
8c7f9cb
Add a trace for tests
nikitamishagin Apr 21, 2023
85751ba
Added OICQ dissector. (#1950)
utoni Apr 21, 2023
b6629ba
Improved debug output. (#1951)
utoni Apr 21, 2023
9470b6f
Change hots id
nikitamishagin Apr 21, 2023
f9205fe
Add "HOTS" protocol
nikitamishagin Apr 19, 2023
9fd0867
Remove detection_bitmask
nikitamishagin Apr 19, 2023
c2eec9c
Fix comment in hots.c
nikitamishagin Apr 20, 2023
0013a6d
Fix info massages
nikitamishagin Apr 20, 2023
b02fb7e
Remove spaces in "hots" protocol name
nikitamishagin Apr 20, 2023
6a447f5
Add small comment
nikitamishagin Apr 20, 2023
8383dce
Remove redundant check of UDP flow
nikitamishagin Apr 20, 2023
56d9274
Add a cycle to check ports
nikitamishagin Apr 21, 2023
78e1496
Fix hots default ports
nikitamishagin Apr 21, 2023
c11c323
Add a trace for tests
nikitamishagin Apr 21, 2023
87c12b0
Change hots id
nikitamishagin Apr 21, 2023
5991425
Merge branch 'dev' of github.com:nikitamishagin/nDPI into dev
nikitamishagin Apr 21, 2023
da96eae
Update test results
nikitamishagin Apr 22, 2023
ddff5d7
Sync utests results
IvanNardi Apr 22, 2023
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
5 changes: 2 additions & 3 deletions example/ndpiReader.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ static struct ndpi_detection_module_struct *ndpi_info_mod = NULL;
extern u_int8_t enable_doh_dot_detection;
extern u_int32_t max_num_packets_per_flow, max_packet_payload_dissection, max_num_reported_top_payloads;
extern u_int16_t min_pattern_len, max_pattern_len;
extern void ndpi_self_check_host_match(); /* Self check function */
u_int8_t dump_internal_stats;

struct ndpi_bin malloc_bins;
Expand Down Expand Up @@ -827,7 +826,7 @@ static void parseOptions(int argc, char **argv) {
switch (opt) {
case 'a':
ndpi_generate_options(atoi(optarg));
break;
exit(0);

case 'A':
dump_internal_stats = 1;
Expand Down Expand Up @@ -5198,7 +5197,7 @@ int main(int argc, char **argv) {
bitmapUnitTest();
automataUnitTest();
analyzeUnitTest();
ndpi_self_check_host_match();
ndpi_self_check_host_match(stderr);
analysisUnitTest();
compressedBitmapUnitTest();
#endif
Expand Down
4 changes: 1 addition & 3 deletions fuzz/fuzz_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
#include <assert.h>
#include "fuzzer/FuzzedDataProvider.h"

extern "C" void ndpi_self_check_host_match(); /* Self check function */

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
FuzzedDataProvider fuzzed_data(data, size);
struct ndpi_detection_module_struct *ndpi_info_mod;
Expand Down Expand Up @@ -136,7 +134,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ndpi_get_num_supported_protocols(ndpi_info_mod);
ndpi_get_ndpi_num_custom_protocols(ndpi_info_mod);

ndpi_self_check_host_match();
ndpi_self_check_host_match(stderr);

/* Basic code to try testing this "config" */
bool_value = fuzzed_data.ConsumeBool();
Expand Down
1 change: 1 addition & 0 deletions src/include/ndpi_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,7 @@ extern "C" {
u_int16_t user_proto_id);
u_int16_t ndpi_map_ndpi_id_to_user_proto_id(struct ndpi_detection_module_struct *ndpi_str,
u_int16_t ndpi_proto_id);
void ndpi_self_check_host_match(FILE *error_out);

/* Tells to called on what l4 protocol given application protocol can be found */
ndpi_l4_proto_info ndpi_get_l4_proto_info(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t ndpi_proto_id);
Expand Down
2 changes: 2 additions & 0 deletions src/include/ndpi_protocol_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ typedef enum {
NDPI_PROTOCOL_TPLINK_SHP = 332, /* TP-LINK Smart Home Protocol */
NDPI_PROTOCOL_SOURCE_ENGINE = 333,
NDPI_PROTOCOL_BACNET = 334,
NDPI_PROTOCOL_OICQ = 335,
NDPI_PROTOCOL_HOTS = 336, /* Heroes of the Storm */


#ifdef CUSTOM_NDPI_PROTOCOLS
Expand Down
2 changes: 2 additions & 0 deletions src/include/ndpi_protocols.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ void init_hsrp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int
void init_guildwars_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
void init_h323_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
void init_halflife2_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
void init_hots_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
void init_http_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
void init_iax_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
void init_icecast_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
Expand Down Expand Up @@ -238,6 +239,7 @@ void init_merakicloud_dissector(struct ndpi_detection_module_struct *ndpi_struct
void init_tailscale_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
void init_source_engine_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
void init_bacnet_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
void init_oicq_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);

/* ndpi_main.c */
extern u_int32_t ndpi_ip_port_hash_funct(u_int32_t ip, u_int16_t port);
Expand Down
77 changes: 45 additions & 32 deletions src/lib/ndpi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,20 +611,6 @@ static int ndpi_default_ports_tree_node_t_cmp(const void *a, const void *b) {

/* ******************************************************************** */

void ndpi_default_ports_tree_node_t_walker(const void *node, const ndpi_VISIT which, const int depth) {
ndpi_default_ports_tree_node_t *f = *(ndpi_default_ports_tree_node_t **) node;

printf("<%d>Walk on node %s (%u)\n", depth,
which == ndpi_preorder ?
"ndpi_preorder" :
which == ndpi_postorder ?
"ndpi_postorder" :
which == ndpi_endorder ? "ndpi_endorder" : which == ndpi_leaf ? "ndpi_leaf" : "unknown",
f->default_port);
}

/* ******************************************************************** */

static int addDefaultPort(struct ndpi_detection_module_struct *ndpi_str,
ndpi_port_range *range,
ndpi_proto_defaults_t *def,
Expand Down Expand Up @@ -875,16 +861,19 @@ void ndpi_init_protocol_match(struct ndpi_detection_module_struct *ndpi_str,
/* ******************************************************************** */

/* Self check function to be called only for testing purposes */
void ndpi_self_check_host_match() {
void ndpi_self_check_host_match(FILE *error_out) {
u_int32_t i, j;

for(i = 0; host_match[i].string_to_match != NULL; i++) {
for(j = 0; host_match[j].string_to_match != NULL; j++) {
if((i != j) && (strcmp(host_match[i].string_to_match, host_match[j].string_to_match) == 0)) {
printf("[INTERNAL ERROR]: Duplicate string detected '%s' [id: %u, id %u]\n",
host_match[i].string_to_match, i, j);
printf("\nPlease fix host_match[] in ndpi_content_match.c.inc\n");
exit(0);
if (error_out != NULL) {
fprintf(error_out,
"[NDPI] INTERNAL ERROR duplicate string detected '%s' [id: %u, id %u]\n",
host_match[i].string_to_match, i, j);
fprintf(error_out, "\nPlease fix host_match[] in ndpi_content_match.c.inc\n");
}
abort();
}
}
}
Expand All @@ -895,20 +884,34 @@ void ndpi_self_check_host_match() {
#define XGRAMS_C 26
static int ndpi_xgrams_inited = 0;
static unsigned int bigrams_bitmap[(XGRAMS_C*XGRAMS_C+31)/32];
static unsigned int imposible_bigrams_bitmap[(XGRAMS_C*XGRAMS_C+31)/32];
static unsigned int impossible_bigrams_bitmap[(XGRAMS_C*XGRAMS_C+31)/32];
static unsigned int trigrams_bitmap[(XGRAMS_C*XGRAMS_C*XGRAMS_C+31)/32];


static void ndpi_xgrams_init(unsigned int *dst,size_t dn, const char **src,size_t sn, unsigned int l) {
static void ndpi_xgrams_init(struct ndpi_detection_module_struct *ndpi_str,
unsigned int *dst, size_t dn,
const char **src, size_t sn,
unsigned int l)
{
unsigned int i,j,c;
for(i=0;i < sn && src[i]; i++) {
for(j=0,c=0; j < l; j++) {
unsigned char a = (unsigned char)src[i][j];
if(a < 'a' || a > 'z') { printf("%u: c%u %c\n",i,j,a); abort(); }
if(a < 'a' || a > 'z') {
NDPI_LOG_ERR(ndpi_str,
"[NDPI] INTERNAL ERROR ndpi_xgrams_init %u: c%u %c\n",
i,j,a);
abort();
}
c *= XGRAMS_C;
c += a - 'a';
}
if(src[i][l]) { printf("%u: c[%d] != 0\n",i,l); abort(); }
if(src[i][l]) {
NDPI_LOG_ERR(ndpi_str,
"[NDPI] INTERNAL ERROR ndpi_xgrams_init %u: c[%d] != 0\n",
i,l);
abort();
}
if((c >> 3) >= dn) abort();
dst[c >> 5] |= 1u << (c & 0x1f);
}
Expand Down Expand Up @@ -950,12 +953,12 @@ static void init_string_based_protocols(struct ndpi_detection_module_struct *ndp

if(!ndpi_xgrams_inited) {
ndpi_xgrams_inited = 1;
ndpi_xgrams_init(bigrams_bitmap,sizeof(bigrams_bitmap),
ndpi_xgrams_init(ndpi_str,bigrams_bitmap,sizeof(bigrams_bitmap),
ndpi_en_bigrams,sizeof(ndpi_en_bigrams)/sizeof(ndpi_en_bigrams[0]), 2);

ndpi_xgrams_init(imposible_bigrams_bitmap,sizeof(imposible_bigrams_bitmap),
ndpi_xgrams_init(ndpi_str,impossible_bigrams_bitmap,sizeof(impossible_bigrams_bitmap),
ndpi_en_impossible_bigrams,sizeof(ndpi_en_impossible_bigrams)/sizeof(ndpi_en_impossible_bigrams[0]), 2);
ndpi_xgrams_init(trigrams_bitmap,sizeof(trigrams_bitmap),
ndpi_xgrams_init(ndpi_str,trigrams_bitmap,sizeof(trigrams_bitmap),
ndpi_en_trigrams,sizeof(ndpi_en_trigrams)/sizeof(ndpi_en_trigrams[0]), 3);
}
}
Expand Down Expand Up @@ -2060,6 +2063,14 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
"BACnet", NDPI_PROTOCOL_CATEGORY_IOT_SCADA,
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 47808, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, 0 /* nw proto */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_OICQ,
"OICQ", NDPI_PROTOCOL_CATEGORY_CHAT,
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 8000, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, 0 /* nw proto */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_HOTS,
"Heroes_of_the_Storm", NDPI_PROTOCOL_CATEGORY_GAME,
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);


#ifdef CUSTOM_NDPI_PROTOCOLS
Expand Down Expand Up @@ -4899,6 +4910,12 @@ static int ndpi_callback_init(struct ndpi_detection_module_struct *ndpi_str) {
/* BACnet */
init_bacnet_dissector(ndpi_str, &a);

/* OICQ */
init_oicq_dissector(ndpi_str, &a);

/* Heroes of the Storm */
init_hots_dissector(ndpi_str, &a);

#ifdef CUSTOM_NDPI_PROTOCOLS
#include "../../../nDPI-custom/custom_ndpi_main_init.c"
#endif
Expand Down Expand Up @@ -6177,9 +6194,7 @@ static void ndpi_add_connection_as_zoom(struct ndpi_detection_module_struct *ndp
*/
static void ndpi_check_tcp_flags(struct ndpi_detection_module_struct *ndpi_str,
struct ndpi_flow_struct *flow) {
#if 0
printf("[TOTAL] %u / %u [tot: %u]\n", flow->packet_direction_complete_counter[0], flow->packet_direction_complete_counter[1], flow->all_packets_counter);
#endif
// printf("[TOTAL] %u / %u [tot: %u]\n", flow->packet_direction_complete_counter[0], flow->packet_direction_complete_counter[1], flow->all_packets_counter);

if((flow->l4.tcp.cli2srv_tcp_flags & TH_SYN)
&& (flow->l4.tcp.srv2cli_tcp_flags & TH_RST)
Expand Down Expand Up @@ -8264,8 +8279,6 @@ void ndpi_generate_options(u_int opt) {
printf("WARNING: option -a out of range\n");
break;
}

exit(0);
}

/* ****************************************************** */
Expand Down Expand Up @@ -8570,7 +8583,7 @@ int ndpi_match_bigram(const char *str) {
}

int ndpi_match_impossible_bigram(const char *str) {
return ndpi_match_xgram(imposible_bigrams_bitmap, 2, str);
return ndpi_match_xgram(impossible_bigrams_bitmap, 2, str);
}

/* ****************************************************** */
Expand Down
75 changes: 75 additions & 0 deletions src/lib/protocols/hots.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* hots.c
*
* Copyright (C) 2023 - ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
*
* nDPI is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* nDPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with nDPI. If not, see <http://www.gnu.org/licenses/>.
*
*/

#include "ndpi_protocol_ids.h"

#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_HOTS

#include "ndpi_api.h"

static void ndpi_hots_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HOTS, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
NDPI_LOG_INFO(ndpi_struct, "found Heroes of the Storm packet\n");
}

void ndpi_search_hots(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
struct ndpi_packet_struct *packet = &ndpi_struct->packet;

NDPI_LOG_DBG(ndpi_struct, "search Heroes of the Storm\n");

int ports[4] = {1119, 1120, 3724, 6113};
for (int i = 0; i < 4; i++) {
if (packet->udp->dest == ntohs(ports[i]) || packet->udp->source == ntohs(ports[i])) {
if (packet->payload_packet_len >= 20 && packet->payload_packet_len <= 122) {
if (packet->payload[14] == 0x40 && packet->payload[15] == 0x00) {
if ((packet->payload[2] == 0x03 && packet->payload[3] == 0x00) ||
(packet->payload[2] == 0x34 && packet->payload[3] == 0x00) ||
(packet->payload[0] == 0x00 && packet->payload[1] == 0x00 && packet->payload[2] == 0x00 &&
packet->payload[3] == 0x00 && packet->payload[4] == 0x00 && packet->payload[5] == 0x00 &&
packet->payload[6] == 0x00 && packet->payload[7] == 0x00 && packet->payload[8] == 0x00 &&
packet->payload[9] == 0x00 && packet->payload[10] == 0x00 && packet->payload[11] == 0x00 &&
packet->payload[12] == 0x00 && packet->payload[13] == 0x00)) {
ndpi_hots_add_connection(ndpi_struct, flow);
return;
}
}
}
break;
}
}
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
}


void init_hots_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id)
{
ndpi_set_bitmask_protocol_detection("HOTS", ndpi_struct, *id,
NDPI_PROTOCOL_HOTS,
ndpi_search_hots,
NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, /* Only IPv4 UDP traffic is expected. */
SAVE_DETECTION_BITMASK_AS_UNKNOWN,
ADD_TO_DETECTION_BITMASK);
*id += 1;
}
Loading