예제 #1
0
int SMB_Fragmentation(u_int8_t *smb_hdr, SMB_WRITEX_REQ *writeX, u_int8_t *smb_data, u_int16_t data_size)
{
    u_char    fragmented = 0;
    u_int16_t writeX_length;
    u_char    success = 0;

    /* Check for fragmentation */
    if ( _disable_smb_fragmentation )
        return 0;

    /* If not yet reassembling, attempt to parse as full DCE/RPC packet */
    if ( !(_dcerpc->fragmentation & SMB_FRAGMENTATION) )
    {
        success = ProcessDCERPCMessage(smb_hdr, smb_data, data_size);

        if ( success )
            return 0;
    }

    /* Set up writeX buffer to save SMB data.  Ignore dataLengthHigh, since we won't
        handle fragments that big.  */
    writeX_length = writeX->dataLength;

    /* Allocate space for buffer
        For now, ignore offset, since servers seem to */
    if ( !(_dcerpc->fragmentation & SUSPEND_FRAGMENTATION) )
    {
        if ( _dcerpc->write_andx_buf == NULL )
        {
            if ( writeX_length > _max_frag_size )
                writeX_length = _max_frag_size;

            _dcerpc->write_andx_buf = (u_int8_t *) DCERPC_FragAlloc(NULL, 0, &writeX_length);

            if ( !_dcerpc->write_andx_buf )
                _dpd.fatalMsg("Failed to allocate space for SMB Write AndX\n");
        
            if ( writeX_length == 0 )
            {
                DEBUG_WRAP(_dpd.debugMsg(DEBUG_DCERPC, "Memcap reached, ignoring SMB fragmentation reassembly.\n"););

                DCERPC_FragFree(_dcerpc->write_andx_buf, 0);
                _dcerpc->write_andx_buf = NULL;
                _dcerpc->fragmentation |= SUSPEND_FRAGMENTATION;
                return 0;
            }

            _dcerpc->write_andx_buf_size = writeX_length;
            _dcerpc->write_andx_buf_len  = 0;
        }
예제 #2
0
static void ReassembleSMBWriteX(SMB_WRITEX_REQ *writeX, u_int8_t *smb_data)
{
    SMB_WRITEX_REQ temp_writeX;
    unsigned int   smb_hdr_len = (u_int8_t *)writeX - _dcerpc_pkt->payload;
    unsigned int   writeX_len = smb_data - (u_int8_t *)writeX;

    /* Make sure we have room to fit into alternate buffer */
    if ( (smb_hdr_len + writeX_len + _dcerpc->write_andx_buf_len) > _dpd.altBufferLen )
    {
        _dpd.logMsg("Reassembled SMB packet greater than %d bytes, skipping.",
															_dpd.altBufferLen);
        return;
    }

    /* Mock up header */
    memcpy(&temp_writeX, writeX, writeX_len);
    temp_writeX.remaining = _dcerpc->write_andx_buf_len;
    temp_writeX.dataLength = _dcerpc->write_andx_buf_len;

    /* Copy headers into buffer */
    /* SMB Header */
    memcpy(_dpd.altBuffer, _dcerpc_pkt->payload, smb_hdr_len);
    _dcerpc_pkt->normalized_payload_size = smb_hdr_len;
    
    /* Write AndX header */
    memcpy(_dpd.altBuffer + _dcerpc_pkt->normalized_payload_size, &temp_writeX, writeX_len);
    _dcerpc_pkt->normalized_payload_size += writeX_len;

    /* Copy data into buffer */
    memcpy(_dpd.altBuffer + _dcerpc_pkt->normalized_payload_size, _dcerpc->write_andx_buf, _dcerpc->write_andx_buf_len);
    _dcerpc_pkt->normalized_payload_size += _dcerpc->write_andx_buf_len;

    _dcerpc_pkt->flags |= FLAG_ALT_DECODE;

    ProcessDCERPCMessage(_dcerpc_pkt->payload, _dcerpc->write_andx_buf, _dcerpc->write_andx_buf_len);

    /* Get ready for next write */
    DCERPC_FragFree(_dcerpc->write_andx_buf, _dcerpc->write_andx_buf_size);
    _dcerpc->write_andx_buf = NULL;
    _dcerpc->write_andx_buf_len = 0;
    _dcerpc->write_andx_buf_size = 0;
    _dcerpc->fragmentation &= ~SMB_FRAGMENTATION;
    _dcerpc->fragmentation &= ~SUSPEND_FRAGMENTATION;
}
예제 #3
0
파일: dcerpc_util.c 프로젝트: OPSF/uClinux
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;
}