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

📄 pp_ftp.c

📁 snort2.8.4版本
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $Id$ *//* ** Copyright (C) 2004-2008 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. *//* pp_ftp.c  *  * Purpose:  FTP sessions contain commands and responses.  Certain *           commands are vectors of attack.  This module checks *           those FTP client commands and their parameter values, as *           well as the server responses per the configuration. * * Arguments:  None *    * Effect:  Alerts may be raised * * Comments: * *//* your preprocessor header file goes here */#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include <string.h>#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#ifndef WIN32#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <ctype.h>#else#include <windows.h>#endif#include "ftpp_eo_log.h"#include "pp_ftp.h"#include "pp_telnet.h"#include "ftpp_return_codes.h"#include "ftp_cmd_lookup.h"#include "ftp_bounce_lookup.h"//#include "decode.h"#include "debug.h"#include "stream_api.h"//#include "plugbase.h"#ifndef MAXHOSTNAMELEN /* Why doesn't Windows define this? */#define MAXHOSTNAMELEN 256#endif#ifdef SUP_IP6#include "ipv6_port.h"#endif/* * Used to keep track of pipelined commands and the last one * that resulted in a  */static int ftp_cmd_pipe_index = 0;#if 0/* * Function: getIP(char **ip_start, *                 char *last_char, *                 char term_char, *                 u_int32_t *ipRet, *                 u_int16_t *portRet) * * Purpose: Returns a 32bit IP address and port from an FTP-style *          string -- ie, a,b,c,d,p1,p2.  Stops checking when term_char *          is seen.  Used to get address and port information from FTP *          PORT command and server response to PASV command. * * Arguments ip_start        => Pointer to pointer to the start of string. *                              Updated to end of IP address if successful. *           last_char       => End of string *           term_char       => Character delimiting the end of the address. *           ipRet           => Return pointer to 32bit address on success *           portRet         => Return pointer to 16bit port on success * * Returns: int => return code indicating error or success * */int getIP(const int type, const char **ip_start, const char *last_char, char term_char,          snort_ip *ipRet, u_int16_t *portRet){    u_int32_t ip=0;    u_int16_t port=0;    int octet=0;    const char *this_param = *ip_start;        do    {        int value = 0;        do        {            if (!isdigit((int)(*this_param)))            {                return FTPP_NON_DIGIT;            }            value = value * 10 + (*this_param - '0');            this_param++;        } while ((this_param < last_char) &&                 (*this_param != ',') &&                 (*this_param != term_char));        if (value > 0xFF)        {            return FTPP_INVALID_ARG;        }        if (octet  < 4)        {            ip = (ip << 8) + value;        }        else        {            port = (port << 8) + value;        }        if (*this_param != term_char)            this_param++;        octet++;    } while ((this_param < last_char) && (*this_param != term_char) );    if (octet != 6)    {        return FTPP_MALFORMED_IP_PORT;    }#ifdef SUP_IP6// XXX-IPv6 NOT YET IMPLEMENTED - IPv4 only at the moment    sfip_set_raw(ipRet, &ip, AF_INET);#else    *ipRet = ip;#endif    *portRet = port;    *ip_start = this_param;    return FTPP_SUCCESS;}#endif/* * Function: getIP959(char **ip_start, *                 char *last_char, *                 char term_char, *                 u_int32_t *ipRet, *                 u_int16_t *portRet) * * Purpose: Returns a 32bit IP address and port from an RFC 959 FTP-style *          string -- ie, a,b,c,d,p1,p2.  Stops checking when term_char *          is seen.  Used to get address and port information from FTP *          PORT command and server response to PASV command. * * Arguments ip_start        => Pointer to pointer to the start of string. *                              Updated to end of IP address if successful. *           last_char       => End of string *           term_char       => Character delimiting the end of the address. *           ipRet           => Return pointer to 32bit address on success *           portRet         => Return pointer to 16bit port on success * * Returns: int => return code indicating error or success */static int getIP959(    const char **ip_start, const char *last_char, char term_char,    snort_ip *ipRet, u_int16_t *portRet){    u_int32_t ip=0;    u_int16_t port=0;    int octet=0;    const char *this_param = *ip_start;    do    {        int value = 0;        do        {            if (!isdigit((int)(*this_param)))            {                return FTPP_NON_DIGIT;            }            value = value * 10 + (*this_param - '0');            this_param++;        } while ((this_param < last_char) &&                 (*this_param != ',') &&                 (*this_param != term_char));        if (value > 0xFF)        {            return FTPP_INVALID_ARG;        }        if (octet  < 4)        {            ip = (ip << 8) + value;        }        else        {            port = (port << 8) + value;        }        if (*this_param != term_char)            this_param++;        octet++;    } while ((this_param < last_char) && (*this_param != term_char) );    if (octet != 6)    {        return FTPP_MALFORMED_IP_PORT;    }#ifdef SUP_IP6    ip = htonl(ip);    sfip_set_raw(ipRet, &ip, AF_INET);#else     *ipRet = ip;#endif    *portRet = port;    *ip_start = this_param;    return FTPP_SUCCESS;}/* * getIP1639() parses the LPRT command parameters which have this * format (ftyp == e_long_host_port): * *     LPRT af,hal,h1,h2,h3,h4...,pal,p1,p2... *     LPRT 4,4,132,235,1,2,2,24,131 *     LPRT 6,16,16,128,0,...,0,8,128,0,32,12,65,123,2,20,162 * * (The above examples correspond to the EPRT examples below.) * * af (address family) is the IP version.  h# and p# are in network * byte order (high byte first). * * This function is called for the LPSV response as well, which  * has this format: * *    228 <human readable text> (af,hal,h1,h2,h3,h4...,pal,p1,p2...) */static int getIP1639 (    const char **ip_start, const char *last_char, char term_char,    snort_ip* ipRet, u_int16_t *portRet){    char bytes[21];  /* max of 1+5+3 and 1+17+3 */    const char* tok = *ip_start;    int nBytes = 0;    bytes[0] = 0;    /* first we just try to get a sequence of csv bytes */    while ( nBytes < sizeof(bytes) && tok < last_char )    {        char* endPtr = (char*)tok;        unsigned long val = strtoul(tok, &endPtr, 10);        if (            val > 255 || endPtr == tok ||            ( *endPtr && *endPtr != ',' && endPtr != last_char )        ) {            return FTPP_INVALID_ARG;        }        bytes[nBytes++] = (uint8_t)val;        tok = (endPtr < last_char) ? endPtr + 1 : endPtr;    }    *ip_start = tok;    /* now we check that the we have a valid sequence of */    /* bytes and convert the address and port accordingly */    switch ( bytes[0] )    {    case 4:        if ( nBytes != 9 || bytes[1] != 4 || bytes[6] != 2 )            return FTPP_INVALID_ARG;        {            uint32_t ip4 = 0;            int n;            for ( n = 0; n < 4; n++ )                 ip4 = (ip4 << 8) | bytes[n+2];#ifdef SUP_IP6            /* don't call sfip_set_raw() on raw bytes               to avoid possible word alignment issues */            ip4 = htonl(ip4);            sfip_set_raw(ipRet, (void*)&ip4, AF_INET);#else            *ipRet = ip4;#endif        }        *portRet = (bytes[7] << 8) | bytes[8];        break;#ifdef SUP_IP6    case 6:        if ( nBytes != 21 || bytes[1] != 16 || bytes[18] != 2 )            return FTPP_INVALID_ARG;        sfip_set_raw(ipRet, bytes+2, AF_INET6);        *portRet = (bytes[19] << 8) | bytes[20];        break;#endif    default:        return FTPP_INVALID_ARG;    }    return FTPP_SUCCESS;}/* * getIP2428() parses the EPRT command parameters which have this * format (ftyp == e_extd_host_port): * *     EPRT |<family>|address|<tcp-port>| *     EPRT |1|132.235.1.2|6275| *     EPRT |2|1080::8:800:200C:417A|5282| * * Note that the address family is 1|2 (as in RFC 2428), not 4|6 * (as in IP version), nor 2|10 (as in AF_INET[6]). * * This function is called for the EPSV response as well, which * has this format (ftyp == e_int): * *     229 <human readable text> (|||<tcp-port>|) * * The delimiter may be other than '|' if required to represent * the protocol address, but must be between 33-126 inclusive. * Other delimiters aren't required for IPv{4,6} but we allow * them for flexibility. * * It is assumed that *ip_start points to the first delimiter in * both cases. *//* * this copy is unfortunate but inet_pton() doesn't * like the delim and the src buf is const so ... */void CopyField (    char* buf, const char* tok, int max, const char* end, char delim){    int len = end - tok + 1;    char* s;    if ( len >= max )    {        strncpy(buf, tok, max);        buf[max-1] = '\0';    }    else    {        strncpy(buf, tok, len);        buf[len] = '\0';    }    s = index(buf, delim);

⌨️ 快捷键说明

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