端口掃描

異常掃描邏輯.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;


//獲取當(dāng)前時間
long get_now_time()
{
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return (tv.tv_sec*1000000 + tv.tv_usec);
}

//獲取掃描的端口個數(shù)
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函數(shù)
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)
        {
            //上次掃描行為結(jié)束
            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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者板驳。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吠勘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌峡眶,老刑警劉巖剧防,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異辫樱,居然都是意外死亡峭拘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門狮暑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸡挠,“玉大人,你說我怎么就攤上這事搬男〖鹫梗” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵止后,是天一觀的道長瞎惫。 經(jīng)常有香客問我,道長译株,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任挺益,我火速辦了婚禮歉糜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘望众。我一直安慰自己匪补,他們只是感情好伞辛,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著夯缺,像睡著了一般蚤氏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上踊兜,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天竿滨,我揣著相機(jī)與錄音,去河邊找鬼捏境。 笑死于游,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的垫言。 我是一名探鬼主播贰剥,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼筷频!你這毒婦竟也來了蚌成?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凛捏,失蹤者是張志新(化名)和其女友劉穎笑陈,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體葵袭,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涵妥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了坡锡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓬网。...
    茶點(diǎn)故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鹉勒,靈堂內(nèi)的尸體忽然破棺而出帆锋,到底是詐尸還是另有隱情,我是刑警寧澤禽额,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布锯厢,位于F島的核電站,受9級特大地震影響脯倒,放射性物質(zhì)發(fā)生泄漏实辑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一藻丢、第九天 我趴在偏房一處隱蔽的房頂上張望剪撬。 院中可真熱鬧,春花似錦悠反、人聲如沸残黑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梨水。三九已至拭荤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間疫诽,已是汗流浹背舅世。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留踊沸,地道東北人歇终。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像逼龟,于是被迫代替她去往敵國和親评凝。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容