📄 pp_ftp.c
字号:
if ( s ) *s = '\0'; else *buf = '\0';}static int getIP2428 ( const char **ip_start, const char *last_char, char term_char, snort_ip* ipRet, u_int16_t *portRet, FTP_PARAM_TYPE ftyp){ const char* tok = *ip_start; char delim = *tok; int field = 1, fieldMask = 0; int family = AF_UNSPEC, port = 0; char buf[64]; IP_CLEAR((*ipRet)); *portRet = 0; /* check first delimiter */ if ( delim < 33 || delim > 126 ) return FTPP_INVALID_ARG; while ( tok && tok < last_char && field < 4 ) { int check = (*++tok != delim) ? field : 0; switch ( check ) { case 0: /* empty */ break; case 1: /* check family */ family = atoi(tok); if ( family == 1 ) family = AF_INET;#ifdef SUP_IP6 else if ( family == 2 ) family = AF_INET6;#endif else return FTPP_INVALID_ARG; fieldMask |= 1; break; case 2: /* check address */ CopyField(buf, tok, sizeof(buf), last_char, delim);#ifdef SUP_IP6 if ( sfip_pton(buf, ipRet) != SFIP_SUCCESS || family != ipRet->family )#else *ipRet = ntohl(inet_addr(buf)); if ( *ipRet == INADDR_NONE || family != AF_INET )#endif return FTPP_INVALID_ARG; fieldMask |= 2; break; case 3: /* check port */ port = atoi(tok); if ( port < 0 || port > 65535 ) return FTPP_MALFORMED_IP_PORT; *portRet = port; fieldMask |= 4; break; } /* advance to next field */ tok = index(tok, delim); field++; } if ( *tok == delim ) tok++; *ip_start = tok; if ( ftyp == e_int && fieldMask == 4 ) /* FIXTHIS: do we need to check for bounce if addr present? */ return FTPP_SUCCESS; if ( ftyp == e_extd_host_port && fieldMask == 7 ) return FTPP_SUCCESS; return FTPP_INVALID_ARG;}static int getFTPip( FTP_PARAM_TYPE ftyp, const char **ip_start, const char *last_char, char term_char, snort_ip *ipRet, u_int16_t *portRet) { if ( ftyp == e_host_port ) { return getIP959(ip_start, last_char, term_char, ipRet, portRet); } if ( ftyp == e_long_host_port ) { return getIP1639(ip_start, last_char, term_char, ipRet, portRet); } return getIP2428(ip_start, last_char, term_char, ipRet, portRet, ftyp);}/* * Function: validate_date_format( * FTP_DATE_FMT *ThisFmt, * char **this_param) * * Purpose: Recursively determines whether a date matches the * a valid format. * * Arguments: ThisFmt => Pointer to the current format * this_param => Pointer to start of the portion to validate. * Updated to end of valid section if valid. * * Returns: int => return code indicating error or success * */static int validate_date_format(FTP_DATE_FMT *ThisFmt, const char **this_param){ int valid_string = 0; int checked_something_else = 0; int checked_next = 0; int iRet = FTPP_ALERT; const char *curr_ch; if (!ThisFmt) return FTPP_INVALID_ARG; if (!this_param || !(*this_param)) return FTPP_INVALID_ARG; curr_ch = *this_param; if (!ThisFmt->empty) { char *format_char = ThisFmt->format_string; do { switch (*format_char) { case 'n': if (!isdigit((int)(*curr_ch))) { /* Return for non-digit */ return FTPP_INVALID_DATE; } curr_ch++; format_char++; break; case 'C': if (!isalpha((int)(*curr_ch))) { /* Return for non-char */ return FTPP_INVALID_DATE; } curr_ch++; format_char++; break; default: if (*curr_ch != *format_char) { /* Return for non-matching char */ return FTPP_INVALID_DATE; } curr_ch++; format_char++; break; } valid_string = 1; } while ((*format_char != '\0') && !isspace((int)(*curr_ch))); if ((*format_char != '\0') && isspace((int)(*curr_ch))) { /* Didn't have enough chars to complete this format */ return FTPP_INVALID_DATE; } } if ((ThisFmt->optional) && !isspace((int)(*curr_ch))) { const char *tmp_ch = curr_ch; iRet = validate_date_format(ThisFmt->optional, &tmp_ch); if (iRet == FTPP_SUCCESS) curr_ch = tmp_ch; } if ((ThisFmt->next_a) && !isspace((int)(*curr_ch))) { const char *tmp_ch = curr_ch; checked_something_else = 1; iRet = validate_date_format(ThisFmt->next_a, &tmp_ch); if (iRet == FTPP_SUCCESS) { curr_ch = tmp_ch; } else if (ThisFmt->next_b) { iRet = validate_date_format(ThisFmt->next_b, &tmp_ch); if (iRet == FTPP_SUCCESS) curr_ch = tmp_ch; } if (ThisFmt->next) { iRet = validate_date_format(ThisFmt->next, &tmp_ch); if (iRet == FTPP_SUCCESS) { curr_ch = tmp_ch; checked_next = 1; } } if (iRet == FTPP_SUCCESS) { *this_param = curr_ch; return iRet; } } if ((!checked_next) && (ThisFmt->next)) { const char *tmp_ch = curr_ch; checked_something_else = 1; iRet = validate_date_format(ThisFmt->next, &tmp_ch); if (iRet == FTPP_SUCCESS) { curr_ch = tmp_ch; checked_next = 1; } } if ((isspace((int)(*curr_ch))) && ((!ThisFmt->next) || checked_next)) { *this_param = curr_ch; return FTPP_SUCCESS; } if (valid_string) { int all_okay = 0; if (checked_something_else) { if (iRet == FTPP_SUCCESS) all_okay = 1; } else { all_okay = 1; } if (all_okay) { *this_param = curr_ch; return FTPP_SUCCESS; } } return FTPP_INVALID_DATE;}/* * Function: validate_param( * Packet *p * char *param * char *end * FTP_PARAM_FMT *param_format, * FTP_SESSION *Session) * * Purpose: Validates the current parameter against the format * specified. * * Arguments: p => Pointer to the current packet * params_begin => Pointer to beginning of parameters * params_end => End of params buffer * param_format => Parameter format specifier for this command * Session => Pointer to the session info * * Returns: int => return code indicating error or success * */static int validate_param(SFSnortPacket *p, const char *param, const char *end, FTP_PARAM_FMT *ThisFmt, FTP_SESSION *Session){ int iRet; const char *this_param = param; if (param > end) return FTPP_ALERT; switch (ThisFmt->type) { case e_head: /* shouldn't get here, but just in case */ break; case e_unrestricted: /* strings/filenames only occur as the last param, * so move to the end of the param buffer. */ { do { this_param++; } while (this_param < end); } break; case e_strformat: /* Check for 2 % signs within the parameter for an FTP command * 2 % signs is the magic number per existing rules (24 Sep 2004) */#define MAX_PERCENT_SIGNS 2 { int numPercents = 0; do { if (*this_param == '%') { numPercents++; if (numPercents >= MAX_PERCENT_SIGNS) { break; } } this_param++; } while ((this_param < end) && (*this_param != ' ')); if (numPercents >= MAX_PERCENT_SIGNS) { /* Alert on string format attack in parameter */ ftp_eo_event_log(Session, FTP_EO_PARAMETER_STR_FORMAT, NULL, NULL); return FTPP_ALERTED; } } break; case e_int: /* check that this_param is all digits up to next space */ { do { if (!isdigit((int)(*this_param))) { /* Alert on non-digit */ return FTPP_INVALID_PARAM; } this_param++; } while ((this_param < end) && (*this_param != ' ') ); } break; case e_number: /* check that this_param is all digits up to next space * and value is between 1 & 255 */ { int iValue = 0; do { if (!isdigit((int)(*this_param))) { /* Alert on non-digit */ return FTPP_INVALID_PARAM; } iValue = iValue * 10 + (*this_param - '0'); this_param++; } while ((this_param < end) && (*this_param != ' ') ); if ((iValue > 255) || (iValue == 0)) return FTPP_INVALID_PARAM; } break; case e_char: /* check that this_param is one of chars specified */ { int bitNum = (*this_param & 0x1f); if (!isalpha((int)(*this_param))) { /* Alert on non-char */ return FTPP_INVALID_PARAM; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -