Esempio n. 1
0
/*
 *  Check cursor function
 *
 *          p: packet data structure, same as the one found in snort.
 * cursorInfo: data defined in the detection plugin for this rule cursor option
 *     cursor: current position within buffer
 *
 * Returns:
 *    > 0 : match found
 *    = 0 : no match found
 *    < 0 : error
 *
 * Predefined constants:
 *    (see sf_snort_plugin_api.h for more values)
 *    CURSOR_IN_BOUNDS     -  if content specifier is found within buffer
 *    CURSOR_OUT_OF_BOUNDS -  if content specifier is not found within buffer
 *
 * Notes:
 *   Since we are checking the cursor position within a buffer, relativity is assumed.
 *     To check absolute position within a buffer, a NULL pointer can be passed in.
 *     In this case, offset will be checked from the start of the given buffer.
 *
 *   Currently support:
 *    options:
 *      offset
 *    buffers:
 *      normalized(alt-decode)
 *      raw
 *      uri
 *
 */
ENGINE_LINKAGE int checkCursor(void *p, CursorInfo* cursorInfo, const u_int8_t *cursor)
{
    /* Get byte_extracted offset if present */
    if (cursorInfo->offset_location)
    {
        cursorInfo->offset = *cursorInfo->offset_location;
    }

    return checkCursorInternal(p, cursorInfo->flags, cursorInfo->offset, cursor);
}
/* 
 *  Content Option processing function
 * 
 *       p: packet data structure, same as the one found in snort.
 * content: data defined in the detection plugin for this rule content option
 *  cursor: updated to point the 1st byte after the match
 *
 * Returns: 
 *    > 0 : match found
 *    = 0 : no match found
 *    < 0 : error
 *
 * Predefined constants: 
 *    (see sf_snort_plugin_api.h for more values)
 *    CONTENT_MATCH   -  if content specifier is found within buffer 
 *    CONTENT_NOMATCH -  if content specifier is not found within buffer 
 * 
 * Notes:
 *   For multiple URI buffers, we scan each buffer, if any one of them 
 *   contains the content we return a match. This is essentially an OR
 *   operation.
 *
 *   Currently support:
 *    options:
 *      nocase
 *      offset
 *      depth
 *    buffers:
 *      normalized(alt-decode)
 *      raw
 *      uri
 *      post
 *      
 */
ENGINE_LINKAGE int contentMatch(void *p, ContentInfo* content, const u_int8_t **cursor)
{
    const u_int8_t * q = NULL;
    const u_int8_t * buffer_start;
    const u_int8_t * buffer_end = NULL;
    u_int  buffer_len;
    int    length;
    int    i;
    char   relative = 0;
    SFSnortPacket *sp = (SFSnortPacket *) p;

    if (content->flags & CONTENT_RELATIVE)
    {
        if( !cursor || !(*cursor) )
        {
            return CONTENT_NOMATCH;
        } 
        relative = 1;
    }

    if (content->flags & (CONTENT_BUF_URI | CONTENT_BUF_POST))
    {
        for (i=0;i<sp->num_uris; i++)
        {
            if ((content->flags & CONTENT_BUF_URI) && (i != HTTP_BUFFER_URI))
            {
                /* Not looking at the "URI" buffer...
                 * keep going. */
                continue;
            }

            if ((content->flags & CONTENT_BUF_POST) && (i != HTTP_BUFFER_CLIENT_BODY))
            {
                /* Not looking at the "POST" buffer...
                 * keep going. */
                continue;
            }

            if (relative)
            {
                if (checkCursorInternal(p, content->flags, content->offset, *cursor) <= 0)
                {
                    /* Okay, cursor is NOT within this buffer... */
                    continue;
                }
                buffer_start = *cursor + content->offset;
            }
            else
            {
                buffer_start = _ded.uriBuffers[i]->uriBuffer + content->offset;
            }

            if (_uri_buffer_end)
            {
                buffer_end = _uri_buffer_end;
            }
            else
            {
                buffer_end = _ded.uriBuffers[i]->uriBuffer + _ded.uriBuffers[i]->uriLength;
            }

            length = buffer_len = buffer_end - buffer_start;

            if (length <= 0)
            {
                continue;
            }
            
            /* Don't bother looking deeper than depth */
            if ( content->depth != 0 && content->depth < buffer_len )
            {
                buffer_len = content->depth;
            }

            q = hbm_match((HBM_STRUCT*)content->boyer_ptr,buffer_start,buffer_len);

            if (q)
            {
                if (content->flags & CONTENT_END_BUFFER)
                {
                    _uri_buffer_end = q;
                }
                if (cursor)
                {
                    *cursor = q + content->patternByteFormLength;
                }
                return CONTENT_MATCH;
            }
        }

        return CONTENT_NOMATCH;
    }

    if (relative)
    {
        if (checkCursorInternal(p, content->flags, content->offset, *cursor) <= 0)
        {
            return CONTENT_NOMATCH;
        }

        if ((content->flags & CONTENT_BUF_NORMALIZED) && (sp->flags & FLAG_ALT_DECODE))
        {
            if (_alt_buffer_end)
            {
                buffer_end = _alt_buffer_end;
            }
            else
            {         
                buffer_end = _ded.altBuffer + sp->normalized_payload_size;
            }
        }
        else
        {
            if (_buffer_end)
            {
                buffer_end = _buffer_end;
            }
            else
            {
                buffer_end = sp->payload + sp->payload_size;
            }
        }
        buffer_start = *cursor + content->offset;
    }
    else
    {
        if ((content->flags & CONTENT_BUF_NORMALIZED) && (sp->flags & FLAG_ALT_DECODE))
        {
            buffer_start = _ded.altBuffer + content->offset;
            if (_alt_buffer_end)
            {
                buffer_end = _alt_buffer_end;
            }
            else
            {
                buffer_end = _ded.altBuffer + sp->normalized_payload_size;
            }
        }
        else
        {
            buffer_start = sp->payload + content->offset;
            if (_buffer_end)
            {
                buffer_end = _buffer_end;
            }
            else
            {
                buffer_end = sp->payload + sp->payload_size;
            }
        }
    }
    length = buffer_len = buffer_end - buffer_start;

    if (length <= 0)
    {
        return CONTENT_NOMATCH;
    }

    /* Don't bother looking deeper than depth */
    if ( content->depth != 0 && content->depth < buffer_len )
    {
        buffer_len = content->depth;
    }

    q = hbm_match((HBM_STRUCT*)content->boyer_ptr,buffer_start,buffer_len);

    if (q)
    {
        if (content->flags & CONTENT_END_BUFFER)
        {
            if ((content->flags & CONTENT_BUF_NORMALIZED) && (sp->flags & FLAG_ALT_DECODE))
            {
                _alt_buffer_end = q;
            }
            else
            {
                _buffer_end = q;
            }
        }
        if (cursor)
        {
            *cursor = q + content->patternByteFormLength;
        }
        return CONTENT_MATCH;
    }

    return CONTENT_NOMATCH;
}
Esempio n. 3
0
/* 
 *  Check cursor function
 * 
 *          p: packet data structure, same as the one found in snort.
 * cursorInfo: data defined in the detection plugin for this rule cursor option
 *     cursor: current position within buffer
 *
 * Returns: 
 *    > 0 : match found
 *    = 0 : no match found
 *    < 0 : error
 *
 * Predefined constants: 
 *    (see sf_snort_plugin_api.h for more values)
 *    CURSOR_IN_BOUNDS     -  if content specifier is found within buffer 
 *    CURSOR_OUT_OF_BOUNDS -  if content specifier is not found within buffer 
 * 
 * Notes:
 *   Since we are checking the cursor position within a buffer, relativity is assumed.
 *     To check absolute position within a buffer, a NULL pointer can be passed in.
 *     In this case, offset will be checked from the start of the given buffer.
 *
 *   Currently support:
 *    options:
 *      offset
 *    buffers:
 *      normalized(alt-decode)
 *      raw
 *      uri
 *      
 */
ENGINE_LINKAGE int checkCursor(void *p, CursorInfo* cursorInfo, u_int8_t *cursor)
{
    return checkCursorInternal(p, cursorInfo->flags, cursorInfo->offset, cursor);
}
/*
 *  Content Option processing function
 *
 *       p: packet data structure, same as the one found in snort.
 * content: data defined in the detection plugin for this rule content option
 *  cursor: updated to point the 1st byte after the match
 *
 * Returns:
 *    > 0 : match found
 *    = 0 : no match found
 *    < 0 : error
 *
 * Predefined constants:
 *    (see sf_snort_plugin_api.h for more values)
 *    CONTENT_MATCH   -  if content specifier is found within buffer
 *    CONTENT_NOMATCH -  if content specifier is not found within buffer
 *
 * Notes:
 *   For multiple URI buffers, we scan each buffer, if any one of them
 *   contains the content we return a match. This is essentially an OR
 *   operation.
 *
 *   Currently support:
 *    options:
 *      nocase
 *      offset
 *      depth
 *    buffers:
 *      normalized(alt-decode)
 *      raw
 *      uri
 *      post
 *
 */
static int contentMatchInternal(void *p, ContentInfo* content, const uint8_t **cursor)
{
    const uint8_t * q = NULL;
    const uint8_t * buffer_start = NULL;
    const uint8_t * buffer_end = NULL;
    u_int  buffer_len;
    int    length;
    int    i;
    char   relative = 0;
    SFSnortPacket *sp = (SFSnortPacket *) p;

    /* This content is only used for fast pattern matching and
     * should not be evaluated */
    if (content->flags & CONTENT_FAST_PATTERN_ONLY)
        return CONTENT_MATCH;

    if (content->flags & CONTENT_RELATIVE)
    {
        if( !cursor || !(*cursor) )
        {
            return CONTENT_NOMATCH;
        }
        relative = 1;
    }

    /* Check for byte_extract variables and use them if present. */
    if (content->offset_location)
    {
        content->offset = *content->offset_location;
    }
    if (content->depth_location)
    {
        content->depth = *content->depth_location;
    }

    if (content->flags & URI_CONTENT_BUFS)
    {
        for (i=0; i<sp->num_uris; i++)
        {
            switch (i)
            {
                case HTTP_BUFFER_URI:
                    if (!(content->flags & CONTENT_BUF_URI))
                        continue; /* Go to next, not looking at URI buffer */
                    break;
                case HTTP_BUFFER_HEADER:
                    if (!(content->flags & CONTENT_BUF_HEADER))
                        continue; /* Go to next, not looking at HEADER buffer */
                    break;
                case HTTP_BUFFER_CLIENT_BODY:
                    if (!(content->flags & CONTENT_BUF_POST))
                        continue; /* Go to next, not looking at POST buffer */
                    break;
                case HTTP_BUFFER_METHOD:
                    if (!(content->flags & CONTENT_BUF_METHOD))
                        continue; /* Go to next, not looking at METHOD buffer */
                    break;
                case HTTP_BUFFER_COOKIE:
                    if (!(content->flags & CONTENT_BUF_COOKIE))
                        continue; /* Go to next, not looking at COOKIE buffer */
                    break;
                case HTTP_BUFFER_RAW_URI:
                    if (!(content->flags & CONTENT_BUF_RAW_URI))
                        continue; /* Go to next, not looking at RAW URI buffer */
                    break;
                case HTTP_BUFFER_RAW_HEADER:
                    if (!(content->flags & CONTENT_BUF_RAW_HEADER))
                        continue; /* Go to next, not looking at RAW HEADER buffer */
                    break;
                case HTTP_BUFFER_RAW_COOKIE:
                    if (!(content->flags & CONTENT_BUF_RAW_COOKIE))
                        continue; /* Go to next, not looking at RAW COOKIE buffer */
                    break;
                case HTTP_BUFFER_STAT_CODE:
                    if (!(content->flags & CONTENT_BUF_STAT_CODE))
                        continue; /* Go to next, not looking at STAT CODE buffer */
                    break;
                case HTTP_BUFFER_STAT_MSG:
                    if (!(content->flags & CONTENT_BUF_STAT_MSG))
                        continue; /* Go to next, not looking at STAT MSG buffer */
                    break;
                default:
                    /* Uh, what buffer is this? */
                    return CONTENT_NOMATCH;
            }

            if (!_ded.uriBuffers[i]->uriBuffer || (_ded.uriBuffers[i]->uriLength == 0))
                continue;

            if (relative)
            {
                if (checkCursorInternal(p, content->flags, content->offset, *cursor) <= 0)
                {
                    /* Okay, cursor is NOT within this buffer... */
                    continue;
                }
                buffer_start = *cursor + content->offset;
            }
            else
            {
                buffer_start = _ded.uriBuffers[i]->uriBuffer + content->offset;
            }

            buffer_end = _ded.uriBuffers[i]->uriBuffer + _ded.uriBuffers[i]->uriLength;

            length = buffer_len = buffer_end - buffer_start;

            if (length <= 0)
            {
                continue;
            }

            /* Don't bother looking deeper than depth */
            if ( content->depth != 0 && content->depth < buffer_len )
            {
                buffer_len = content->depth;
            }

            q = hbm_match((HBM_STRUCT*)content->boyer_ptr,buffer_start,buffer_len);

            if (q)
            {
                if (content->flags & CONTENT_END_BUFFER)
                {
                    _uri_buffer_end = q;
                }
                if (cursor)
                {
                    *cursor = q + content->patternByteFormLength;
                }
                return CONTENT_MATCH;
            }
        }

        return CONTENT_NOMATCH;
    }

    if (relative)
    {
        if (checkCursorInternal(p, content->flags, content->offset, *cursor) <= 0)
        {
            return CONTENT_NOMATCH;
        }

        if ((content->flags & CONTENT_BUF_NORMALIZED) && _ded.Is_DetectFlag(SF_FLAG_DETECT_ALL))
        {
            if(_ded.Is_DetectFlag(SF_FLAG_ALT_DETECT))
            {
                if (_alt_detect_end)
                {
                    buffer_end = _alt_detect_end;
                }
                else
                {
                    buffer_end = _ded.altDetect->data + _ded.altDetect->len;
                }
            }
            else if(_ded.Is_DetectFlag(SF_FLAG_ALT_DECODE))
            {
                if (_alt_buffer_end)
                {
                    buffer_end = _alt_buffer_end;
                }
                else
                {
                    buffer_end = _ded.altBuffer->data + _ded.altBuffer->len;
                }
            }
        }
        else
        {
            if(sp->normalized_payload_size)
            {
                buffer_end = sp->payload + sp->normalized_payload_size;
            }
            else if (_buffer_end)
            {
                buffer_end = _buffer_end;
            }
            else
            {
                buffer_end = sp->payload + sp->payload_size;
            }
        }
        buffer_start = *cursor + content->offset;
    }
    else
    {
        if ((content->flags & CONTENT_BUF_NORMALIZED) && _ded.Is_DetectFlag(SF_FLAG_DETECT_ALL))
        {
            if(_ded.Is_DetectFlag(SF_FLAG_ALT_DETECT))
            {
                buffer_start = _ded.altDetect->data + content->offset;
                if (_alt_detect_end)
                {
                    buffer_end = _alt_detect_end;
                }
                else
                {
                    buffer_end = _ded.altDetect->data + _ded.altDetect->len;
                }
            }
            else if(_ded.Is_DetectFlag(SF_FLAG_ALT_DECODE))
            {
                buffer_start = _ded.altBuffer->data + content->offset;
                if (_alt_buffer_end)
                {
                    buffer_end = _alt_buffer_end;
                }
                else
                {
                    buffer_end = _ded.altBuffer->data + _ded.altBuffer->len;
                }
            }
        }
        else
        {
            buffer_start = sp->payload + content->offset;
            if(sp->normalized_payload_size)
            {
                buffer_end = sp->payload + sp->normalized_payload_size;
            }
            else if (_buffer_end)
            {
                buffer_end = _buffer_end;
            }
            else
            {
                buffer_end = sp->payload + sp->payload_size;
            }
        }
    }
    length = buffer_len = buffer_end - buffer_start;

    if (length <= 0)
    {
        return CONTENT_NOMATCH;
    }

    /* Don't bother looking deeper than depth */
    if ( content->depth != 0 && content->depth < buffer_len )
    {
        buffer_len = content->depth;
    }

    q = hbm_match((HBM_STRUCT*)content->boyer_ptr,buffer_start,buffer_len);

    if (q)
    {
        if (content->flags & CONTENT_END_BUFFER)
        {
            if((content->flags & CONTENT_BUF_NORMALIZED) && _ded.Is_DetectFlag(SF_FLAG_ALT_DETECT))
            {
                _alt_detect_end = q;
            }
            else if ((content->flags & CONTENT_BUF_NORMALIZED) && _ded.Is_DetectFlag(SF_FLAG_ALT_DECODE))
            {
                _alt_buffer_end = q;
            }
            else
            {
                _buffer_end = q;
            }
        }
        if (cursor)
        {
            *cursor = q + content->patternByteFormLength;
        }
        return CONTENT_MATCH;
    }

    return CONTENT_NOMATCH;
}