异常扫描逻辑.png
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include "hikadef_hash.h"
#include "hikadef_scan_check.h"
#include "hikadef_publish.h"
#include "Hikadef_Log.h"
/*----------------------------------------------------------------------------------*/
typedef struct scan_info_t
{
char scan_ipstr[32];
unsigned int scan_port;
unsigned int protocol;
unsigned int scan_type;
unsigned char portmap[65535];
long timestamp;
} scan_info;
enum SCAN_TYPE
{
SCAN_TYPE_NULL = 0,
SCAN_TYPE_SYN = 1,
SCAN_TYPE_ACK,
SCAN_TYPE_FIN,
SCAN_TYPE_CON,
SCAN_TYPE_SEND
};
static char *protocol_str[] = {
[0] = "TCP",
[1] = "UDP",
};
/*----------------------------------------------------------------------------------*/
#define HASH_TABLE_SIZE 80 //hash桶大小
#define SCAN_TIME_LIMIT 5000000 //5s
#define SCAN_PORT_LIMIT 5
hash_t *scan_hash;
//获取当前时间
long get_now_time()
{
struct timeval tv;
gettimeofday(&tv,NULL);
return (tv.tv_sec*1000000 + tv.tv_usec);
}
//获取扫描的端口个数
static int get_scan_port_count(unsigned char map[65535])
{
int i = 0;
int sum = 0;
for(i = 0; i< 65535; i++)
{
if(1 == map[i])
{
sum++;
}
}
return sum;
}
static void hexToCharIP(struct in_addr addrIP, char ipstr[16])
{
unsigned int intIP;
memcpy(&intIP, &addrIP,sizeof(unsigned int));
int a = (intIP >> 24) & 0xFF;
int b = (intIP >> 16) & 0xFF;
int c = (intIP >> 8) & 0xFF;
int d = intIP & 0xFF;
sprintf(ipstr, "%d.%d.%d.%d", d,c,b,a);
}
//基于ip+protocol的hash函数
static unsigned int hash_func(unsigned int bucktes, void *key)
{
unsigned int hashval = 0;
while('\0' != *(char*)key)
{
hashval = (hashval << 5) + *(char*)key++;
}
return hashval % bucktes;
}
int network_scan_init()
{
scan_hash = hash_alloc(HASH_TABLE_SIZE, hash_func);
if(NULL == scan_hash)
{
return -1;
}
return 0;
}
static int network_parse_info(struct NETWATCH_HEADER_T *pap, scan_info *parse_info)
{
int iRslt = 0;
unsigned int seq = pap->seq;
unsigned char fin = pap->flag & 0x01;
unsigned char syn = (pap->flag & 0x02) >> 1;
//unsigned char rst = (pap->flag & 0x04) >> 2;
unsigned char psh = (pap->flag & 0x08) >> 3;
unsigned char ack = (pap->flag & 0x10) >> 4;
switch(pap->protpcol)
{
case 0: //TCP
if(0 == psh)
{
parse_info->scan_type = SCAN_TYPE_NULL;
goto end;
}
if(1 == syn && 0 == ack)
{
parse_info->scan_type = SCAN_TYPE_SYN;
}
else if(1 == ack && 0 == seq)
{
parse_info->scan_type = SCAN_TYPE_ACK;
}
else if(1 == fin && 0 == ack)
{
parse_info->scan_type = SCAN_TYPE_FIN;
}
else if(0 != seq && 0 != ack)
{
parse_info->scan_type = SCAN_TYPE_CON;
}
else
{
parse_info->scan_type = SCAN_TYPE_NULL;
goto end;
}
break;
case 1: //UDP
parse_info->scan_type = SCAN_TYPE_SEND;
break;
default:
parse_info->scan_type = SCAN_TYPE_NULL;
break;
}
parse_info->protocol = pap->protpcol;
parse_info->scan_port= pap->port;
hexToCharIP(pap->ip, parse_info->scan_ipstr);
end:
//HikadefLog(LOG_INFO, "%d,%d,%d,%d,%d,%d, ip = %s", seq,fin,syn,rst,psh,ack, parse_info->scan_ipstr);
return iRslt;
}
int network_scan_check(struct NETWATCH_HEADER_T *pap)
{
char key[100] = {0};
scan_info parse_info = {0};
scan_info *find = NULL;
//解析
network_parse_info(pap, &parse_info);
if(SCAN_TYPE_NULL == parse_info.scan_type)
{
//HikadefLog(LOG_INFO,"not scan");
return 0;
}
//key = ip:proto
snprintf(key, sizeof(key), "%s:%d", parse_info.scan_ipstr, parse_info.protocol);
find = (scan_info*)hash_lookup_entry(scan_hash, key, sizeof(*key));
if(NULL == find)
{
parse_info.timestamp = get_now_time();
parse_info.portmap[parse_info.scan_port] = 1;
hash_add_entry(scan_hash, key, sizeof(key), &parse_info, sizeof(scan_info));
HikadefLog(LOG_INFO,"new hash node ,time %ld, port = %d ", parse_info.timestamp, parse_info.scan_port);
}
else
{
if(get_now_time() - find->timestamp > SCAN_TIME_LIMIT)
{
//上次扫描行为结束
HikadefLog(LOG_INFO,"Time up, port count = %d ", get_scan_port_count(find->portmap));
if(get_scan_port_count(find->portmap)>= SCAN_PORT_LIMIT)
{
HikadefLog(LOG_INFO,"Timpe and port up, must alarm ");
hikadef_alarm_network_scan_insert_info(find->scan_ipstr, find->scan_port, protocol_str[find->protocol]);
hash_free_entry(scan_hash, key, sizeof(key));
}
else
{
HikadefLog(LOG_INFO,"Time up, new_port = %d", parse_info.scan_port);
find->portmap[parse_info.scan_port] = 1;
find->timestamp = get_now_time();
hash_update_entry(scan_hash, key, sizeof(key), find, sizeof(scan_info));
}
}
else
{
HikadefLog(LOG_INFO,"Time not up, add port =%d", parse_info.scan_port);
find->portmap[parse_info.scan_port] = 1;
hash_update_entry(scan_hash, key, sizeof(key), find, sizeof(scan_info));
}
}
return 0;
}
#if 0
int main()
{
struct NETWATCH_HEADER_T test = {0};
network_scan_init();
test.protpcol = 0;
test.flag = 0x1a;
test.port = 10;
test.seq = 0;
network_scan_check(&test);
test.protpcol = 1;
network_scan_check(&test);
test.port = 11;
network_scan_check(&test);
sleep (5);
test.port = 12;
network_scan_check(&test);
test.port = 13;
network_scan_check(&test);
return 0;
}
#endif
网友评论