📄 smb_andx_decode.c
字号:
/* Service field is ALWAYS ascii */ if (service_len > 0) PrintSMBString("Service: ", service_ptr, service_len, 0);#endif /* put tree_data at end of this request for comparing * against andXOffset */ tree_data += tree_data_len; /* Handle next andX command in this packet */ if (treeConnX->andXCommand != SMB_NONE) { u_int16_t andXOffset = smb_ntohs(treeConnX->andXOffset); u_int8_t *next_command; u_int16_t data_left_len; if ( andXOffset >= total_size ) return 0; next_command = (u_int8_t *)smbHdr + andXOffset; /* Make sure we don't backtrack or look at the same data again */ if (next_command < tree_data) return 0; /* Skip header, get size of remaining data */ data_left_len = total_size - andXOffset; /* Next block is at smbHdr + smb_ntohs(sess_setupx_req->andXOffset) */ return ProcessNextSMBCommand(treeConnX->andXCommand, smbHdr, next_command, data_left_len, total_size); } return 0;}int ProcessSMBNTCreateX(SMB_HDR *smbHdr, u_int8_t *data, u_int16_t size, u_int16_t total_size){ SMB_NTCREATEX_REQ *ntCreateX; u_int16_t byteCount; u_int8_t *nt_create_data; u_int16_t nt_create_data_len; u_int8_t *file_name_ptr; int file_name_len; if ( size <= sizeof(SMB_NTCREATEX_REQ) ) { return 0; } ntCreateX = (SMB_NTCREATEX_REQ *)data; size -= sizeof(SMB_NTCREATEX_REQ); byteCount = smb_ntohs(ntCreateX->byteCount); if (byteCount > size) return 0; nt_create_data = data + sizeof(SMB_NTCREATEX_REQ); nt_create_data_len = byteCount; /* Appears to be a pad in there to word-align if unicode */ if (HAS_UNICODE_STRINGS(smbHdr)) { nt_create_data++; nt_create_data_len--; } /* note that the file name length in the header does not seem * to be used by the server */ file_name_len = GetSMBStringLength(nt_create_data, nt_create_data_len, HAS_UNICODE_STRINGS(smbHdr)); if (file_name_len == -1) return 0; file_name_ptr = nt_create_data; /* there shouldn't be any more data */ if (nt_create_data + file_name_len != nt_create_data + nt_create_data_len) return 0; if ( _dcerpc->smb_state == STATE_GOT_TREE_CONNECT ) _dcerpc->smb_state = STATE_GOT_NTCREATE;#ifdef DEBUG_DCERPC_PRINT PrintSMBString("Create/Open: ", file_name_ptr, file_name_len, HAS_UNICODE_STRINGS(smbHdr));#endif /* put nt_create_data at end of this request for comparing * against andXOffset */ nt_create_data += nt_create_data_len; /* Handle next andX command in this packet */ if (ntCreateX->andXCommand != SMB_NONE) { u_int16_t andXOffset = smb_ntohs(ntCreateX->andXOffset); u_int8_t *next_command; u_int16_t data_left_len; if ( andXOffset >= total_size ) return 0; next_command = (u_int8_t *)smbHdr + andXOffset; /* Make sure we don't backtrack or look at the same data again */ if (next_command < nt_create_data) return 0; /* Skip header, get size of remaining data */ data_left_len = total_size - andXOffset; /* Next block is at smbHdr + smb_ntohs(sess_setupx_req->andXOffset) */ return ProcessNextSMBCommand(ntCreateX->andXCommand, smbHdr, next_command, data_left_len, total_size); } return 0;}int ProcessSMBWriteX(SMB_HDR *smbHdr, u_int8_t *data, u_int16_t size, u_int16_t total_size){ SMB_WRITEX_REQ *writeX; u_int8_t *writeX_data; u_int16_t writeX_data_len; u_int16_t writeX_byte_count; u_int16_t data_offset; u_int16_t padding; /* Only process WriteAndX packet if it is part of a DCE/RPC session */ if ( _dcerpc->smb_state != STATE_GOT_NTCREATE ) { return 0; } if ( size <= sizeof(SMB_WRITEX_REQ) ) { return 0; } writeX = (SMB_WRITEX_REQ *)data; data_offset = smb_ntohs(writeX->dataOffset); if ( data_offset >= total_size ) { return 0; } writeX_data = (u_int8_t *)smbHdr + data_offset; writeX_data_len = smb_ntohs(writeX->dataLength); writeX_byte_count = smb_ntohs(writeX->byteCount); /* byte count is always greater than or equal to data length and * accounts for extra padding at end of header and before actual data */ if (writeX_data_len > writeX_byte_count) return 0; padding = writeX_byte_count - writeX_data_len; /* data_offset put us somewhere before the end of the header and padding */ if (writeX_data < (u_int8_t *)writeX + sizeof(SMB_WRITEX_REQ) + padding) return 0; /* data_offset + data_len will put us past end of packet */ if (writeX_data + writeX_data_len > (u_int8_t *)smbHdr + total_size) return 0;#ifdef DEBUG_DCERPC_PRINT if (writeX_data_len > 0) printf("WriteAndX data: %02.*X\n", writeX_data_len, writeX_data);#endif if (writeX_data_len > 0) { u_int16_t smb_hdr_len = writeX_data - (u_int8_t *)smbHdr; DCERPC_Buffer *sbuf = &_dcerpc->smb_seg_buf; int status = ProcessDCERPCMessage((u_int8_t *)smbHdr, smb_hdr_len, writeX_data, writeX_data_len); if (status == -1) return -1; if ((status == DCERPC_FULL_FRAGMENT) && !DCERPC_BufferIsEmpty(sbuf)) { ReassembleSMBWriteX((u_int8_t *)smbHdr, smb_hdr_len); DCERPC_BufferFreeData(sbuf); } else if ((status == DCERPC_SEGMENTED) && _reassemble_increment) { _dcerpc->num_inc_reass++; if (_reassemble_increment == _dcerpc->num_inc_reass) { _dcerpc->num_inc_reass = 0; ReassembleSMBWriteX((u_int8_t *)smbHdr, smb_hdr_len); } } } /* put dce_data at end of this request for comparing * against andXOffset */ writeX_data += writeX_data_len; /* Handle next andX command in this packet */ if (writeX->andXCommand != SMB_NONE) { u_int16_t andXOffset = smb_ntohs(writeX->andXOffset); u_int8_t *next_command; u_int16_t data_left_len; if ( andXOffset >= total_size ) return 0; next_command = (u_int8_t *)smbHdr + andXOffset; /* Make sure we don't backtrack or look at the same data again */ if (next_command < writeX_data) return 0; /* Skip WriteX header, get size of remaining data */ data_left_len = total_size - andXOffset; /* Next block is at smbHdr + smb_ntohs(sess_setupx_req->andXOffset) */ return ProcessNextSMBCommand(writeX->andXCommand, smbHdr, next_command, data_left_len, total_size); } return 0;}int ProcessSMBTransaction(SMB_HDR *smbHdr, u_int8_t *data, u_int16_t size, u_int16_t total_size){ SMB_TRANS_REQ *trans; u_int8_t *dcerpc_data; u_int16_t dcerpc_data_len; u_int16_t data_offset; /* Only process Trans packet if we think it is part of a DCE/RPC session NTCREATE state is when we get the bind packet IS_DCERPC is when we get a request packet */ if ( _dcerpc->smb_state != STATE_GOT_NTCREATE ) { return 0; } /* We got a Tree Connect followed by a NTCreate, followed by Trans. Assume DCE/RPC */ _dcerpc->state = STATE_IS_DCERPC; if ( size <= sizeof(SMB_TRANS_REQ) ) { return 0; } trans = (SMB_TRANS_REQ *)data; data_offset = smb_ntohs(trans->dataOffset); dcerpc_data = (u_int8_t *)smbHdr + data_offset; if ( data_offset >= total_size ) return 0; /* offset didn't put us after header * TODO Account for transaction name length - seems like * for unicode strings there is an extra byte of padding * after byteCount before name starts */ if (dcerpc_data < (u_int8_t *)trans + sizeof(SMB_TRANS_REQ)) return 0; dcerpc_data_len = smb_ntohs(trans->totalDataCount); /* make sure data length doesn't put us past end of packet */ if (dcerpc_data + dcerpc_data_len > (u_int8_t *)smbHdr + total_size) return 0; if (dcerpc_data_len > 0) ProcessDCERPCMessage((u_int8_t *)smbHdr, (u_int16_t)(dcerpc_data - (u_int8_t *)smbHdr), dcerpc_data, dcerpc_data_len);#ifdef DEBUG_DCERPC_PRINT printf("Trans data: %02.*X\n", dcerpc_data_len, dcerpc_data);#endif return 0;}int ProcessSMBReadX(SMB_HDR *smbHdr, u_int8_t *data, u_int16_t size, u_int16_t total_size){ SMB_READX_REQ *readX; if ( size < sizeof(SMB_READX_REQ) ) { return 0; } readX = (SMB_READX_REQ *)data; data += sizeof(SMB_READX_REQ); /* Handle next andX command in this packet */ if (readX->andXCommand != SMB_NONE) { u_int16_t andXOffset = smb_ntohs(readX->andXOffset); u_int8_t *next_command; u_int16_t data_left_len; if ( andXOffset >= total_size ) return 0; next_command = (u_int8_t *)smbHdr + andXOffset; /* Make sure we don't backtrack or look at the same data again */ if (next_command < data) return 0; /* Skip ReadX header, get size of remaining data */ data_left_len = total_size - andXOffset; /* Next block is at smbHdr + smb_ntohs(sess_setupx_req->andXOffset) */ return ProcessNextSMBCommand(readX->andXCommand, smbHdr, next_command, data_left_len, total_size); } return 0;}#ifdef UNUSED_SMB_COMMANDint ProcessSMBSetupXReq(SMB_HDR *smbHdr, u_int8_t *data, u_int16_t size, u_int16_t total_size){ int extraIndex = 0; SMB_SESS_SETUPX_REQ_HDR *sess_setupx_req_hdr; /* Ptr to first null terminated data element */ unsigned char wordCount; /* Skip the common header portion, wordCount byte + parameter bytes * 2 */ unsigned char *smb_data; short byteCount = 0, extraBytes = 0; int skipBytes = 1; int passwdLen = 0; char unicodePasswd = 0; if ( size <= sizeof(SMB_SESS_SETUPX_REQ_HDR) ) { return 0; } sess_setupx_req_hdr = (SMB_SESS_SETUPX_REQ_HDR *)data; wordCount = sess_setupx_req_hdr->wordCount; switch (wordCount) { case 10: { /* Old session setup andx */ SMB_SESS_SETUPX_REQ_AUTH_OLD *sess_setupx_auth = (SMB_SESS_SETUPX_REQ_AUTH_OLD *) (data + sizeof(SMB_SESS_SETUPX_REQ_HDR)); passwdLen = smb_ntohs(sess_setupx_auth->passwdLen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -