⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spp_sfportscan.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************** * * Copyright (C) 2004-2007 Sourcefire, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as * published by the Free Software Foundation.  You may not use, modify or * distribute this program under any other version of the GNU General * Public License. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ****************************************************************************/ /***  @file       spp_sfportscan.c****  @author     Daniel Roelker <droelker@sourcefire.com>****  @brief      Portscan detection****  NOTES**    - User Configuration:  The following is a list of parameters that can**      be configured through the user interface:****      proto  { tcp udp icmp ip all }**      scan_type { portscan portsweep decoy_portscan distributed_portscan all }**      sense_level { high }    # high, medium, low**      watch_ip { }            # list of IPs, CIDR blocks**      ignore_scanners { }     # list of IPs, CIDR blocks**      ignore_scanned { }      # list of IPs, CIDR blocks**      memcap { 10000000 }     # number of max bytes to allocate**      logfile { /tmp/ps.log } # file to log detailed portscan info*/#include <sys/types.h>#ifndef WIN32    #include <sys/socket.h>    #include <netinet/in.h>    #include <arpa/inet.h>#endif /* !WIN32 */#include "decode.h"#include "plugbase.h"#include "generators.h"#include "event_wrapper.h"#include "util.h"#include "ipobj.h"#include "checksum.h"#include "packet_time.h"#include "snort.h"#include "sfthreshold.h"#include "sfsnprintfappend.h"#include "sf_iph.h"#include "portscan.h"#include "profiler.h"#define DELIMITERS " \t\n"#define TOKEN_ARG_BEGIN "{"#define TOKEN_ARG_END   "}"#define PROTO_BUFFER_SIZE 256extern PV    pv;extern char *file_name;extern int   file_line;static int     g_print_tracker = 0;static u_char  g_logpath[256];static FILE   *g_logfile = NULL;static Packet *g_tmp_pkt;int g_include_midstream = 0;#ifdef PERF_PROFILINGPreprocStats sfpsPerfStats;#endif/***  NAME**    PortscanPacketInit::*//****  Initialize the Packet structure buffer so we can generate our**  alert packets for portscan.  We initialize the various fields in**  the Packet structure and set the hardware layer for easy identification**  by user interfaces.****  @return int****  @retval !0 initialization failed**  @retval  0 success*/static int PortscanPacketInit(void){    const char mac_addr[] = "MACDAD";    Packet *p;    p = (Packet *)SnortAlloc(sizeof(Packet));    p->pkth = (struct pcap_pkthdr *)SnortAlloc(sizeof(struct pcap_pkthdr) +                    ETHERNET_HEADER_LEN + SPARC_TWIDDLE + IP_MAXPACKET);        /* Add 2 to align iph struct members on 4 byte boundaries - for sparc, etc */    p->pkt  = ((u_char *)p->pkth + sizeof(struct pcap_pkthdr) + SPARC_TWIDDLE);    p->eh   = (EtherHdr *)p->pkt;    p->iph  = (IPHdr *)(((u_char *)p->eh) + ETHERNET_HEADER_LEN);    p->data = ((u_char *)p->iph) + sizeof(IPHdr);    /*    **  Set the ethernet header with our cooked values.    */    ((EtherHdr *)p->eh)->ether_type = htons(0x0800);    memcpy(((EtherHdr *)p->eh)->ether_dst, mac_addr, 6);    memcpy(((EtherHdr *)p->eh)->ether_src, mac_addr, 6);    g_tmp_pkt = p;    return 0;}void PortscanCleanExitFunction(int signal, void *foo){    ps_cleanup();    free((void *)g_tmp_pkt->pkth);    free(g_tmp_pkt);    g_tmp_pkt = NULL;}void PortscanRestartFunction(int signal, void *foo){    ps_cleanup();    free((void *)g_tmp_pkt->pkth);    free(g_tmp_pkt);    g_tmp_pkt = NULL;}/***  NAME**    MakeProtoInfo::*//****  This routine makes the portscan payload for the events.  The listed**  info is:**    - priority count (number of error transmissions RST/ICMP UNREACH)**    - connection count (number of protocol connections SYN)**    - ip count (number of IPs that communicated with host)**    - ip range (low to high range of IPs)**    - port count (number of port changes that occurred on host)**    - port range (low to high range of ports connected too)****  @return integer****  @retval -1 buffer not large enough**  @retval  0 successful*/static int MakeProtoInfo(PS_PROTO *proto, u_char *buffer, u_int *total_size){    unsigned char *ip1;    unsigned char *ip2;    int            dsize;    if(!total_size || !buffer)        return -1;    dsize = (IP_MAXPACKET - *total_size);    if(dsize < PROTO_BUFFER_SIZE)       return -1;     ip1 = (unsigned char *)&proto->low_ip;    ip2 = (unsigned char *)&proto->high_ip;    if(proto->alerts == PS_ALERT_PORTSWEEP ||       proto->alerts == PS_ALERT_PORTSWEEP_FILTERED)    {        SnortSnprintf((char *)buffer, PROTO_BUFFER_SIZE,                      "Priority Count: %d\n"                      "Connection Count: %d\n"                      "IP Count: %d\n"                      "Scanned IP Range: %d.%d.%d.%d:%d.%d.%d.%d\n"                      "Port/Proto Count: %d\n"                      "Port/Proto Range: %d:%d\n",                      proto->priority_count,                      proto->connection_count,                      proto->u_ip_count,                      ip1[3],ip1[2],ip1[1],ip1[0],                      ip2[3],ip2[2],ip2[1],ip2[0],                      proto->u_port_count,                      proto->low_p,                      proto->high_p);    }    else    {        SnortSnprintf((char *)buffer, PROTO_BUFFER_SIZE,                      "Priority Count: %d\n"                      "Connection Count: %d\n"                      "IP Count: %d\n"                      "Scanner IP Range: %d.%d.%d.%d:%d.%d.%d.%d\n"                      "Port/Proto Count: %d\n"                      "Port/Proto Range: %d:%d\n",                      proto->priority_count,                      proto->connection_count,                      proto->u_ip_count,                      ip1[3],ip1[2],ip1[1],ip1[0],                      ip2[3],ip2[2],ip2[1],ip2[0],                      proto->u_port_count,                      proto->low_p,                      proto->high_p);    }    dsize = SnortStrnlen((const char *)buffer, PROTO_BUFFER_SIZE);    *total_size += dsize;    /*    **  Set the payload size.  This is protocol independent.    */    g_tmp_pkt->dsize = dsize;    return 0;}static int LogPortscanAlert(Packet *p, char *msg, u_int32_t event_id,        u_int32_t event_ref, u_int32_t gen_id, u_int32_t sig_id){    char timebuf[TIMEBUF_SIZE];    ip_p src_addr;    ip_p dst_addr;    if(!p->iph)        return -1;    /* Do not log if being suppressed */    src_addr = GET_SRC_IP(p);    dst_addr = GET_DST_IP(p);    if( !sfthreshold_test(gen_id, sig_id, src_addr, dst_addr, p->pkth->ts.tv_sec) )    {        return 0;    }    ts_print((struct timeval *)&p->pkth->ts, timebuf);    fprintf(g_logfile, "Time: %s\n", timebuf);    if(event_id)        fprintf(g_logfile, "event_id: %u\n", event_id);    else        fprintf(g_logfile, "event_ref: %u\n", event_ref);#ifdef SUP_IP6    fprintf(g_logfile, "%s ", inet_ntoa(GET_SRC_IP(p)));    fprintf(g_logfile, "-> %s %s\n", inet_ntoa(GET_DST_IP(p)), msg);#else    fprintf(g_logfile, "%s ", inet_ntoa(p->iph->ip_src));    fprintf(g_logfile, "-> %s %s\n", inet_ntoa(p->iph->ip_dst), msg);#endif    fprintf(g_logfile, "%.*s\n", p->dsize, p->data);    fflush(g_logfile);    return 0;}static int GeneratePSSnortEvent(Packet *p,u_int32_t gen_id,u_int32_t sig_id,         u_int32_t sig_rev, u_int32_t class, u_int32_t priority, char *msg){    unsigned int event_id;        event_id = GenerateSnortEvent(p,gen_id,sig_id,sig_rev,class,priority,msg);    if(g_logfile)        LogPortscanAlert(p, msg, event_id, 0, gen_id, sig_id);    return event_id;}/***  NAME**    GenerateOpenPortEvent::*//****  We have to generate open port events differently because we tag these**  to the original portscan event.****  @return int****  @retval 0 success*/static int GenerateOpenPortEvent(Packet *p, u_int32_t gen_id, u_int32_t sig_id,        u_int32_t sig_rev, u_int32_t class, u_int32_t pri,         u_int32_t event_ref, struct timeval *event_time, char *msg){    Event event;    /*    **  This means that we logged an open port, but we don't have a event    **  reference for it, so we don't log a snort event.  We still keep    **  track of it though.    */    if(!event_ref)        return 0;    /* reset the thresholding subsystem checks for this packet */    sfthreshold_reset();                SetEvent(&event, gen_id, sig_id, sig_rev, class, pri, event_ref);    //CallAlertFuncs(p,msg,NULL,&event);    event.ref_time.tv_sec  = event_time->tv_sec;    event.ref_time.tv_usec = event_time->tv_usec;    if(p)    {        /*         * Do threshold test for suppression and thresholding.  We have to do it         * here since these are tagged packets, which aren't subject to thresholding,         * but we want to do it for open port events.         */        if( !sfthreshold_test(gen_id, sig_id, GET_SRC_IP(p),                            GET_DST_IP(p), p->pkth->ts.tv_sec) )        {            return 0;        }        CallLogFuncs(p,msg,NULL,&event);    }     else     {        return -1;    }    if(g_logfile)        LogPortscanAlert(p, msg, 0, event_ref, gen_id, sig_id);    return event.event_id;}/***  NAME**    MakeOpenPortInfo::*//** **  Write out the open ports info for open port alerts.****  @return integer*/static int MakeOpenPortInfo(PS_PROTO *proto, u_char *buffer, u_int *total_size,         void *user){    int dsize;    if(!total_size || !buffer)        return -1;    dsize = (IP_MAXPACKET - *total_size);    if(dsize < PROTO_BUFFER_SIZE)       return -1;     SnortSnprintf((char *)buffer, PROTO_BUFFER_SIZE,                  "Open Port: %u\n", *((unsigned short *)user));    dsize = SnortStrnlen((const char *)buffer, PROTO_BUFFER_SIZE);    *total_size += dsize;    /*    **  Set the payload size.  This is protocol independent.    */    g_tmp_pkt->dsize = dsize;    return 0;}/***  NAME**    MakePortscanPkt::*//***  We have to create this fake packet so portscan data can be passed**  through the unified output.****  We want to copy the network and transport layer headers into our**  fake packet.**  */static int MakePortscanPkt(PS_PKT *ps_pkt, PS_PROTO *proto, int proto_type,        void *user){    Packet *p;    unsigned long  tmp_addr;    unsigned int   hlen;    unsigned int   ip_size = 0;    struct pcap_pkthdr *pkth = (struct pcap_pkthdr *)g_tmp_pkt->pkth;      if(!ps_pkt && proto_type != PS_PROTO_OPEN_PORT)       return -1;    if(ps_pkt)    {         p = (Packet *)ps_pkt->pkt;        if(!p->iph)            return -1;        hlen = IP_HLEN(p->iph)<<2;        if ( p->iph != g_tmp_pkt->iph )            /*             * it happen that ps_pkt->pkt can be the same             * as g_tmp_pkt. Avoid overlapping copy then.             */             memcpy((IPHdr *)g_tmp_pkt->iph, p->iph, hlen);        if(ps_pkt->reverse_pkt)        {            tmp_addr = p->iph->ip_src.s_addr;            ((IPHdr *)g_tmp_pkt->iph)->ip_src.s_addr = p->iph->ip_dst.s_addr;            ((IPHdr *)g_tmp_pkt->iph)->ip_dst.s_addr = tmp_addr;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -