|
version 1.9.2.1, 2007/02/02 15:17:11
|
version 1.9.2.2, 2007/02/17 20:36:46
|
|
|
|
| #include <string.h> | #include <string.h> |
| | |
| #include "debug.h" | #include "debug.h" |
| |
#include "bounds.h" |
| | |
| #include "snort_dcerpc.h" | #include "snort_dcerpc.h" |
| #include "smb_structs.h" | #include "smb_structs.h" |
|
|
|
| static void ReassembleSMBWriteX(SMB_WRITEX_REQ *writeX, u_int8_t *smb_data) | static void ReassembleSMBWriteX(SMB_WRITEX_REQ *writeX, u_int8_t *smb_data) |
| { | { |
| SMB_WRITEX_REQ temp_writeX; | SMB_WRITEX_REQ temp_writeX; |
| u_int16_t smb_hdr_len = (u_int16_t)((u_int8_t *)writeX - _dcerpc_pkt->payload); |
u_int16_t smb_hdr_len = sizeof(SMB_HDR) + sizeof(NBT_HDR); |
| u_int16_t writeX_len = (u_int16_t)(smb_data - (u_int8_t *)writeX); | u_int16_t writeX_len = (u_int16_t)(smb_data - (u_int8_t *)writeX); |
| |
u_int32_t check_len; |
| |
int ret; |
| |
|
| |
check_len = (u_int32_t)smb_hdr_len + (u_int32_t)writeX_len + (u_int32_t)_dcerpc->write_andx_buf_len; |
| | |
| /* Make sure we have room to fit into alternate buffer */ | /* Make sure we have room to fit into alternate buffer */ |
| if ( (smb_hdr_len + writeX_len + _dcerpc->write_andx_buf_len) > (u_int16_t) _dpd.altBufferLen ) |
if ( check_len > _dpd.altBufferLen ) |
| { | { |
| DEBUG_WRAP(_dpd.debugMsg(DEBUG_DCERPC, "Reassembled SMB packet greater than %d bytes, skipping.", | DEBUG_WRAP(_dpd.debugMsg(DEBUG_DCERPC, "Reassembled SMB packet greater than %d bytes, skipping.", |
| _dpd.altBufferLen)); | _dpd.altBufferLen)); |
| goto dcerpc_fragfree; | goto dcerpc_fragfree; |
| } | } |
| | |
| /* Sanity check on size; account for alternate padding */ |
/* Sanity check on size; account for optional padding */ |
| if ( writeX_len > (sizeof(SMB_WRITEX_REQ) + 1) ) | if ( writeX_len > (sizeof(SMB_WRITEX_REQ) + 1) ) |
| { | { |
| DEBUG_WRAP(_dpd.debugMsg(DEBUG_DCERPC, "WriteAndX header too big: %u, skipping SMB reassembly.", | DEBUG_WRAP(_dpd.debugMsg(DEBUG_DCERPC, "WriteAndX header too big: %u, skipping SMB reassembly.", |
| _dpd.altBufferLen)); |
writeX_len)); |
| goto dcerpc_fragfree; | goto dcerpc_fragfree; |
| } | } |
| | |
|
|
|
| | |
| /* Copy headers into buffer */ | /* Copy headers into buffer */ |
| /* SMB Header */ | /* SMB Header */ |
| memcpy(_dpd.altBuffer, _dcerpc_pkt->payload, smb_hdr_len); |
ret = SafeMemcpy(_dpd.altBuffer, _dcerpc_pkt->payload, smb_hdr_len, |
| |
_dpd.altBuffer, _dpd.altBuffer + _dpd.altBufferLen); |
| |
if ( ret == 0 ) |
| |
{ |
| |
DEBUG_WRAP(_dpd.debugMsg(DEBUG_DCERPC, "WriteAndX header too big: %u, skipping SMB reassembly.", |
| |
_dpd.altBufferLen)); |
| |
goto dcerpc_fragfree; |
| |
} |
| |
|
| _dcerpc_pkt->normalized_payload_size = smb_hdr_len; | _dcerpc_pkt->normalized_payload_size = smb_hdr_len; |
| | |
| /* Write AndX header */ | /* Write AndX header */ |
| memcpy(_dpd.altBuffer + _dcerpc_pkt->normalized_payload_size, &temp_writeX, writeX_len); |
ret = SafeMemcpy(_dpd.altBuffer + _dcerpc_pkt->normalized_payload_size, &temp_writeX, |
| _dcerpc_pkt->normalized_payload_size += writeX_len; |
sizeof(SMB_WRITEX_REQ), _dpd.altBuffer, _dpd.altBuffer + _dpd.altBufferLen); |
| |
if ( ret == 0 ) |
| |
{ |
| |
DEBUG_WRAP(_dpd.debugMsg(DEBUG_DCERPC, "WriteAndX header too big: %u, skipping SMB reassembly.", |
| |
_dpd.altBufferLen)); |
| |
goto dcerpc_fragfree; |
| |
} |
| |
_dcerpc_pkt->normalized_payload_size += sizeof(SMB_WRITEX_REQ); |
| |
|
| |
/* Account for optional padding byte in WriteAndX header. It is never used so we don't write it. */ |
| |
if ( writeX_len > sizeof(SMB_WRITEX_REQ) ) |
| |
{ |
| |
_dcerpc_pkt->normalized_payload_size += 1; |
| |
} |
| | |
| /* Copy data into buffer */ | /* Copy data into buffer */ |
| memcpy(_dpd.altBuffer + _dcerpc_pkt->normalized_payload_size, _dcerpc->write_andx_buf, _dcerpc->write_andx_buf_len); |
ret = SafeMemcpy(_dpd.altBuffer + _dcerpc_pkt->normalized_payload_size, _dcerpc->write_andx_buf, |
| |
_dcerpc->write_andx_buf_len, _dpd.altBuffer, _dpd.altBuffer + _dpd.altBufferLen); |
| |
if ( ret == 0 ) |
| |
{ |
| |
DEBUG_WRAP(_dpd.debugMsg(DEBUG_DCERPC, "WriteAndX header too big: %u, skipping SMB reassembly.", |
| |
_dpd.altBufferLen)); |
| |
goto dcerpc_fragfree; |
| |
} |
| _dcerpc_pkt->normalized_payload_size += _dcerpc->write_andx_buf_len; | _dcerpc_pkt->normalized_payload_size += _dcerpc->write_andx_buf_len; |
| | |
| _dcerpc_pkt->flags |= FLAG_ALT_DECODE; | _dcerpc_pkt->flags |= FLAG_ALT_DECODE; |
|
|
|
| | |
| int SMB_Fragmentation(u_int8_t *smb_hdr, SMB_WRITEX_REQ *writeX, u_int8_t *smb_data, u_int16_t data_size) | int SMB_Fragmentation(u_int8_t *smb_hdr, SMB_WRITEX_REQ *writeX, u_int8_t *smb_data, u_int16_t data_size) |
| { | { |
| u_int16_t writeX_length; |
u_int16_t writeX_length, temp_len; |
| int success = 0; | int success = 0; |
| | |
| /* Check for fragmentation */ | /* Check for fragmentation */ |
|
|
|
| { | { |
| writeX_length = _dcerpc->write_andx_buf_size - _dcerpc->write_andx_buf_len; | writeX_length = _dcerpc->write_andx_buf_size - _dcerpc->write_andx_buf_len; |
| } | } |
| |
/* Make sure data to be copied is within source buffer */ |
| |
if ( (smb_data + writeX_length) > (_dcerpc_pkt->payload + _dcerpc_pkt->payload_size) ) |
| |
{ |
| |
temp_len = _dcerpc_pkt->payload + _dcerpc_pkt->payload_size - smb_data; |
| |
if ( writeX_length > temp_len ) |
| |
{ |
| |
writeX_length = temp_len; |
| |
} |
| |
} |
| memcpy(_dcerpc->write_andx_buf + _dcerpc->write_andx_buf_len, smb_data, writeX_length); | memcpy(_dcerpc->write_andx_buf + _dcerpc->write_andx_buf_len, smb_data, writeX_length); |
| _dcerpc->write_andx_buf_len += writeX_length; | _dcerpc->write_andx_buf_len += writeX_length; |
| _dcerpc->fragmentation |= SMB_FRAGMENTATION; | _dcerpc->fragmentation |= SMB_FRAGMENTATION; |