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

📄 spp_http_decode.c

📁 该软件是一个有名的基于网络的入侵检测系统
💻 C
字号:
/*
** Copyright (C) 1998,1999,2000 Martin Roesch <roesch@clark.net>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** 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.
*/

/* $Id: spp_http_decode.c,v 1.11 2000/03/16 02:58:48 roesch Exp $ */
/* spp_http_decode 
 * 
 * Purpose:
 *
 * This preprocessor normalizes HTTP requests from remote machines by
 * converting any %XX character substitutions to their ASCII equivalent.
 * This is very useful for doing things like defeating hostile attackers
 * trying to stealth themselves from IDSs by mixing these substitutions 
 * in with the request.
 *
 * Arguments:
 *   
 * This plugin takes a list of integers representing the TCP ports that the
 * user is interested in having normalized
 *
 * Effect:
 *
 * Changes the data in the packet payload to a plain ASCII representation 
 * and changes p->dsize to reflect the new (smaller) payload size.
 *
 * Comments:
 *
 * It could be interesting to generate an alert based on the number of
 * characters converted for a single packet, through some sort of threshold
 * setting.
 *
 */
#include "spp_http_decode.h"
#include <ctype.h>

extern char *file_name;
extern int file_line;

/* Instantiate the list of ports we're going to watch */
PortList HttpDecodePorts;

/*
 * Function: SetupHttpDecode()
 *
 * Purpose: Registers the preprocessor keyword and initialization 
 *          function into the preprocessor list.
 *
 * Arguments: None.
 *
 * Returns: void function
 *
 */
void SetupHttpDecode()
{
    /* link the preprocessor keyword to the init function in 
       the preproc list */
    RegisterPreprocessor("http_decode", HttpDecodeInit);

#ifdef DEBUG
    printf("Preprocessor: HttpDecode in setup...\n");
#endif
}


/*
 * Function: HttpDecodeInit(u_char *)
 *
 * Purpose: Processes the args sent to the preprocessor, sets up the
 *          port list, links the processing function into the preproc
 *          function list
 *
 * Arguments: args => ptr to argument string
 *
 * Returns: void function
 *
 */
void HttpDecodeInit(u_char *args)
{
#ifdef DEBUG
    printf("Preprocessor: HttpDecode Initialized\n");
#endif

    /* parse the argument list into a list of ports to normalize */
    SetPorts((char *)args);

    /* Set the preprocessor function into the function list */
    AddFuncToPreprocList(PreprocUrlDecode);
}



/*
 * Function: SetPorts(char *)
 *
 * Purpose: Reads the list of port numbers from the argument string and 
 *          parses them into the port list data struct
 *
 * Arguments: portlist => argument list
 *
 * Returns: void function
 *
 */
void SetPorts(char *portlist)
{
    char **toks;
    int num_toks;
    int num_ports = 0;

    if (portlist == NULL)
    {
        FatalError("ERROR %s (%d)=> No arguments to http_decode preprocessor!\n", file_name, file_line);
    }

    /* tokenize the argument list */
    toks = mSplit(portlist, " ", 31, &num_toks, '\\');

    /* convert the tokens and place them into the port list */
    for (num_ports = 0; num_ports < num_toks; num_ports++)
    {
        HttpDecodePorts.ports[num_ports] = atoi(toks[num_ports]);
    }   

    HttpDecodePorts.num_entries = num_ports;

#ifdef DEBUG
    printf("Decoding HTTP on %d ports: ", HttpDecodePorts.num_entries);

    for (num_ports = 0; num_ports < HttpDecodePorts.num_entries; num_ports++)
    {
        printf("%d ", HttpDecodePorts.ports[num_ports]);
    }

    printf("\n");
#endif

}


/*
 * Function: PreprocUrlDecode(Packet *)
 *
 * Purpose: Inspects the packet's payload for "Escaped" characters and 
 *          converts them back to their ASCII values.  This function
 *          is based on the NCSA code and was contributed by Michael Henry!
 *
 * Arguments: p => pointer to the current packet data struct 
 *
 * Returns: void function
 *
 */
void PreprocUrlDecode(Packet *p)
{
    char *url;     /* this is where the converted data will be written */
    char *index;   /* this is the index pointer to walk thru the data */
    char *end;     /* points to the end of the payload, for loop control */
    u_short psize; /* payload size */
    int i;         /* loop counter */

#ifdef DEBUG
    printf("http decoder init on %d bytes\n", p->dsize);
#endif

    /* check to make sure we're talking TCP and that the TWH has already
       completed before processing anything */
    if (!PacketIsTCP(p))
    {
#ifdef DEBUG
        printf("It isn't TCP session traffic\n");
#endif
        return;
    }

    if (!IsTcpSessionTraffic(p))
    {
#ifdef DEBUG
        printf("It isn't TCP session traffic\n");
#endif
        return;
    }

    /* check the port against the decode port list */
    for (i = 0; i < HttpDecodePorts.num_entries; i++)
    {
        if (HttpDecodePorts.ports[i] == p->dp)
        {
            /* on match, normalize the data */
#ifdef DEBUG
            printf("Got HTTP traffic (%d bytes)!\n", p->dsize);
            printf("%s\n", p->data);
#endif
            /* setup the pointers */
            url = (char *) p->data;
            index = (char *) p->data;
            end = (char *) p->data + p->dsize;
            psize = (u_short) (p->dsize);

            /* walk thru each char in the payload */
            while (index < end)
            {
                /* if it's potentially "escaped" and not too close to the end of 
                   the payload */
                if ((*index == '%') && (index < end - 2))
                {
                    /* and if the following two chars are hex digits */
                    if (isxdigit((int)*(index+1)) && isxdigit((int)*(index+2)))
                    {
                        /*convert it and stuff it */
                        *url = (nibble(*(index+1)) << 4) | nibble(*(index+2));
                        index += 3; 
                        url++;
                        psize -= 2;
                    }
                    else
                    {
                        *url = *index;
                        url++;
                        index++;
                    }        
                }
                else
                {
                    *url = *index;
                    url++;
                    index++;
                }
            }

            /* set the payload size to reflect the new size */ 
            p->dsize = psize;

#ifdef DEBUG
            printf("New size: %d\n", p->dsize);
            printf("converted data:\n");
            PrintNetData(stdout, p->data, psize);
#endif

            return;
        }
    }
}




/*
 * Function: nibble(char)
 *
 * Purpose: converts a hex character into a value in the range 0..15
 *
 * Arguments: what => the character in question
 *
 * Returns: The converted character or -1 if the character is not hex
 *
 */
int nibble(char what)
{
    if (isdigit((int)what)) return what - '0';

    if (isxdigit((int)what)) return toupper((int)what) - 'A' + 10;

    return -1;
}

⌨️ 快捷键说明

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