add socks_decoder, stratum_decoder and session_flags
This commit is contained in:
217
decoders/session_flags/tunneling.cpp
Normal file
217
decoders/session_flags/tunneling.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
#include <cctype>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "cJSON.h"
|
||||
#include "session_flags_internal.h"
|
||||
#include "tunneling.h"
|
||||
#include "stellar/log.h"
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
thread_local hs_scratch_t *hs_scratch = NULL;
|
||||
extern struct session_flags_init_conf g_sf_conf;
|
||||
|
||||
static char tunneling_length_to_character(enum flow_type flow_type, size_t len)
|
||||
{
|
||||
char ret;
|
||||
|
||||
switch(len)
|
||||
{
|
||||
case 1 ... 200:
|
||||
ret = 'A';
|
||||
break;
|
||||
case 201 ... 600:
|
||||
ret = 'B';
|
||||
break;
|
||||
case 601 ... 1000:
|
||||
ret = 'C';
|
||||
break;
|
||||
case 1001 ... 1460:
|
||||
ret = 'D';
|
||||
break;
|
||||
default:
|
||||
ret = 'Z';
|
||||
break;
|
||||
}
|
||||
|
||||
if (flow_type == FLOW_TYPE_C2S)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
return tolower(ret);
|
||||
}
|
||||
}
|
||||
|
||||
static int tunneling_match_event_handler(unsigned int id, unsigned long long from, unsigned long long to, unsigned int flags, void *context) {
|
||||
UNUSED(id);
|
||||
UNUSED(from);
|
||||
UNUSED(to);
|
||||
UNUSED(flags);
|
||||
|
||||
struct session_flags_ctx *ctx = (struct session_flags_ctx *)context;
|
||||
ctx->stat.result.flags |= SESSION_FLAGS_TUNNELING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tunneling_scan_sequence(struct session_flags_plugin_info *sf_plugin_info, struct session *session, struct session_flags_ctx *ctx, size_t payload_len, enum flow_type flow_type, uint64_t pkts_cnt)
|
||||
{
|
||||
if (ctx->stat.result.flags & SESSION_FLAGS_TUNNELING)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->stat.tunneling_stat.payload_pkt_num++;
|
||||
if (ctx->stat.result.is_tls && ctx->stat.tunneling_stat.payload_pkt_num <= g_sf_conf.tunneling_tls_ignore_pkts)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((ctx->stat.result.is_tls==0) && (ctx->stat.tunneling_stat.payload_pkt_num > g_sf_conf.tunneling_max_scan_pkts))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((ctx->stat.result.is_tls) && (ctx->stat.tunneling_stat.payload_pkt_num > g_sf_conf.tunneling_max_scan_pkts+g_sf_conf.tunneling_tls_ignore_pkts))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hs_scratch == NULL)
|
||||
{
|
||||
hs_error_t err = hs_alloc_scratch(sf_plugin_info->tunneling_hs_db, &hs_scratch);
|
||||
if (err != HS_SUCCESS)
|
||||
{
|
||||
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "hs_alloc_scratch failed, err:%d", err);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
char tunneling_seq_char = tunneling_length_to_character(flow_type, payload_len);
|
||||
STELLAR_LOG_DEBUG(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "session: %s, is tls:%s, total_num: %d, payload_pkt_num: %d, tunneling_seq_char:%c, payload_len:%d",
|
||||
session_get0_readable_addr(session), ctx->stat.result.is_tls == true ? "yes":"no", pkts_cnt, ctx->stat.tunneling_stat.payload_pkt_num, tunneling_seq_char, payload_len);
|
||||
|
||||
hs_error_t err = hs_scan_stream(ctx->tunneling_hs_stream, &tunneling_seq_char, 1, 0, hs_scratch, tunneling_match_event_handler, ctx);
|
||||
if (err != HS_SUCCESS)
|
||||
{
|
||||
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "hs_scan_stream failed, err:%d", err);
|
||||
return -1;
|
||||
}
|
||||
if (ctx->stat.result.flags & SESSION_FLAGS_TUNNELING)
|
||||
{
|
||||
ctx->stat.result.identify[session_flags_tunneling_mask] = pkts_cnt;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tunneling_hs_stream_init(struct session_flags_plugin_info *sf_plugin_info, struct session_flags_ctx *ctx)
|
||||
{
|
||||
hs_error_t err = hs_open_stream(sf_plugin_info->tunneling_hs_db, 0, &ctx->tunneling_hs_stream);
|
||||
if (err != HS_SUCCESS)
|
||||
{
|
||||
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "hs_open_stream failed, err:%d", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void tunneling_hs_stream_free(struct session_flags_ctx *ctx)
|
||||
{
|
||||
if (ctx->tunneling_hs_stream == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hs_close_stream(ctx->tunneling_hs_stream, hs_scratch, NULL, NULL);
|
||||
}
|
||||
|
||||
int tunneling_hyperscan_engine_init(struct session_flags_plugin_info *sf_plugin_info, struct session_flags_init_conf *g_sf_conf)
|
||||
{
|
||||
cJSON *json = NULL, *item = NULL;
|
||||
int array_num;
|
||||
char **pcre = NULL;
|
||||
hs_compile_error_t *compile_err;
|
||||
hs_error_t err;
|
||||
unsigned int *flags = NULL;
|
||||
unsigned int *ids = NULL;
|
||||
int ret = 0;
|
||||
|
||||
g_sf_conf->tunneling_enabled = 0;
|
||||
|
||||
json = cJSON_Parse(g_sf_conf->tunneling_pcre_list);
|
||||
if (json == NULL)
|
||||
{
|
||||
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "cJSON_Parse failed, tunneling_pcre_list:%s", g_sf_conf->tunneling_pcre_list);
|
||||
goto END;
|
||||
}
|
||||
item = cJSON_GetObjectItem(json, "tunneling_pcre_list");
|
||||
if (item == NULL)
|
||||
{
|
||||
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "cJSON_GetObjectItem failed, tunneling_pcre_list:%s", g_sf_conf->tunneling_pcre_list);
|
||||
goto END;
|
||||
}
|
||||
array_num = cJSON_GetArraySize(item);
|
||||
if (array_num < 0)
|
||||
{
|
||||
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "array size error, array_num:%d", array_num);
|
||||
goto END;
|
||||
}
|
||||
|
||||
if (array_num == 0)
|
||||
{
|
||||
goto END;
|
||||
}
|
||||
|
||||
g_sf_conf->tunneling_enabled = 1;
|
||||
pcre = (char **)calloc(array_num, sizeof(char *));
|
||||
for (int i = 0; i < array_num; i++)
|
||||
{
|
||||
pcre[i] = cJSON_GetArrayItem(item, i)->valuestring;
|
||||
}
|
||||
|
||||
flags = (unsigned int *)calloc(array_num, sizeof(unsigned int));
|
||||
ids = (unsigned int *)calloc(array_num, sizeof(unsigned int));
|
||||
for (int i = 0; i < array_num; i++)
|
||||
{
|
||||
flags[i] = HS_FLAG_DOTALL;
|
||||
ids[i] = i;
|
||||
}
|
||||
|
||||
err = hs_compile_multi(pcre, flags, ids, array_num, HS_MODE_STREAM, NULL, &sf_plugin_info->tunneling_hs_db, &compile_err);
|
||||
if (err != HS_SUCCESS)
|
||||
{
|
||||
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "hs_compile_multi failed, err:%d, pattern id: %d, err_msg: %s, pattern: %s", err, compile_err->expression, compile_err->message, pcre[compile_err->expression]);
|
||||
cJSON_Delete(json);
|
||||
free(pcre);
|
||||
ret = -1;
|
||||
goto END;
|
||||
}
|
||||
|
||||
END:
|
||||
if (json != NULL)
|
||||
{
|
||||
cJSON_Delete(json);
|
||||
}
|
||||
if (pcre != NULL)
|
||||
{
|
||||
free(pcre);
|
||||
}
|
||||
if (flags != NULL)
|
||||
{
|
||||
free(flags);
|
||||
}
|
||||
if (ids != NULL)
|
||||
{
|
||||
free(ids);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void tunneling_hyperscan_engine_exit(hs_database_t *tunneling_hs_db)
|
||||
{
|
||||
if (tunneling_hs_db != NULL)
|
||||
{
|
||||
hs_free_database(tunneling_hs_db);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user