Project

General

Profile

Bug #22 » 0001-fix-for-bug-22-better-handle-malformed-smb-packets.patch

Kirby Kuehl, 12/29/2009 12:28 AM

View differences:

src/app-layer-smb.c
/* For WriteAndX we need to get writeandxdataoffset */
static int SMBParseWriteAndX(Flow *f, void *smb_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, AppLayerParserResult *output) {
SCEnter();
SMBState *sstate = (SMBState *) smb_state;
uint8_t *p = input;
switch (sstate->andx.andxbytesprocessed) {
......
sstate->andx.dataoffset|= (uint64_t) *(p+25) << 48;
sstate->andx.dataoffset|= (uint64_t) *(p+26) << 40;
sstate->andx.dataoffset|= (uint64_t) *(p+27) << 32;
input_len -= 28;
sstate->bytesprocessed += 28;
return 28;
SCReturnInt(28);
} else {
sstate->andx.andxcommand = *(p++);
if (!(--input_len)) break;
......
break;
default:
// SHOULD NEVER OCCUR
return 0;
SCReturnInt(-1);
}
sstate->bytesprocessed += (p - input);
return (p - input);
SCReturnInt(p - input);
}
/**
......
*/
static int SMBParseReadAndX(Flow *f, void *smb_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, AppLayerParserResult *output) {
SCEnter();
SMBState *sstate = (SMBState *) smb_state;
uint8_t *p = input;
switch (sstate->andx.andxbytesprocessed) {
......
sstate->andx.datalength |= (uint64_t) *(p+17) << 32;
input_len -= 24;
sstate->bytesprocessed += 24;
return 24;
SCReturnInt(24);
} else {
sstate->andx.andxcommand = *(p++);
if (!(--input_len)) break;
......
break;
default:
// SHOULD NEVER OCCUR
return 0;
SCReturnInt(0);
}
return 0;
sstate->bytesprocessed += (p - input);
return (p - input);
SCReturnInt(p - input);
}
/**
......
*/
static int PaddingParser(void *smb_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, AppLayerParserResult *output) {
SCEnter();
SMBState *sstate = (SMBState *) smb_state;
uint8_t *p = input;
while (sstate->bytesprocessed++ < sstate->andx.dataoffset && sstate->bytecount.bytecount-- && input_len--) {
......
sstate->andx.paddingparsed = 1;
}
sstate->bytesprocessed += (p - input);
return (p - input);
SCReturnInt(p - input);
}
/**
......
*/
static int DataParser(void *smb_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, AppLayerParserResult *output) {
SCEnter();
SMBState *sstate = (SMBState *) smb_state;
uint8_t *p = input;
......
}
}
sstate->bytesprocessed += (p - input);
return (p - input);
SCReturnInt(p - input);
}
/**
* \brief Obtain SMB WordCount which is 2 times the value.
* Reset bytecount.bytecountbytes to 0.
......
if (input_len) {
SMBState *sstate = (SMBState *) smb_state;
sstate->wordcount.wordcount = *(input) * 2;
sstate->wordcount.wordcountleft = sstate->wordcount.wordcount;
sstate->bytesprocessed++;
sstate->bytecount.bytecountbytes = 0;
sstate->andx.isandx = isAndX(sstate);
......
if (input_len && sstate->bytesprocessed == NBSS_HDR_LEN + SMB_HDR_LEN +
2 + sstate->wordcount.wordcount) {
sstate->bytecount.bytecount |= *(p++) << 8;
sstate->bytecount.bytecountleft = sstate->bytecount.bytecount;
sstate->bytesprocessed++;
SCLogDebug("Bytecount %u", sstate->bytecount.bytecount);
--input_len;
......
retval = SMBParseReadAndX(f, sstate, pstate, input + parsed, input_len, output);
parsed += retval;
input_len -= retval;
sstate->wordcount.wordcount -= retval;
return retval;
sstate->wordcount.wordcountleft -= retval;
SCReturnInt(retval);
} else if (((sstate->smb.flags & SMB_FLAGS_SERVER_TO_REDIR) == 0) && sstate->smb.command == SMB_COM_WRITE_ANDX) {
retval = SMBParseWriteAndX(f, sstate, pstate, input + parsed, input_len, output);
parsed += retval;
input_len -= retval;
sstate->wordcount.wordcount -= retval;
return retval;
sstate->wordcount.wordcountleft -= retval;
SCReturnInt(retval);
} else { /* Generic WordCount Handler */
while (sstate->wordcount.wordcount-- && input_len--) {
printf("0x%02x ", *(p++));
while (sstate->wordcount.wordcountleft-- && input_len--) {
SCLogDebug("0x%02x wordcountleft %u input_len %u\n", *(p++),
sstate->wordcount.wordcountleft, input_len);
}
printf("\n");
SCLogDebug("\n");
sstate->bytesprocessed += (p - input);
return (p - input);
SCReturnInt(p - input);
}
}
......
}
}
while (sstate->bytecount.bytecount && input_len) {
while (sstate->bytecount.bytecountleft-- && input_len--) {
SCLogDebug("0x%02x bytecount %u input_len %u", *(p++),
sstate->bytecount.bytecount, input_len);
sstate->wordcount.wordcount--;
input_len--;
}
printf("\n");
SCLogDebug("\n");
sstate->bytesprocessed += (p - input);
SCReturnInt(p - input);
}
#define DEBUG 1
static int NBSSParseHeader(Flow *f, void *smb_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, AppLayerParserResult *output)
{
......
sstate->smb.uid |= *(p + 29);
sstate->smb.mid = *(p + 30) << 8;
sstate->smb.mid |= *(p + 31);
input_len -= SMB_HDR_LEN;
sstate->bytesprocessed += SMB_HDR_LEN;
SCReturnInt(SMB_HDR_LEN);
break;
......
parsed, input_len, output);
parsed += retval;
input_len -= retval;
printf("SMB Header (%u/%u) Command 0x%02x parsed %u input_len %u\n",
SCLogDebug("SMB Header (%u/%u) Command 0x%02x parsed %u input_len %u\n",
sstate->bytesprocessed, NBSS_HDR_LEN + SMB_HDR_LEN,
sstate->smb.command, parsed, input_len);
}
......
output);
parsed += retval;
input_len -= retval;
printf("Wordcount (%u) parsed %u input_len %u\n",
sstate->wordcount.wordcount, parsed, input_len);
}
while (input_len && (sstate->bytesprocessed >= NBSS_HDR_LEN + SMB_HDR_LEN + 1 &&
......
input_len -= retval;
}
if (SMB_HDR_LEN + sstate->wordcount.wordcount + sstate->bytecount.bytecount + 3 >
sstate->nbss.length) {
printf("Caught Malformed SMB Packet\n");
pstate->parse_field = 0;
pstate->flags |= APP_LAYER_PARSER_DONE;
SCReturnInt(-1);
}
while (input_len && (sstate->bytesprocessed >= NBSS_HDR_LEN +
SMB_HDR_LEN + 3 + sstate->wordcount.wordcount &&
sstate->bytesprocessed < NBSS_HDR_LEN + SMB_HDR_LEN + 3
......
*/
int isAndX(SMBState *smb_state) {
SCEnter();
switch (smb_state->smb.command) {
case SMB_NO_SECONDARY_ANDX_COMMAND:
case SMB_COM_LOCKING_ANDX:
......
case SMB_COM_TREE_CONNECT_ANDX:
case SMB_COM_NT_CREATE_ANDX:
smb_state->andx.andxbytesprocessed = 0;
return 1;
SCReturnInt(1);
default:
return 0;
SCReturnInt(0);
}
}
src/app-layer-smb.h
typedef struct wordcount_ {
uint8_t wordcount;
uint8_t wordcountleft;
uint8_t *words;
}wordcount_t, *pwordcount_t;
typedef struct bytecount_ {
uint8_t bytecountbytes;
uint16_t bytecount;
uint16_t bytecountleft;
uint8_t *bytes;
}bytecount_t, *pbytyecount_t;
(2-2/2)