示例#1
0
int SMTP_CopyToAltBuffer(SFSnortPacket *p, const uint8_t *start, int length)
{
    uint8_t *alt_buf;
    int alt_size;
    uint16_t *alt_len;
    int ret;

    /* if we make a call to this it means we want to use the alt buffer
     * regardless of whether we copy any data into it or not - barring a failure */
    smtp_normalizing = 1;

    /* if start and end the same, nothing to copy */
    if (length == 0)
        return 0;

    alt_buf = _dpd.altBuffer->data;
    alt_size = sizeof(_dpd.altBuffer->data);
    alt_len = &_dpd.altBuffer->len;

    ret = SafeMemcpy(alt_buf + *alt_len, start, length, alt_buf, alt_buf + alt_size);

    if (ret != SAFEMEM_SUCCESS)
    {
        _dpd.DetectFlag_Disable(SF_FLAG_ALT_DECODE);
        smtp_normalizing = 0;
        return -1;
    }
    *alt_len += length;

    _dpd.SetAltDecode(*alt_len);

    return 0;
}
示例#2
0
void HttpBase::Append(const void * context, const s32 size) {
	while (_content.GetFreeSpace() < size)
		_content.Expand();

	SafeMemcpy(_content.GetFree(), _content.GetFreeSpace(), context, size);
	_content.In(size);
}
示例#3
0
int SMTP_CopyToAltBuffer(SFSnortPacket *p, const uint8_t *start, int length)
{
    uint8_t *alt_buf;
    int alt_size;
    uint16_t *alt_len;
    int ret;

    /* if we make a call to this it means we want to use the alt buffer
     * regardless of whether we copy any data into it or not - barring a failure */
    p->flags |= FLAG_ALT_DECODE;
    smtp_normalizing = 1;

    /* if start and end the same, nothing to copy */
    if (length == 0)
        return 0;

    alt_buf = &_dpd.altBuffer[0];
    alt_size = _dpd.altBufferLen;
    alt_len = &p->normalized_payload_size;

    ret = SafeMemcpy(alt_buf + *alt_len, start, length, alt_buf, alt_buf + alt_size);

    if (ret != SAFEMEM_SUCCESS)
    {
        p->flags &= ~FLAG_ALT_DECODE;
        smtp_normalizing = 0;
        *alt_len = 0;

        return -1;
    }

    *alt_len += length;

    return 0;
}
/* accumulate MIME attachment filenames. The filenames are appended by commas */
int log_file_name(const uint8_t *start, int length, FILE_LogState *log_state, bool *disp_cont)
{
    uint8_t *alt_buf;
    int alt_size;
    uint16_t *alt_len;
    int ret=0;
    int cont =0;
    int log_avail = 0;


    if(!start || (length <= 0))
    {
        *disp_cont = false;
        return -1;
    }

    if(*disp_cont)
        cont = 1;

    ret = extract_file_name((const char **)(&start), length, disp_cont);

    if (ret == -1)
        return ret;

    length = ret;

    alt_buf = log_state->filenames;
    alt_size =  MAX_FILE;
    alt_len = &(log_state->file_logged);
    log_avail = alt_size - *alt_len;

    if(!alt_buf || (log_avail <= 0))
        return -1;


    if ( *alt_len > 0 && ((*alt_len + 1) < alt_size))
    {
        if(!cont)
        {
            alt_buf[*alt_len] = ',';
            *alt_len = *alt_len + 1;
        }
    }

    ret = SafeMemcpy(alt_buf + *alt_len, start, length, alt_buf, alt_buf + alt_size);

    if (ret != SAFEMEM_SUCCESS)
    {
        if(*alt_len != 0)
            *alt_len = *alt_len - 1;
        return -1;
    }

    log_state->file_current = *alt_len;
    *alt_len += length;

    return 0;
}
示例#5
0
void Redis::Append(CommandBuff& buf, const void * val, const s32 size) {
	SafeSprintf(buf.data + buf.size, sizeof(buf.data) - buf.size, "$%d\r\n", size);
	buf.size += (s32)strlen(buf.data + buf.size);

	SafeMemcpy(buf.data + buf.size, sizeof(buf.data) - buf.size, val, size);
	buf.size += size;
	SafeSprintf(buf.data + buf.size, sizeof(buf.data) - buf.size, "\r\n");
	buf.size += (s32)strlen(buf.data + buf.size);
}
示例#6
0
void Gate::BuildToken(char * token, s32 size, const TokenData& data) {
	char checkBuf[1024];
	SafeMemcpy(checkBuf, sizeof(checkBuf), &data, sizeof(TokenData));
	SafeSprintf(checkBuf + sizeof(TokenData), sizeof(checkBuf) - sizeof(TokenData), "%s", _tokenKey.GetString());

	MD5 md5;
	md5.update(checkBuf, sizeof(TokenData) + _tokenKey.Length());
	std::string sign = md5.toString();

	char buf[1024];
	SafeMemcpy(buf, sizeof(buf), &data, sizeof(TokenData));
	SafeSprintf(buf + sizeof(TokenData), sizeof(buf) - sizeof(TokenData), "%s", sign.c_str());

	u32 outSize = size;
	s32 ret = Base64Encode((u8*)buf, (u32)(sizeof(TokenData) + sign.size()), token, &outSize);
	OASSERT(ret == BASE64_OK, "wtf");
	token[outSize] = 0;
}
示例#7
0
文件: JList.cpp 项目: weiganyi/jphone
template<> inline JUINT32 JList<JPER_RECORD>::CopyObject(JList<JPER_RECORD>& rDst, 
                                                        JList<JPER_RECORD>& rSrc)

{
    JPER_RECORD* pDstData = JNULL;
    JListItem<JPER_RECORD>* pDstItem = JNULL;
    JUINT32 uiLen = 0;
    JPER_RECORD* pSrcData = JNULL;
    JListItem<JPER_RECORD>* pSrcItem = JNULL;
    JListItem<JPER_RECORD>* prevDstItem = JNULL;

    rDst.m_pHead = JNULL;
    rDst.m_pTail = JNULL;

    JLogAutoPtr clsLogAutoPtr(JSingleton<JLog>::instance(), 
        JLOG_MOD_LIST, "JList::CopyObject");

    JListIterator<JPER_RECORD> clsListIter(rSrc);
    for (clsListIter.First(); clsListIter.Done(); clsListIter.Next())
    {
        pSrcItem = clsListIter.Item();

        pDstData = JNULL;

        pSrcData = pSrcItem->GetData();
        uiLen = pSrcItem->GetDataLength();
        if (uiLen)
        {
            //alloc memory for the dst data
            pDstData = 
                reinterpret_cast<JPER_RECORD*>(JSingleton<JStaticMemory>::instance()->Alloc(uiLen+1));
            if (pDstData)
            {
	            SafeMemset(reinterpret_cast<JCHAR*>(pDstData), 0, uiLen+1);
                SafeMemcpy(reinterpret_cast<JCHAR*>(pDstData), 
                    reinterpret_cast<JCHAR*>(pSrcData), uiLen, uiLen+1);
            }
            else
            {
                JSingleton<JLog>::instance2() << set(JLOG_MOD_LIST, JLOG_ERROR_LEVEL)
                    << "JList::CopyObject memory alloc failure\n";
                return JFAILURE;
            }
        }

        //construct the dst item
        pDstItem = new JListItem<JPER_RECORD>(pDstData);
        pDstItem->SetDataLength(uiLen);
        rDst.InsertItem(pDstItem, prevDstItem);

        prevDstItem = pDstItem;
    }

    return JSUCCESS;
}
示例#8
0
/*
 * Normalize current line in buffer.  Walk buffer, consolidating whitespace into
 *   alternate buffer, then return number of bytes walked in packet data buffer.
 *
 * @param   p           standard Packet structure
 * @param   offset      offset into p->data to data of interest
 * @param   cmd_len     length of command on this line
 *
 * @return  length
 * @retval  integer     length of line
 */
int SMTP_Normalize(SFSnortPacket *p, int offset, int cmd_len)
{
    int   i = 0;
    int   datalen;
    char *data;
    int   past_spaces = 0;
    int   first_space = 1;
    char *startBuffer = &_dpd.altBuffer[0];
    char *endBuffer = startBuffer + _dpd.altBufferLen;
    int ret;

    data = p->payload + offset;
    datalen = p->payload_size - offset;

    //memcpy(_dpd.altBuffer + p->normalized_payload_size, data, cmd_len);
    ret = SafeMemcpy(startBuffer + p->normalized_payload_size, data, cmd_len,
                     startBuffer, endBuffer);

    //if (ret == SAFEMEM_ERROR)
    //{
    //    DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "SMTP_Normalize() => SafeMemcpy failed\n"););
    //    return -1;
    //}

    data += cmd_len;
    i += cmd_len;
    p->normalized_payload_size += cmd_len;

    for ( ; i < datalen && *data != '\n' && p->normalized_payload_size < _dpd.altBufferLen; i++, data++ )
    {
        if ( !past_spaces && i > cmd_len && !isspace((int)*data) )
        {
            past_spaces = 1;
        }
        
        if ( first_space || past_spaces )
        {
            if (isspace((int)*data))
                *(_dpd.altBuffer + p->normalized_payload_size) = ' ';
            else
                *(_dpd.altBuffer + p->normalized_payload_size) = *data;

            p->normalized_payload_size++;
            first_space = 0;
        }
    }    

    return i;
}
示例#9
0
/* accumulate MIME attachment filenames. The filenames are appended by commas */
int SMTP_CopyFileName(const uint8_t *start, int length)
{
    uint8_t *alt_buf;
    int alt_size;
    uint16_t *alt_len;
    int ret=0;
    int cont =0;


    if(length == 0)
        return -1;

    if(smtp_ssn->state_flags & SMTP_FLAG_IN_CONT_DISP_CONT)
        cont = 1;

    ret = SMTP_ExtractFileName((const char **)(&start), length );

    if (ret == -1)
        return ret;

    length = ret;

    alt_buf = smtp_ssn->filenames.data;
    alt_size = sizeof(smtp_ssn->filenames.data);
    alt_len = &(smtp_ssn->filenames.len);

    if ( *alt_len > 0 && ((*alt_len + 1) < alt_size))
    {
        if(!cont)
        {
            alt_buf[*alt_len] = ',';
            *alt_len = *alt_len + 1;
        }
    }

    ret = SafeMemcpy(alt_buf + *alt_len, start, length, alt_buf, alt_buf + alt_size);

    if (ret != SAFEMEM_SUCCESS)
    {
        if(*alt_len != 0)
            *alt_len = *alt_len - 1;
        return -1;
    }

    *alt_len += length;
    smtp_ssn->log_flags |= SMTP_FLAG_FILENAME_PRESENT;

    return 0;
}
示例#10
0
static KTRIEPATTERN * KTrieNewPattern(unsigned char * P, int n)
{
   KTRIEPATTERN *p;
   int ret;

   if (n < 1)
       return NULL;

   p = (KTRIEPATTERN*) KTRIE_MALLOC( sizeof(KTRIEPATTERN) );

   if (p == NULL)
       return NULL;

   /* Save as a nocase string */
   p->P = (unsigned char*) KTRIE_MALLOC( n );
   if( !p->P )
   {
       KTRIE_FREE(p);
       return NULL;
   }

   ConvertCaseEx( p->P, P, n );

   /* Save Case specific version */
   p->Pcase = (unsigned char*) KTRIE_MALLOC( n );
   if( !p->Pcase )
   {
       KTRIE_FREE(p->P);
       KTRIE_FREE(p);
       return NULL;
   }

   ret = SafeMemcpy(p->Pcase, P, n, p->Pcase, p->Pcase + n);
   if (ret != SAFEMEM_SUCCESS)
   {
       KTRIE_FREE(p->Pcase);
       KTRIE_FREE(p->P);
       KTRIE_FREE(p);
       return NULL;
   }

   p->n    = n;
   p->next = NULL;

   return p;
}
示例#11
0
bool Gate::CheckToken(const char * token, TokenData& data, bool login) {
	u8 buf[1024];
	u32 size = 1023;
	if (BASE64_OK != Base64Decode(token, (u32)strlen(token), buf, &size))
		return false;
	buf[size] = 0;

	data = *(TokenData*)buf;
	const char * sign = (const char *)(buf + sizeof(TokenData));

	char checkBuf[1024];
	SafeMemcpy(checkBuf, sizeof(checkBuf), buf, sizeof(TokenData));
	SafeSprintf(checkBuf + sizeof(TokenData), sizeof(checkBuf) - sizeof(TokenData), "%s", login ? _loginKey.GetString() : _tokenKey.GetString());
	MD5 md5;
	md5.update(checkBuf, sizeof(TokenData) + login ? _loginKey.Length() : _tokenKey.Length());
	if (strcmp(md5.toString().c_str(), sign) != 0)
		return false;

	return true;
}
示例#12
0
/* Accumulate EOL seperated headers, one or more at a time */
int SMTP_CopyEmailHdrs(const uint8_t *start, int length)
{
    int log_avail = 0;
    uint8_t *log_buf;
    uint32_t *hdrs_logged;
    int ret = 0;

    if ((smtp_ssn->log_state == NULL) || (length <= 0))
        return -1;

    
    log_avail = (smtp_ssn->log_state->log_depth - smtp_ssn->log_state->hdrs_logged);
    hdrs_logged = &(smtp_ssn->log_state->hdrs_logged);
    log_buf = (uint8_t *)smtp_ssn->log_state->emailHdrs;

    if(log_avail <= 0)
    {
        return -1;
    }

    if(length > log_avail )
    {
        length = log_avail;
    }

    /* appended by the EOL \r\n */

    ret = SafeMemcpy(log_buf + *hdrs_logged, start, length, log_buf, log_buf+(smtp_ssn->log_state->log_depth));

    if (ret != SAFEMEM_SUCCESS)
    {
        return -1;
    }

    *hdrs_logged += length;
    smtp_ssn->log_flags |= SMTP_FLAG_EMAIL_HDRS_PRESENT;

    return 0;
}
示例#13
0
/* Accumulate EOL seperated headers, one or more at a time */
int SMTP_CopyEmailHdrs(const uint8_t *start, int length, MAIL_LogState *log_state)
{
    int log_avail = 0;
    uint8_t *log_buf;
    uint32_t *hdrs_logged;
    int ret = 0;

    if ((log_state == NULL) || (length <= 0))
        return -1;


    log_avail = (log_state->log_depth - log_state->hdrs_logged);
    hdrs_logged = &(log_state->hdrs_logged);
    log_buf = (uint8_t *)log_state->emailHdrs;

    if(log_avail <= 0)
    {
        return -1;
    }

    if(length > log_avail )
    {
        length = log_avail;
    }

    /* appended by the EOL \r\n */

    ret = SafeMemcpy(log_buf + *hdrs_logged, start, length, log_buf, log_buf+(log_state->log_depth));

    if (ret != SAFEMEM_SUCCESS)
    {
        return -1;
    }

    *hdrs_logged += length;

    return 0;
}
示例#14
0
static int AddCmd(char *name)
{
    static int num_cmds = CMD_LAST + 1;
    static int id = CMD_LAST;
    SMTPToken *cmds, *tmp_cmds;
    SMTPSearch *cmd_search;
    SMTPCmdConfig *cmd_config;
    int ret;

    /* allocate enough memory for new commmand - alloc one extra for NULL entry */
    cmds = (SMTPToken *)calloc(num_cmds + 1, sizeof(SMTPToken));
    if (cmds == NULL)
    {
        DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP "
                                        "command structure\n", 
                                        *(_dpd.config_file), *(_dpd.config_line));
    }

    cmd_search = (SMTPSearch *)calloc(num_cmds, sizeof(SMTPSearch));
    if (cmd_search == NULL)
    {
        DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP "
                                        "command structure\n", 
                                        *(_dpd.config_file), *(_dpd.config_line));
    }

    cmd_config = (SMTPCmdConfig *)calloc(num_cmds, sizeof(SMTPCmdConfig));
    if (cmd_config == NULL)
    {
        DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP "
                                        "command structure\n", 
                                        *(_dpd.config_file), *(_dpd.config_line));
    }


    /* copy existing commands into newly allocated memory
     * don't need to copy anything from cmd_search since this hasn't been initialized yet */
    ret = SafeMemcpy(cmds, _smtp_cmds, id * sizeof(SMTPToken), cmds, cmds + num_cmds);
    if (ret != SAFEMEM_SUCCESS)
    {
        DynamicPreprocessorFatalMessage("%s(%d) => Failed to memory copy SMTP command structure\n", 
                                        *(_dpd.config_file), *(_dpd.config_line));
    }

    ret = SafeMemcpy(cmd_config, _smtp_cmd_config, id * sizeof(SMTPCmdConfig), cmd_config, cmd_config + num_cmds);
    if (ret != SAFEMEM_SUCCESS)
    {
        DynamicPreprocessorFatalMessage("%s(%d) => Failed to memory copy SMTP command structure\n", 
                                        *(_dpd.config_file), *(_dpd.config_line));
    }


    /* add new command to cmds
     * cmd_config doesn't need anything added - this will probably be done by a calling function
     * cmd_search will be initialized when the searches are initialized */
    tmp_cmds = &cmds[id];
    tmp_cmds->name = strdup(name);
    tmp_cmds->name_len = strlen(name);
    tmp_cmds->search_id = id;

    if (tmp_cmds->name == NULL)
    {
        DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP "
                                        "command structure\n", 
                                        *(_dpd.config_file), *(_dpd.config_line));
    }


    /* free global memory structures */
    if (_smtp_cmds != NULL)
        free(_smtp_cmds);
    if (_smtp_cmd_search != NULL)
        free(_smtp_cmd_search);
    if (_smtp_cmd_config != NULL)
        free(_smtp_cmd_config);


    /* set globals to new memory */
    _smtp_cmds = cmds;
    _smtp_cmd_search = cmd_search;
    _smtp_cmd_config = cmd_config;

    ret = id;

    id++;
    num_cmds++;

    return ret;
}
示例#15
0
static int AddCmd(SMTPConfig *config, char *name)
{
    SMTPToken *cmds, *tmp_cmds;
    SMTPSearch *cmd_search;
    SMTPCmdConfig *cmd_config;
    int ret;

    if (config == NULL)
    {
        DynamicPreprocessorFatalMessage("%s(%d) SMTP config is NULL.\n",
                                        __FILE__, __LINE__);
    }

    config->num_cmds++;

    /* allocate enough memory for new commmand - alloc one extra for NULL entry */
    cmds = (SMTPToken *)calloc(config->num_cmds + 1, sizeof(SMTPToken));
    if (cmds == NULL)
    {
        DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP "
                                        "command structure\n",
                                        *(_dpd.config_file), *(_dpd.config_line));
    }

    /* This gets filled in later */
    cmd_search = (SMTPSearch *)calloc(config->num_cmds, sizeof(SMTPSearch));
    if (cmd_search == NULL)
    {
        DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP "
                                        "command structure\n",
                                        *(_dpd.config_file), *(_dpd.config_line));
    }

    cmd_config = (SMTPCmdConfig *)calloc(config->num_cmds, sizeof(SMTPCmdConfig));
    if (cmd_config == NULL)
    {
        DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP "
                                        "command structure\n",
                                        *(_dpd.config_file), *(_dpd.config_line));
    }

    /* copy existing commands into newly allocated memory
     * don't need to copy anything from cmd_search since this hasn't been initialized yet */
    ret = SafeMemcpy(cmds, config->cmds, (config->num_cmds - 1) * sizeof(SMTPToken),
                     cmds, cmds + (config->num_cmds - 1));

    if (ret != SAFEMEM_SUCCESS)
    {
        DynamicPreprocessorFatalMessage("%s(%d) => Failed to memory copy SMTP command structure\n",
                                        *(_dpd.config_file), *(_dpd.config_line));
    }

    ret = SafeMemcpy(cmd_config, config->cmd_config, (config->num_cmds - 1) * sizeof(SMTPCmdConfig),
                     cmd_config, cmd_config + (config->num_cmds - 1));

    if (ret != SAFEMEM_SUCCESS)
    {
        DynamicPreprocessorFatalMessage("%s(%d) => Failed to memory copy SMTP command structure\n",
                                        *(_dpd.config_file), *(_dpd.config_line));
    }

    /* add new command to cmds
     * cmd_config doesn't need anything added - this will probably be done by a calling function
     * cmd_search will be initialized when the searches are initialized */
    tmp_cmds = &cmds[config->num_cmds - 1];
    tmp_cmds->name = strdup(name);
    tmp_cmds->name_len = strlen(name);
    tmp_cmds->search_id = config->num_cmds - 1;

    if (tmp_cmds->name == NULL)
    {
        DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP "
                                        "command structure\n",
                                        *(_dpd.config_file), *(_dpd.config_line));
    }

    /* free global memory structures */
    if (config->cmds != NULL)
        free(config->cmds);

    if (config->cmd_search != NULL)
        free(config->cmd_search);

    if (config->cmd_config != NULL)
        free(config->cmd_config);

    /* set globals to new memory */
    config->cmds = cmds;
    config->cmd_search = cmd_search;
    config->cmd_config = cmd_config;

    return (config->num_cmds - 1);
}
示例#16
0
int HttpResponseInspection(HI_SESSION *Session, Packet *p, const unsigned char *data,
        int dsize, HttpSessionData *sd)
{
    HTTPINSPECT_CONF *ServerConf;
    URI_PTR stat_code_ptr;
    URI_PTR stat_msg_ptr;
    HEADER_PTR header_ptr;
    URI_PTR body_ptr;
    HI_SERVER *Server;

    const u_char *start;
    const u_char *end;
    const u_char *ptr;
    int len;
    int iRet = 0;
    int resp_header_size = 0;
    /* Refers to the stream reassembled packets when reassembly is turned on.
     * Refers to all packets when reassembly is turned off.
     */
    int not_stream_insert = 1;
#ifdef ZLIB
    int parse_cont_encoding = 1;
    int status;
#endif
    int expected_pkt = 0;
    int alt_dsize;
    uint32_t seq_num = 0;

    if (!Session || !p || !data || (dsize == 0))
        return HI_INVALID_ARG;

    ServerConf = Session->server_conf;
    if(!ServerConf)
        return HI_INVALID_ARG;


    Server = &(Session->server);
    clearHttpRespBuffer(Server);

    seq_num = GET_PKT_SEQ(p);

    if ( (sd != NULL) )
    {
        /* If the previously inspected packet in this session identified as a body
         * and if the packets are stream inserted wait for reassembled */
        if (sd->resp_state.inspect_reassembled)
        {
            if(p->packet_flags & PKT_STREAM_INSERT)
            {
#ifdef ZLIB
                parse_cont_encoding = 0;
#endif
                not_stream_insert = 0;
            }
        }
        /* If this packet is the next expected packet to be inspected and is out of sequence
         * clear out the resp state*/
#ifdef ZLIB
        if(( sd->decomp_state && sd->decomp_state->decompress_data) && parse_cont_encoding)
        {
            if( sd->resp_state.next_seq &&
                    (seq_num == sd->resp_state.next_seq) )
            {
                sd->resp_state.next_seq = seq_num + p->dsize;
                expected_pkt = 1;
            }
            else
            {
                ResetGzipState(sd->decomp_state);
                ResetRespState(&(sd->resp_state));
            }
        }
        else
#endif
        if(sd->resp_state.inspect_body && not_stream_insert)
        {
            /* If the server flow depth is 0 then we need to check if the packet
             * is in sequence
             */
            if(!ServerConf->server_flow_depth)
            {
                if( sd->resp_state.next_seq &&
                        (seq_num == sd->resp_state.next_seq) )
                {
                    sd->resp_state.next_seq = seq_num + p->dsize;
                    expected_pkt = 1;
                }
                else
                {
#ifdef ZLIB
                    ResetGzipState(sd->decomp_state);
#endif
                    ResetRespState(&(sd->resp_state));
                }
            }
            else 
            {
                /*Check if the sequence number of the packet is within the allowed
                 * flow_depth
                 */
                if( (sd->resp_state.is_max_seq) && 
                        SEQ_LT(seq_num, (sd->resp_state.max_seq)))
                {
                    expected_pkt = 1;
                }
                else
                {
#ifdef ZLIB
                    ResetGzipState(sd->decomp_state);
#endif
                    ResetRespState(&(sd->resp_state));
                }
            }

        }
    }


    memset(&stat_code_ptr, 0x00, sizeof(URI_PTR));
    memset(&stat_msg_ptr, 0x00, sizeof(URI_PTR));
    memset(&header_ptr, 0x00, sizeof(HEADER_PTR));
    memset(&body_ptr, 0x00, sizeof(URI_PTR));

    start = data;
    end = data + dsize;
    ptr = start;

    /* moving past the CRLF */

    while(hi_util_in_bounds(start, end, ptr))
    {
        if(*ptr < 0x21)
        {
            if(*ptr < 0x0E && *ptr > 0x08)
            {
                ptr++;
                continue;
            }
            else
            {
                if(*ptr == 0x20)
                {
                    ptr++;
                    continue;
                }
            }
        }

        break;
    }

    /*after doing this we need to basically check for version, status code and status message*/

    len = end - ptr;
    if ( len > 4 )
    {
        if(!IsHttpVersion(&ptr, end))
        { 
            if(expected_pkt)
            {
                ptr = start;
                p->packet_flags |= PKT_HTTP_DECODE;
            }
            else
            {
                p->packet_flags |= PKT_HTTP_DECODE;
                ApplyFlowDepth(ServerConf, p, sd, resp_header_size, 0, seq_num);
                if ( not_stream_insert && (sd != NULL))
                {
#ifdef ZLIB
                    ResetGzipState(sd->decomp_state);
#endif
                    ResetRespState(&(sd->resp_state));
                }
                CLR_SERVER_HEADER(Server);
                return HI_SUCCESS;
            }
        }
        else
        {
            p->packet_flags |= PKT_HTTP_DECODE;
            /* This is a next expected packet to be decompressed but the packet is a
             * valid HTTP response. So the gzip decompression ends here */
            if(expected_pkt)
            {
                expected_pkt = 0;
#ifdef ZLIB
                ResetGzipState(sd->decomp_state);
#endif
                ResetRespState(&(sd->resp_state));
            }
            while(hi_util_in_bounds(start, end, ptr))
            {
                if (isspace((int)*ptr))
                    break;
                ptr++;
            }

        }
    }
    else if (!expected_pkt)
    {
        return HI_SUCCESS;
    }

    /*If this is the next expected packet to be decompressed, send this packet 
     * decompression */

    if (expected_pkt)
    {
        if (hi_util_in_bounds(start, end, ptr))
        {
            iRet = hi_server_inspect_body(Session, sd, ptr, end, &body_ptr);
        }
    }
    else
    {
        iRet = hi_server_extract_status_code(Session, start,ptr,end , &stat_code_ptr);

        if ( iRet == STAT_END )
        {
            Server->response.status_code = stat_code_ptr.uri;
            Server->response.status_code_size = stat_code_ptr.uri_end - stat_code_ptr.uri;
            if ( (int)Server->response.status_code_size <= 0)
            {
                CLR_SERVER_STAT(Server);
            }
            else
            {
                iRet = hi_server_extract_status_msg(start, stat_code_ptr.uri_end , 
                        end, &stat_msg_ptr);
    
                if ( stat_msg_ptr.uri )
                {
                    Server->response.status_msg = stat_msg_ptr.uri;
                    Server->response.status_msg_size = stat_msg_ptr.uri_end - stat_msg_ptr.uri;
                    if ((int)Server->response.status_msg_size <= 0)
                    {
                        CLR_SERVER_STAT(Server);
                    }
                    else
                    {
#ifdef ZLIB
                        ptr =  hi_server_extract_header(Session, ServerConf, &header_ptr,
                                            stat_msg_ptr.uri_end , end, parse_cont_encoding, sd );
#else
                        /* We dont need the content-encoding header when zlib is not enabled */
                        ptr =  hi_server_extract_header(Session, ServerConf, &header_ptr,
                                    stat_msg_ptr.uri_end , end, 0, sd );
#endif
                    }
                }
                else
                {
                    CLR_SERVER_STAT(Server);
                }
            }
     
            if (header_ptr.header.uri)
            {
                Server->response.header_raw = header_ptr.header.uri;
                Server->response.header_raw_size = 
                    header_ptr.header.uri_end - header_ptr.header.uri;
                if(!Server->response.header_raw_size)
                {
                    CLR_SERVER_HEADER(Server);
                }
                else
                {
                    resp_header_size = (header_ptr.header.uri_end - p->data);
                    hi_stats.resp_headers++;
                    Server->response.header_norm = header_ptr.header.uri;
                    if (header_ptr.cookie.cookie)
                    {
                        hi_stats.resp_cookies++;
                        Server->response.cookie.cookie = header_ptr.cookie.cookie;
                        Server->response.cookie.cookie_end = header_ptr.cookie.cookie_end;
                        Server->response.cookie.next = header_ptr.cookie.next;
                    }
                    else
                    {
                        Server->response.cookie.cookie = NULL;
                        Server->response.cookie.cookie_end = NULL;
                        Server->response.cookie.next = NULL;
                    }
                    if (sd != NULL)
                    {
#ifdef ZLIB
                        if( header_ptr.content_encoding.compress_fmt )
                        {
                            hi_stats.gzip_pkts++;

                            /* We've got gzip data - grab buffer from mempool and attach
                             * to session data if server is configured to do so */
                            if (sd->decomp_state == NULL)
                                SetGzipBuffers(sd, Session);

                            if (sd->decomp_state != NULL)
                            {
                                sd->decomp_state->decompress_data = 1;
                                sd->decomp_state->compress_fmt =
                                                            header_ptr.content_encoding.compress_fmt;
                            }

                        }
                        else
#endif
                        {
                            sd->resp_state.inspect_body = 1;
                        }

                        sd->resp_state.last_pkt_contlen = header_ptr.content_len.len;
                        if(ServerConf->server_flow_depth == -1)
                            sd->resp_state.is_max_seq = 0;
                        else
                        {
                            sd->resp_state.is_max_seq = 1;
                            sd->resp_state.max_seq = seq_num +
                                        (header_ptr.header.uri_end - start)+ ServerConf->server_flow_depth;
                        }

                        if (p->packet_flags & PKT_STREAM_INSERT)
                        {
                            if(header_ptr.content_len.cont_len_start && ((end - (header_ptr.header.uri_end)) >= header_ptr.content_len.len))
                            {
                                /* change this when the api is fixed to flush correctly */
                                //stream_api->response_flush_stream(p);
                                expected_pkt = 1;
                            }
                            else
                                sd->resp_state.inspect_reassembled = 1;

                        }
                        else
                        {
                            if(p->packet_flags & PKT_REBUILT_STREAM)
                                sd->resp_state.inspect_reassembled = 1;

                            expected_pkt = 1;
                        }
                        if(expected_pkt)
                        {
                            sd->resp_state.next_seq = seq_num + p->dsize;

                            if(hi_util_in_bounds(start, end, header_ptr.header.uri_end))
                            {
                                iRet = hi_server_inspect_body(Session, sd, header_ptr.header.uri_end,
                                                                end, &body_ptr);
                            }
                        }
                    }
                }
            }
            else
            {
                CLR_SERVER_HEADER(Server);

            }
        }
        else
        {
            CLR_SERVER_STAT(Server);
        }
    }

    if( body_ptr.uri )
    {
        Server->response.body = body_ptr.uri;
        Server->response.body_size = body_ptr.uri_end - body_ptr.uri;
        if( Server->response.body_size > 0)
        {
            if ( Server->response.body_size < sizeof(DecodeBuffer.data) )
            {
                alt_dsize = Server->response.body_size;
            }
            else
            {
                alt_dsize = sizeof(DecodeBuffer.data);
            }
#ifdef ZLIB
            if(sd->decomp_state && sd->decomp_state->decompress_data)
            {
                status = SafeMemcpy(DecodeBuffer.data, Server->response.body,
                                            alt_dsize, DecodeBuffer.data, DecodeBuffer.data + sizeof(DecodeBuffer.data));
                if( status != SAFEMEM_SUCCESS  )
                    return HI_MEM_ALLOC_FAIL;
                p->data_flags |= DATA_FLAGS_GZIP;
                SetAltDecode(p, alt_dsize);
                SetDetectLimit(p, alt_dsize);
            }
            else
#endif
            {
                if(sd->resp_state.last_pkt_chunked)
                {
                    p->data_flags |= DATA_FLAGS_RESP_BODY;
                    SetAltDecode(p, alt_dsize);
                    SetDetectLimit(p, alt_dsize);
                }
                else
                {
                    p->data_flags |= DATA_FLAGS_RESP_BODY;
                    p->packet_flags |= PKT_HTTP_RESP_BODY;
                    SetDetectLimit(p, (alt_dsize + resp_header_size));
                }
            }

            if (get_decode_utf_state_charset(&(sd->utf_state)) != CHARSET_DEFAULT)
            {
                if ( Server->response.body_size < sizeof(DecodeBuffer.data) )
                {
                    alt_dsize = Server->response.body_size;
                }           
                else
                {
                    alt_dsize = sizeof(DecodeBuffer.data);
                }
                SetDetectLimit(p, alt_dsize);
                SetAltDecode(p, alt_dsize);
            }
        }
        
    }
    else
    {
        /* There is no body to the HTTP response.
         * In this case we need to inspect the entire HTTP response header.
         */
        ApplyFlowDepth(ServerConf, p, sd, resp_header_size, 1, seq_num);
    }

    return HI_SUCCESS;
}
/* DNP3 Transport-Layer reassembly state machine.

   Arguments:
     rdata:     DNP3 reassembly state object.
     buf:       DNP3 Transport Layer segment
     buflen:    Length of Transport Layer segment.

   Returns:
    DNP3_FAIL:     Segment was discarded.
    DNP3_OK:       Segment was queued.
*/
static int DNP3ReassembleTransport(dnp3_reassembly_data_t *rdata, char *buf, uint16_t buflen)
{
    dnp3_transport_header_t *trans_header;

    if (rdata == NULL || buf == NULL || buflen < sizeof(dnp3_transport_header_t) ||
        (buflen > DNP3_MAX_TRANSPORT_LEN))
    {
        return DNP3_FAIL;
    }

    /* Take the first byte as a transport header, cut it off of the buffer. */
    trans_header = (dnp3_transport_header_t *)buf;
    buf += sizeof(dnp3_transport_header_t);
    buflen -= sizeof(dnp3_transport_header_t);


    /* If the previously-existing state was DONE, we need to reset it back
       to IDLE. */
    if (rdata->state == DNP3_REASSEMBLY_STATE__DONE)
        DNP3ReassemblyReset(rdata);

    switch (rdata->state)
    {
        case DNP3_REASSEMBLY_STATE__IDLE:
            /* Discard any non-first segment. */
            if ( DNP3_TRANSPORT_FIR(trans_header->control) == 0 )
                return DNP3_FAIL;

            /* Reset the buffer & queue the first segment */
            DNP3ReassemblyReset(rdata);
            DNP3QueueSegment(rdata, buf, buflen);
            rdata->last_seq = DNP3_TRANSPORT_SEQ(trans_header->control);

            if ( DNP3_TRANSPORT_FIN(trans_header->control) )
                rdata->state = DNP3_REASSEMBLY_STATE__DONE;
            else
                rdata->state = DNP3_REASSEMBLY_STATE__ASSEMBLY;
            
            break;

        case DNP3_REASSEMBLY_STATE__ASSEMBLY:
            /* Reset if the FIR flag is set. */
            if ( DNP3_TRANSPORT_FIR(trans_header->control) )
            {
                DNP3ReassemblyReset(rdata);
                DNP3QueueSegment(rdata, buf, buflen);
                rdata->last_seq = DNP3_TRANSPORT_SEQ(trans_header->control);

                if (DNP3_TRANSPORT_FIN(trans_header->control))
                    rdata->state = DNP3_REASSEMBLY_STATE__DONE;

                /* Raise an alert so it's clear the buffer was reset.
                   Could signify device trouble. */
                _dpd.alertAdd(GENERATOR_SPP_DNP3, DNP3_REASSEMBLY_BUFFER_CLEARED,
                                1, 0, 3, DNP3_REASSEMBLY_BUFFER_CLEARED_STR, 0);
            }
            else
            {
                /* Same seq but FIN is set. Discard segment, BUT finish reassembly. */
                if ((DNP3_TRANSPORT_SEQ(trans_header->control) == rdata->last_seq) &&
                    (DNP3_TRANSPORT_FIN(trans_header->control)))
                {
                    _dpd.alertAdd(GENERATOR_SPP_DNP3, DNP3_DROPPED_SEGMENT,
                                    1, 0, 3, DNP3_DROPPED_SEGMENT_STR, 0);
                    rdata->state = DNP3_REASSEMBLY_STATE__DONE;
                    return DNP3_FAIL;
                }

                /* Discard any other segments without the correct sequence. */
                if (DNP3_TRANSPORT_SEQ(trans_header->control) !=
                    ((rdata->last_seq + 1) % 0x40 ))
                {
                    _dpd.alertAdd(GENERATOR_SPP_DNP3, DNP3_DROPPED_SEGMENT,
                                    1, 0, 3, DNP3_DROPPED_SEGMENT_STR, 0);
                    return DNP3_FAIL;
                }

                /* Otherwise, queue it up! */
                DNP3QueueSegment(rdata, buf, buflen);
                rdata->last_seq = DNP3_TRANSPORT_SEQ(trans_header->control);

                if (DNP3_TRANSPORT_FIN(trans_header->control))
                    rdata->state = DNP3_REASSEMBLY_STATE__DONE;
                else
                    rdata->state = DNP3_REASSEMBLY_STATE__ASSEMBLY;
            }
            
            break;

        case DNP3_REASSEMBLY_STATE__DONE:
            break;
    }

    /* Set the Alt Decode buffer. This must be done during preprocessing
       in order to stop the Fast Pattern matcher from using raw packet data
       to evaluate the longest content in a rule. */
    if (rdata->state == DNP3_REASSEMBLY_STATE__DONE)
    {
        uint8_t *alt_buf = _dpd.altBuffer->data;
        uint16_t alt_len = sizeof(_dpd.altBuffer->data);
        int ret;

        ret = SafeMemcpy((void *)alt_buf,
                         (const void *)rdata->buffer,
                         (size_t)rdata->buflen,
                         (const void *)alt_buf,
                         (const void *)(alt_buf + alt_len));

        if (ret == SAFEMEM_SUCCESS)
            _dpd.SetAltDecode(alt_len);
    }

    return DNP3_OK;
}
示例#18
0
/* Accumulate email addresses from RCPT TO and/or MAIL FROM commands. Email addresses are separated by comma */
int SMTP_CopyEmailID(const uint8_t *start, int length, int command_type)
{
    uint8_t *alt_buf;
    int alt_size;
    uint16_t *alt_len;
    int ret;
    const uint8_t *tmp_eol;

    if (length <= 0)
        return -1;

    tmp_eol = (uint8_t *)memchr(start, ':', length);
    if(tmp_eol == NULL)
        return -1;

    if((tmp_eol+1) < (start+length))
    {
        length = length - ( (tmp_eol+1) - start );
        start = tmp_eol+1;
    }
    else
        return -1;


   
    switch (command_type)
    {
        case CMD_MAIL:
            alt_buf = smtp_ssn->senders.data;
            alt_size = sizeof(smtp_ssn->senders.data);
            alt_len = &(smtp_ssn->senders.len);
            break;

        case CMD_RCPT:
            alt_buf = smtp_ssn->recipients.data;
            alt_size = sizeof(smtp_ssn->recipients.data);
            alt_len = &(smtp_ssn->recipients.len);
            break;

        default:
            return -1;
    }

    if ( *alt_len > 0 && ((*alt_len + 1) < alt_size))
    {
        alt_buf[*alt_len] = ',';
        *alt_len = *alt_len + 1;
    }

    ret = SafeMemcpy(alt_buf + *alt_len, start, length, alt_buf, alt_buf + alt_size);

    if (ret != SAFEMEM_SUCCESS)
    {
        if(*alt_len != 0)
                *alt_len = *alt_len - 1;
        return -1;
    }

    *alt_len += length;

    return 0;
}
示例#19
0
void *DCERPC_FragAlloc(void *p, u_int16_t old_size, u_int16_t *new_size)
{
    u_int16_t add_size;
    void *new_buf = NULL;

    if (old_size >= *new_size)
    {
        *new_size = old_size;
        return p;
    }

    add_size = *new_size - old_size;

    if ( (((u_int32_t) add_size) + _total_memory) > _memcap )
    {
        /* Raise alert */
        if ( _alert_memcap )
        {
            DCERPC_GenerateAlert(DCERPC_EVENT_MEMORY_OVERFLOW, 
                                    DCERPC_EVENT_MEMORY_OVERFLOW_STR);
        }
        add_size = (u_int16_t) (_memcap - _total_memory);
    }

    *new_size = old_size + add_size;

    if (*new_size == old_size)
        return p;

    new_buf = calloc(*new_size, 1);

    if (new_buf == NULL)
    {
        if (p != NULL)
        {
            DCERPC_FragFree(p, old_size);
        }

        return NULL;
    }

    if (p != NULL)
    {
        int ret;

        ret = SafeMemcpy(new_buf, p, old_size, new_buf, (u_int8_t *)new_buf + *new_size);

        if (ret == 0)
        {
            *new_size = old_size;
            free(new_buf);
            return p;
        }

        DCERPC_FragFree(p, old_size);
    }

    /* DCERPC_FragFree will decrement old_size from _total_memory so
     * we add the *new_size */
    _total_memory += *new_size;

    return new_buf;
}
示例#20
0
文件: obfuscation.c 项目: eqmcc/snort
/*******************************************************************************
 * Function: GetObfuscationPayloadCallback()
 *
 * ObfuscationCallback for returning an allocated obfuscated payload.
 *
 * Arguments
 *  DAQ_PktHdr_t *pkth
 *   The pcap header information associated with the payload being
 *   obfuscated.
 *  uint8_t *packet_data
 *   Pointer to the packet data to be obfuscated
 *  ob_char_t ob_char
 *   The obfuscation character
 *  ob_size_t length
 *   The length of the portion of packet payload to use
 *  void *user_data
 *   The ObfuscatedPayload data
 *
 * Returns
 *  OB_RET_ERROR  if copying obfuscation data is not successful
 *  OB_RET_SUCCESS  if successful copying data to payload
 *
 ******************************************************************************/
static ObRet GetObfuscatedPayloadCallback(const DAQ_PktHdr_t *pkth,
     const uint8_t *packet_data, ob_size_t length,
     ob_char_t ob_char, void *user_data)
{
    ObfuscatedPayload *ob_payload = (ObfuscatedPayload *)user_data;
    uint8_t *payload;
    ob_size_t payload_len, payload_size;

    if (ob_payload == NULL)
        return OB_RET_ERROR;

    if ((ob_payload->payload == NULL) || (ob_payload->payload_len == NULL))
        return OB_RET_ERROR;

    payload = *ob_payload->payload;
    payload_len = *ob_payload->payload_len;
    payload_size = ob_payload->payload_size;

    if ((payload_len + length) > payload_size)
    {
        /* Allocate extra so we don't have to reallocate every time in */
        ob_size_t new_size = payload_len + length + 100;
        uint8_t *tmp = (uint8_t *)SnortAlloc(new_size);

        if (payload != NULL)
        {
            if (SafeMemcpy(tmp, payload, payload_len,
                        tmp, tmp + new_size) != SAFEMEM_SUCCESS)
            {
                free(tmp);
                free(payload);
                return OB_RET_ERROR;
            }

            free(payload);
        }

        payload_size = new_size;
        ob_payload->payload_size = new_size;

        *ob_payload->payload = tmp;
        payload = tmp;
    }

    if (packet_data != NULL)
    {
        if (SafeMemcpy(payload + payload_len, packet_data, length,
                    payload, payload + payload_size) != SAFEMEM_SUCCESS)
        {
            free(payload);
            return OB_RET_ERROR;
        }
    }
    else
    {
        if (SafeMemset(payload + payload_len, (uint8_t)ob_char, length,
                    payload, payload + payload_size) != SAFEMEM_SUCCESS)
        {
            free(payload);
            return OB_RET_ERROR;
        }
    }

    *ob_payload->payload_len += length;

    return OB_RET_SUCCESS;
}
示例#21
0
/* Accumulate email addresses from RCPT TO and/or MAIL FROM commands. Email addresses are separated by comma */
int SMTP_CopyEmailID(const uint8_t *start, int length, int command_type)
{
    uint8_t *alt_buf;
    int alt_size;
    uint16_t *alt_len;
    int ret;
    int log_avail=0;
    const uint8_t *tmp_eol;

    if ((smtp_ssn->log_state == NULL) || (length <= 0))
        return -1;

    tmp_eol = (uint8_t *)memchr(start, ':', length);
    if(tmp_eol == NULL)
        return -1;

    if((tmp_eol+1) < (start+length))
    {
        length = length - ( (tmp_eol+1) - start );
        start = tmp_eol+1;
    }
    else
        return -1;



    switch (command_type)
    {
        case CMD_MAIL:
            alt_buf = smtp_ssn->log_state->senders;
            alt_size = MAX_EMAIL;
            alt_len = &(smtp_ssn->log_state->snds_logged);
            break;

        case CMD_RCPT:
            alt_buf = smtp_ssn->log_state->recipients;
            alt_size = MAX_EMAIL;
            alt_len = &(smtp_ssn->log_state->rcpts_logged);
            break;

        default:
            return -1;
    }

    log_avail = alt_size - *alt_len;

    if(log_avail <= 0 || !alt_buf)
        return -1;
    else if(log_avail < length)
        length = log_avail;

    if ( *alt_len > 0 && ((*alt_len + 1) < alt_size))
    {
        alt_buf[*alt_len] = ',';
        *alt_len = *alt_len + 1;
    }

    ret = SafeMemcpy(alt_buf + *alt_len, start, length, alt_buf, alt_buf + alt_size);

    if (ret != SAFEMEM_SUCCESS)
    {
        if(*alt_len != 0)
            *alt_len = *alt_len - 1;
        return -1;
    }

    *alt_len += length;

    return 0;
}
示例#22
0
int hi_split_header_cookie(HI_SESSION *Session, u_char *header, int *i_header_len,
                           u_char *cookie_header, int *i_cookie_len,
                           const u_char *raw_header, int i_raw_header_len,
                           COOKIE_PTR *cookie)
{
    int iRet = HI_SUCCESS;
    COOKIE_PTR *last_cookie = NULL;
    COOKIE_PTR *first_cookie = cookie;
    const u_char *raw_header_end = raw_header + i_raw_header_len;
    int this_cookie_len = 0;
    const u_char *this_header_start = raw_header;
    const u_char *this_header_end;
    int this_header_len = 0;
    const u_char *header_end;
    const u_char *cookie_end;

    if (!cookie || !i_header_len || !i_cookie_len)
        return HI_INVALID_ARG;

    /* Can't use hi_util_in_bounds header because == is okay */
    if (cookie->cookie_end > raw_header + i_raw_header_len)
        return HI_OUT_OF_BOUNDS;

    header_end = (const u_char *)(header + *i_header_len);
    *i_header_len = 0;
    cookie_end = (const u_char *)(cookie_header + *i_cookie_len);
    *i_cookie_len = 0;

    do
    {
        this_cookie_len = cookie->cookie_end - cookie->cookie;
        this_header_end = cookie->cookie;
        this_header_len = this_header_end - this_header_start;

        /* Trim the header and only copy what we can store in the buf */
        if (*i_header_len + this_header_len > MAX_URI)
        {
            this_header_len = MAX_URI - *i_header_len;
        }
        /* Copy out the headers from start to beginning of the cookie */
        if (this_header_len > 0)
        {
            if (SafeMemcpy(header + *i_header_len, this_header_start, this_header_len, header, header_end) == SAFEMEM_SUCCESS)
            {
                *i_header_len += this_header_len;
            }
        }
        else
        {
            DEBUG_WRAP(DebugMessage(DEBUG_HTTPINSPECT, "HttpInspect: no leading header: %d to %d\n",
                this_header_end - this_header_start, this_header_len););
        }

        /* Trim the cookie and only copy what we can store in the buf */
        if (*i_cookie_len + this_cookie_len > MAX_URI)
        {
            this_cookie_len = MAX_URI - *i_cookie_len;
        }
        /* And copy the cookie */
        if (this_cookie_len > 0)
        {
            if (SafeMemcpy(cookie_header + *i_cookie_len, cookie->cookie, this_cookie_len, cookie_header, cookie_end) == SAFEMEM_SUCCESS)
            {
                *i_cookie_len += this_cookie_len;
            }
        }
        else
        {
            DEBUG_WRAP(DebugMessage(DEBUG_HTTPINSPECT, "HttpInspect: trimming cookie: %d to %d\n",
                cookie->cookie_end - cookie->cookie, this_cookie_len););
        }
示例#23
0
文件: obfuscation.c 项目: eqmcc/snort
/*******************************************************************************
 * Function: TraverseObfuscationList()
 *
 * This is the main function for obfuscating a payload or stream segments.
 * It walks through a packet and obfuscation entries, calling the user
 * callback with obfuscated and non-obfuscated instructions.
 *
 * Arguments
 *  ObfuscationCallbackData *data
 *   The state tracking data structure.  Has the packet being obfuscated,
 *   current obfuscation entry and total number of bytes obfuscated thus
 *   far.
 *  DAQ_PktHdr_t *pkth
 *   The pcap header information associated with the payload being
 *   obfuscated.
 *  uint8_t *pkt
 *   The start of the packet including Ethernet headers, etc.
 *  uint8_t *payload
 *   Pointer to the payload data to be obfuscated
 *  ob_size_t
 *   The size of the payload data
 *
 * Returns
 *  OB_RET_SUCCESS  if successfully completed
 *  OB_RET_ERROR  if the user callback doesn't return OB_RET_SUCCESS
 *
 ******************************************************************************/
static ObRet TraverseObfuscationList(ObfuscationCallbackData *data,
        const DAQ_PktHdr_t *pkth, const uint8_t *payload_data,
        ob_size_t payload_size)
{
    int i;
    ob_size_t total_offset = data->total_offset;
    ob_size_t payload_offset = 0;
    const DAQ_PktHdr_t *pkth_tmp = pkth;
#ifdef OBFUSCATION_TEST
    uint8_t print_array[OB_LENGTH_MAX];
    ob_size_t start_total_offset = 0;
    ob_size_t start_payload_offset = 0;
#endif

    if ((payload_data == NULL) || (payload_size == 0))
        return OB_RET_ERROR;

#ifdef OBFUSCATION_TEST
    LogMessage("Payload data: %u bytes\n", payload_size);
    LogMessage("==============================================================="
            "=================\n");
#endif

    /* Start from current saved obfuscation entry index */
    for (i = data->entry_index; i < ob_struct.num_entries; i++)
    {
        /* Get the entry from the sorted array */
        const ObfuscationEntry *entry = ob_struct.sort_entries[i];
        ob_size_t ob_offset = entry->offset;
        ob_size_t ob_length = entry->length;

        /* Make sure it's for the right packet */
        if (entry->p != data->packet)
        {
#ifdef OBFUSCATION_TEST
            LogMessage("flags1: %08x, flags2: %08x\n", entry->p->packet_flags, data->packet->packet_flags);
#endif
            continue;
        }

        /* We've already obfuscated this part of the packet payload
         * Account for overflow */
        if (((ob_offset + ob_length) <= total_offset)
                && ((ob_offset + ob_length) > ob_offset))
        {
            continue;
        }

#ifdef OBFUSCATION_TEST
        LogMessage("  Total offset: %u\n\n", total_offset);
        start_total_offset = total_offset;
        start_payload_offset = payload_offset;
#endif

        /* Note the obfuscation offset is only used at this point to determine
         * the amount of data that does not need to be obfuscated up to the
         * offset or the length of what needs to be obfuscated if the offset
         * is less than what's already been logged */

        if (ob_offset > total_offset)
        {
            /* Get the amount of non-obfuscated data - need to log straight
             * packet data up to obfuscation offset */
            ob_size_t length = ob_offset - total_offset;

            /* If there is more length than what's left in the packet,
             * truncate it, do we don't overflow */
            if (length > (payload_size - payload_offset))
                length = payload_size - payload_offset;

            /* Call the user callback and tell it not to obfuscate the data
             * by passing in a non-NULL packet pointer */
            if (data->user_callback(pkth_tmp, payload_data + payload_offset,
                        length, 0, data->user_data) != OB_RET_SUCCESS)
            {
                return OB_RET_ERROR;
            }

#ifdef OBFUSCATION_TEST
            SafeMemcpy(print_array + payload_offset, payload_data + payload_offset,
                    length, print_array, print_array + sizeof(print_array));
#endif
            /* Only the first payload call sends the pcap_pkthdr */
            pkth_tmp = NULL;

            /* Adjust offsets */
            payload_offset += length;
            total_offset += length;

            /* If there is no more packet data, break out of the loop */
            if (payload_offset == payload_size)
            {
#ifdef OBFUSCATION_TEST
                PrintPacketData(print_array + start_payload_offset, length);
                LogMessage("\n");
#endif
                break;
            }
        }
        else if (ob_offset < total_offset)
        {
            /* If the entries offset is less than the current total offset,
             * decrease the length. */
            ob_length -= (total_offset - ob_offset);
        }

        /* Adjust the amount of data to obfuscate if it exceeds the amount of
         * data left in the packet.  Account for overflow */
        if (((payload_offset + ob_length) > payload_size)
                || ((payload_offset + ob_length) <= payload_offset))
        {
            ob_length = payload_size - payload_offset;
        }

        /* Call the user callback and tell it to obfuscate the data by passing
         * in a NULL packet pointer */
        if (data->user_callback(pkth_tmp, NULL, ob_length,
                    entry->ob_char, data->user_data) != OB_RET_SUCCESS)
        {
            return OB_RET_ERROR;
        }

#ifdef OBFUSCATION_TEST
        LogMessage("  Entry: %d\n", i);
        LogMessage("  --------------------------\n");
        PrintObfuscationEntry(entry, 4);
        LogMessage("\n");

        SafeMemset(print_array + payload_offset, entry->ob_char,
                ob_length, print_array, print_array + sizeof(print_array));

        if (ob_length < entry->length)
        {
            if (ob_offset < start_total_offset)
            {
                if (payload_offset + ob_length == payload_size)
                {
                    LogMessage("  Obfuscating beyond already obfuscated "
                            "(%u bytes) and to end of payload: %u bytes\n\n",
                            (start_total_offset - ob_offset), ob_length);
                }
                else
                {
                    LogMessage("  Obfuscating beyond already obfuscated "
                            "(%u bytes): %u bytes\n\n",
                            (start_total_offset - ob_offset), ob_length);
                }
            }
            else
            {
                LogMessage("  Obfuscating to end of payload: "
                        "%u bytes\n\n", ob_length);
            }
        }
        else
        {
            LogMessage("  Obfuscating: %u bytes\n\n", ob_length);
        }

        PrintPacketData(print_array + start_payload_offset,
                (payload_offset - start_payload_offset) + ob_length);

        if (((entry->offset + entry->length) - (total_offset + ob_length)) > 0)
        {
            LogMessage("\n  Remaining amount to obfuscate: %u bytes\n",
                    (entry->offset + entry->length) - (total_offset + ob_length));
        }

        LogMessage("\n");
#endif

        /* Only the first payload call sends the pcap_pkthdr */
        pkth_tmp = NULL;

        /* Adjust offsets */
        payload_offset += ob_length;
        total_offset += ob_length;

        /* If there is no more packet data, break out of the loop */
        if (payload_offset == payload_size)
            break;
    }

    /* There's more data in the packet left, meaning we ran out of
     * obfuscation entries */
    if (payload_size > payload_offset)
    {
        ob_size_t length = payload_size - payload_offset;

        /* Call the user callback and tell it not to obfuscate the data
         * by passing in a non-NULL packet pointer */
        if (data->user_callback(pkth_tmp, payload_data + payload_offset,
                    length, 0, data->user_data) != OB_RET_SUCCESS)
        {
            return OB_RET_ERROR;
        }

#ifdef OBFUSCATION_TEST
        SafeMemcpy(print_array + payload_offset, payload_data + payload_offset,
                length, print_array, print_array + sizeof(print_array));
#endif

        /* Adjust offsets - don't need to adjust packet offset since
         * we're done with the packet */
        total_offset += length;
    }

#ifdef OBFUSCATION_TEST
    LogMessage("Obfuscated payload\n");
    LogMessage("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
            "~~~~~~~~~~\n");
    PrintPacketData(print_array, payload_size);
    LogMessage("\n\n");
#endif

    /* Save these for next time we come in if necessary.  Mainly for
     * traversing stream segments */
    data->entry_index = i;
    data->total_offset = total_offset;

    return OB_RET_SUCCESS;
}