feature(adapt maat): PXY_SSL_FINGERPRINT adapt uuid
This commit is contained in:
@@ -5,11 +5,10 @@
|
||||
|
||||
struct ssl_svc_ja3
|
||||
{
|
||||
char ja3_hash[33];
|
||||
int fingerprint_id;
|
||||
uuid_t uuid;
|
||||
char ja3_hash[33];
|
||||
int pinning_state;
|
||||
int is_valid;
|
||||
int ref_cnt;
|
||||
int ref_cnt;
|
||||
};
|
||||
|
||||
struct ssl_svc_addr
|
||||
@@ -20,135 +19,168 @@ struct ssl_svc_addr
|
||||
const char *dport;
|
||||
};
|
||||
|
||||
static int table_id = 0;
|
||||
|
||||
static void ssl_svc_ja3_param_dup_cb(int table_id, void **to, void **from, long argl, void *argp)
|
||||
static void ssl_svc_ja3_param_dup_cb(const char *table_name, void **to, void **from, long argl, void *argp)
|
||||
{
|
||||
struct ssl_svc_ja3 *param = (struct ssl_svc_ja3 *)*from;
|
||||
if (param)
|
||||
{
|
||||
__sync_add_and_fetch(&(param->ref_cnt), 1);
|
||||
*to = param;
|
||||
}
|
||||
else
|
||||
{
|
||||
*to = NULL;
|
||||
}
|
||||
return;
|
||||
struct ssl_svc_ja3 *param = (struct ssl_svc_ja3 *)*from;
|
||||
if (param)
|
||||
{
|
||||
__sync_add_and_fetch(&(param->ref_cnt), 1);
|
||||
*to = param;
|
||||
}
|
||||
else
|
||||
{
|
||||
*to = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void ssl_svc_ja3_param_new_cb(const char *table_name, int table_id, const char *key, const char *table_line, void **ad, long argl, void *argp)
|
||||
// NOTE: key is ja3_hash
|
||||
static void ssl_svc_ja3_param_new_cb(const char *table_name, const char *key, const char *table_line, void **ad, long argl, void *argp)
|
||||
{
|
||||
int is_valid = 0;
|
||||
int pinning_state = 0;
|
||||
int fingerprint_id = 0;
|
||||
char ja3_hash[33] = {0};
|
||||
cJSON *json = NULL;
|
||||
cJSON *item = NULL;
|
||||
struct ssl_svc_ja3 *param = NULL;
|
||||
|
||||
if (sscanf(table_line, "%d\t%s\t%d\t%d", &fingerprint_id, ja3_hash, &pinning_state, &is_valid) != 4)
|
||||
{
|
||||
TFE_LOG_ERROR(g_default_logger, "Invalid JA3 policy: %s", table_line);
|
||||
return;
|
||||
}
|
||||
char *json_str = strdup(table_line);
|
||||
json = cJSON_Parse(json_str);
|
||||
if (json == NULL)
|
||||
{
|
||||
TFE_LOG_ERROR(g_default_logger, "Invalid JA3 policy: (invalid json format) %s", table_line);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
struct ssl_svc_ja3 *param = ALLOC(struct ssl_svc_ja3, 1);
|
||||
param->fingerprint_id = fingerprint_id;
|
||||
memcpy(param->ja3_hash, ja3_hash, 32);
|
||||
param->pinning_state = pinning_state;
|
||||
param->is_valid = is_valid;
|
||||
param->ref_cnt = 1;
|
||||
param = ALLOC(struct ssl_svc_ja3, 1);
|
||||
param->ref_cnt = 1;
|
||||
|
||||
*ad = param;
|
||||
TFE_LOG_INFO(g_default_logger, "Add JA3 policy: id:%d, ja3_hash:%s, pinning_state:%d, is_valid:%d, ref_cnt:%d",
|
||||
param->fingerprint_id, param->ja3_hash, param->pinning_state, param->is_valid, param->ref_cnt);
|
||||
// uuid
|
||||
item = cJSON_GetObjectItem(json, "uuid");
|
||||
if (!item || !cJSON_IsString(item))
|
||||
{
|
||||
TFE_LOG_ERROR(g_default_logger, "Invalid JA3 policy: (invalid uuid param) %s", table_line);
|
||||
goto error_out;
|
||||
}
|
||||
uuid_parse(item->valuestring, param->uuid);
|
||||
|
||||
// ja3_hash
|
||||
item = cJSON_GetObjectItem(json, "ja3_hash");
|
||||
if (!item || !cJSON_IsString(item))
|
||||
{
|
||||
TFE_LOG_ERROR(g_default_logger, "Invalid JA3 policy: (invalid ja3_hash param) %s", table_line);
|
||||
goto error_out;
|
||||
}
|
||||
strncpy(param->ja3_hash, item->valuestring, 32);
|
||||
|
||||
// pinning_state
|
||||
item = cJSON_GetObjectItem(json, "pinning_state");
|
||||
if (!item || !cJSON_IsNumber(item))
|
||||
{
|
||||
TFE_LOG_ERROR(g_default_logger, "Invalid JA3 policy: (invalid pinning_state param) %s", table_line);
|
||||
goto error_out;
|
||||
}
|
||||
param->pinning_state = item->valueint;
|
||||
|
||||
*ad = param;
|
||||
TFE_LOG_INFO(g_default_logger, "Add JA3 policy: uuid:%s, ja3_hash:%s, pinning_state:%d",
|
||||
key, param->ja3_hash, param->pinning_state);
|
||||
|
||||
cJSON_Delete(json);
|
||||
free(json_str);
|
||||
return;
|
||||
|
||||
error_out:
|
||||
if (json)
|
||||
{
|
||||
cJSON_Delete(json);
|
||||
}
|
||||
if (json_str)
|
||||
{
|
||||
free(json_str);
|
||||
}
|
||||
if (param)
|
||||
{
|
||||
free(param);
|
||||
}
|
||||
*ad = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
static void ssl_svc_ja3_param_free_cb(int table_id, void **ad, long argl, void *argp)
|
||||
static void ssl_svc_ja3_param_free_cb(const char *table_name, void **ad, long argl, void *argp)
|
||||
{
|
||||
struct ssl_svc_ja3 *param = (struct ssl_svc_ja3 *)*ad;
|
||||
if (param == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
struct ssl_svc_ja3 *param = (struct ssl_svc_ja3 *)*ad;
|
||||
if (param == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((__sync_sub_and_fetch(¶m->ref_cnt, 1) == 0))
|
||||
{
|
||||
TFE_LOG_INFO(g_default_logger, "Del JA3 policy: id:%d, ja3_hash:%s, pinning_state:%d, is_valid:%d, ref_cnt:%d",
|
||||
param->fingerprint_id, param->ja3_hash, param->pinning_state, param->is_valid, param->ref_cnt);
|
||||
free(param);
|
||||
*ad = NULL;
|
||||
}
|
||||
if ((__sync_sub_and_fetch(¶m->ref_cnt, 1) == 0))
|
||||
{
|
||||
char uuid_str[UUID_STRING_SIZE] = {0};
|
||||
uuid_unparse(param->uuid, uuid_str);
|
||||
TFE_LOG_INFO(g_default_logger, "Del JA3 policy: id:%s", uuid_str);
|
||||
free(param);
|
||||
*ad = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void ssl_svc_ja3_param_free(struct ssl_svc_ja3 *param)
|
||||
{
|
||||
ssl_svc_ja3_param_free_cb(0, (void **)¶m, 0, NULL);
|
||||
return;
|
||||
ssl_svc_ja3_param_free_cb(NULL, (void **)¶m, 0, NULL);
|
||||
}
|
||||
|
||||
static int ssl_svc_ja3_init(const char *table_name)
|
||||
static int ssl_svc_ja3_init()
|
||||
{
|
||||
table_id = maat_get_table_id(tfe_get_maat_handle(), table_name);
|
||||
if (table_id < 0)
|
||||
{
|
||||
TFE_LOG_ERROR(g_default_logger, "Maat table %s register failed.", table_name);
|
||||
return 0;
|
||||
}
|
||||
int ret = maat_plugin_table_ex_schema_register(tfe_get_maat_handle(),
|
||||
table_name,
|
||||
ssl_svc_ja3_param_new_cb,
|
||||
ssl_svc_ja3_param_free_cb,
|
||||
ssl_svc_ja3_param_dup_cb,
|
||||
0,
|
||||
NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
TFE_LOG_ERROR(g_default_logger, "failed at Maat_plugin_EX_register(%s), table_id = %d, ret = %d",
|
||||
table_name, table_id, ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
if (maat_plugin_table_ex_schema_register(tfe_get_maat_handle(),
|
||||
"PXY_SSL_FINGERPRINT",
|
||||
ssl_svc_ja3_param_new_cb,
|
||||
ssl_svc_ja3_param_free_cb,
|
||||
ssl_svc_ja3_param_dup_cb,
|
||||
0,
|
||||
NULL) != 0)
|
||||
{
|
||||
TFE_LOG_ERROR(g_default_logger, "failed at Maat_plugin_EX_register(PXY_SSL_FINGERPRINT)");
|
||||
return -1
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
enum ssl_ja3_pinning_status ssl_svc_ja3_scan(char *ja3_hash, const char *addr_str)
|
||||
{
|
||||
enum ssl_ja3_pinning_status ret = JA3_PINNING_STATUS_UNKNOWN;
|
||||
struct ssl_svc_ja3 *param = NULL;
|
||||
enum ssl_ja3_pinning_status ret = JA3_PINNING_STATUS_UNKNOWN;
|
||||
struct ssl_svc_ja3 *param = NULL;
|
||||
char uuid_str[UUID_STRING_SIZE] = {0};
|
||||
|
||||
param = (struct ssl_svc_ja3 *)maat_plugin_table_get_ex_data(tfe_get_maat_handle(), table_id, ja3_hash, strlen(ja3_hash));
|
||||
if (param == NULL)
|
||||
{
|
||||
ret = JA3_PINNING_STATUS_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
TFE_LOG_INFO(g_default_logger, "Hit JA3 policy: id:%d, ja3_hash:%s, pinning_state:%d, is_valid:%d, ref_cnt:%d, addr:%s",
|
||||
param->fingerprint_id, param->ja3_hash, param->pinning_state, param->is_valid, param->ref_cnt, addr_str);
|
||||
|
||||
if (!param->is_valid)
|
||||
{
|
||||
ret = JA3_PINNING_STATUS_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
param = (struct ssl_svc_ja3 *)maat_plugin_table_get_ex_data(tfe_get_maat_handle(), "PXY_SSL_FINGERPRINT", ja3_hash, strlen(ja3_hash));
|
||||
if (param == NULL)
|
||||
{
|
||||
ret = JA3_PINNING_STATUS_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
uuid_unparse(param->uuid, uuid_str);
|
||||
TFE_LOG_INFO(g_default_logger, "Hit JA3 policy: uuid:%s, ja3_hash:%s, pinning_state:%d, addr:%s",
|
||||
uuid_str, param->ja3_hash, param->pinning_state, addr_str);
|
||||
|
||||
// 1 - pinning
|
||||
if (param->pinning_state)
|
||||
{
|
||||
ret = JA3_PINNING_STATUS_IS_PINNING;
|
||||
}
|
||||
// 0 - not pinning
|
||||
else
|
||||
if (param->pinning_state)
|
||||
{
|
||||
ret = JA3_PINNING_STATUS_NOT_PINNING;
|
||||
}
|
||||
ret = JA3_PINNING_STATUS_IS_PINNING;
|
||||
}
|
||||
// 0 - not pinning
|
||||
else
|
||||
{
|
||||
ret = JA3_PINNING_STATUS_NOT_PINNING;
|
||||
}
|
||||
|
||||
end:
|
||||
if (param)
|
||||
{
|
||||
ssl_svc_ja3_param_free(param);
|
||||
param = NULL;
|
||||
}
|
||||
if (param)
|
||||
{
|
||||
ssl_svc_ja3_param_free(param);
|
||||
param = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct ssl_svc_client_st
|
||||
@@ -510,10 +542,9 @@ void ssl_service_cache_write(struct ssl_service_cache *svc_cache, const struct s
|
||||
|
||||
free(addr_str);
|
||||
}
|
||||
struct ssl_service_cache *ssl_service_cache_create(unsigned int slot_size, unsigned int expire_seconds, int fail_as_pinning_cnt, int fail_as_proto_err_cnt, int fail_time_win
|
||||
, char *ja3_table_name)
|
||||
struct ssl_service_cache *ssl_service_cache_create(unsigned int slot_size, unsigned int expire_seconds, int fail_as_pinning_cnt, int fail_as_proto_err_cnt, int fail_time_win)
|
||||
{
|
||||
if (ssl_svc_ja3_init(ja3_table_name) == 0)
|
||||
if (ssl_svc_ja3_init() != 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user