Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

sp_ftpbounce.c

Go to the documentation of this file.
00001 /* $Id$ */
00002 /* Copyright (C) 2005 Sourcefire Inc. */
00003 /* Author: Steven Sturges */
00004 
00005 /* sp_ftpbounce 
00006  * 
00007  * Purpose:
00008  *      Checks the address listed (a,b,c,d format) in the packet
00009  *      against the source address.
00010  *
00011  *      does not update the doe_ptr
00012  *
00013  * Arguments:
00014  *      Required:
00015  *        None
00016  *      Optional:
00017  *        None
00018  *   
00019  *   sample rules:
00020  *   alert tcp any any -> any 21 (content: "PORT"; \
00021  *       ftpbounce;
00022  *       msg: "FTP Bounce attack";)
00023  *
00024  * Effect:
00025  *
00026  *      Returns 1 if the address matches, 0 if it doesn't.
00027  *
00028  * Comments:
00029  *
00030  * Any comments?
00031  *
00032  */
00033 
00034 #ifdef HAVE_CONFIG_H
00035 #include "config.h"
00036 #endif
00037 
00038 #include <sys/types.h>
00039 #include <stdlib.h>
00040 #include <ctype.h>
00041 #ifdef HAVE_STRINGS_H
00042 #include <strings.h>
00043 #endif
00044 #include <errno.h>
00045 
00046 #include "bounds.h"
00047 #include "rules.h"
00048 #include "decode.h"
00049 #include "plugbase.h"
00050 #include "parser.h"
00051 #include "debug.h"
00052 #include "util.h"
00053 #include "plugin_enum.h"
00054 #include "mstring.h"
00055 
00056 extern u_int8_t *doe_ptr;
00057 extern u_int8_t DecodeBuffer[DECODE_BLEN];
00058 
00059 void FTPBounceInit(char *, OptTreeNode *, int);
00060 void FTPBounceParse(char *, OptTreeNode *);
00061 int FTPBounce(Packet *, struct _OptTreeNode *, OptFpList *);
00062 
00063 /****************************************************************************
00064  * 
00065  * Function: SetupFTPBounce()
00066  *
00067  * Purpose: Load 'er up
00068  *
00069  * Arguments: None.
00070  *
00071  * Returns: void function
00072  *
00073  ****************************************************************************/
00074 void SetupFTPBounce(void)
00075 {
00076     /* map the keyword to an initialization/processing function */
00077     RegisterPlugin("ftpbounce", FTPBounceInit);
00078 
00079     DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: FTPBounce Setup\n"););
00080 }
00081 
00082 
00083 /****************************************************************************
00084  * 
00085  * Function: FTPBounceInit(char *, OptTreeNode *)
00086  *
00087  * Purpose: Generic rule configuration function.  Handles parsing the rule 
00088  *          information and attaching the associated detection function to
00089  *          the OTN.
00090  *
00091  * Arguments: data => rule arguments/data
00092  *            otn => pointer to the current rule option list node
00093  *            protocol => protocol the rule is on (we don't care in this case)
00094  *
00095  * Returns: void function
00096  *
00097  ****************************************************************************/
00098 void FTPBounceInit(char *data, OptTreeNode *otn, int protocol)
00099 {
00100     OptFpList *fpl;
00101 
00102     /* this is where the keyword arguments are processed and placed into the 
00103        rule option's data structure */
00104     FTPBounceParse(data, otn);
00105 
00106     fpl = AddOptFuncToList(FTPBounce, otn);
00107 
00108     /* attach it to the context node so that we can call each instance
00109      * individually
00110      */
00111     fpl->context = (void *) NULL;
00112 }
00113 
00114 
00115 
00116 /****************************************************************************
00117  * 
00118  * Function: FTPBounceParse(char *, void *, OptTreeNode *)
00119  *
00120  * Purpose: This is the function that is used to process the option keyword's
00121  *          arguments and attach them to the rule's data structures.
00122  *
00123  * Arguments: data => argument data
00124  *            otn => pointer to the current rule's OTN
00125  *
00126  * Returns: void function
00127  *
00128  ****************************************************************************/
00129 void FTPBounceParse(char *data, OptTreeNode *otn)
00130 {
00131     char **toks;
00132     int num_toks;
00133 
00134     toks = mSplit(data, ",", 12, &num_toks, 0);
00135 
00136     if(num_toks > 0)
00137         FatalError("ERROR %s (%d): Bad arguments to ftpbounce: %s\n", file_name,
00138                 file_line, data);
00139 
00140     mSplitFree(&toks, num_toks);
00141 }
00142 
00143 
00144 /****************************************************************************
00145  * 
00146  * Function: FTPBounce(char *, OptTreeNode *, OptFpList *)
00147  *
00148  * Purpose: Use this function to perform the particular detection routine
00149  *          that this rule keyword is supposed to encompass.
00150  *
00151  * Arguments: p => pointer to the decoded packet
00152  *            otn => pointer to the current rule's OTN
00153  *            fp_list => pointer to the function pointer list
00154  *
00155  * Returns: If the detection test fails, this function *must* return a zero!
00156  *          On success, it calls the next function in the detection list 
00157  *
00158  ****************************************************************************/
00159 int FTPBounce(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00160 {
00161     u_int32_t ip = 0;
00162     int octet=0;
00163     char *this_param = doe_ptr;
00164 
00165     int dsize;
00166     int use_alt_buffer = p->packet_flags & PKT_ALT_DECODE;
00167     char *base_ptr, *end_ptr, *start_ptr;
00168 
00169     if (!doe_ptr)
00170     {
00171         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00172                     "[*] ftpbounce no doe_ptr set..\n"););
00173         return 0;
00174     }
00175 
00176     if(use_alt_buffer)
00177     {
00178         dsize = p->alt_dsize;
00179         start_ptr = (char *) DecodeBuffer;        
00180         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, 
00181                     "Using Alternative Decode buffer!\n"););
00182 
00183     }
00184     else
00185     {
00186         start_ptr = p->data;
00187         dsize = p->dsize;
00188     }
00189 
00190     DEBUG_WRAP(
00191             DebugMessage(DEBUG_PATTERN_MATCH,"[*] ftpbounce firing...\n");
00192             DebugMessage(DEBUG_PATTERN_MATCH,"payload starts at %p\n", start_ptr);
00193             );  /* END DEBUG_WRAP */
00194 
00195     /* save off whatever our ending pointer is */
00196     end_ptr = start_ptr + dsize;
00197     base_ptr = start_ptr;
00198 
00199     if(doe_ptr)
00200     {
00201         /* @todo: possibly degrade to use the other buffer, seems non-intuitive*/        
00202         if(!inBounds(start_ptr, end_ptr, doe_ptr))
00203         {
00204             DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00205                                     "[*] ftpbounce bounds check failed..\n"););
00206             return 0;
00207         }
00208     }
00209 
00210     while (isspace((int)*this_param) && (this_param < end_ptr)) this_param++;
00211     
00212     do
00213     {
00214         int value = 0;
00215         do
00216         {
00217             if (!isdigit((int)*this_param))
00218             {
00219                 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00220                     "[*] ftpbounce non digit char failed..\n"););
00221                 return 0;
00222             }
00223             value = value * 10 + (*this_param - '0');
00224             this_param++;
00225         } while ((this_param < end_ptr) &&
00226                  (*this_param != ',') &&
00227                   (!(isspace((int)*this_param))));
00228         if (value > 0xFF)
00229         {
00230             DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00231                 "[*] ftpbounce value > 256 ..\n"););
00232             return 0;
00233         }
00234         if (octet  < 4)
00235         {
00236             ip = (ip << 8) + value;
00237         }
00238 
00239         if (!isspace((int)*this_param))
00240             this_param++;
00241         octet++;
00242     } while ((this_param < end_ptr) && !isspace((int)*this_param) && (octet < 4));
00243 
00244     if (octet < 4)
00245     {
00246         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00247             "[*] ftpbounce insufficient data ..\n"););
00248         return 0;
00249     }
00250 
00251     if (ip != ntohl(p->iph->ip_src.s_addr))
00252     {
00253         return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00254     }
00255     else
00256     {
00257         DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00258             "PORT command not being used in bounce\n"););
00259         return 0;
00260     }
00261     
00262     /* Never reached */
00263     return 0;
00264 }

Generated on Sun May 14 14:51:13 2006 by  doxygen 1.4.2