?? smb_andx_decode.c
字號:
printf("\n");}#endifint SkipBytes(u_int8_t *data, u_int16_t size){ u_int16_t i = 0; while ( i < size && *data != 0 ) { data++; i++; } return i;}int SkipBytesWide(u_int8_t *data, u_int16_t size){ u_int16_t i = 0; /* Check against size-1 in case someone is screwing with us and giving us an odd number of bytes for 2-byte Unicode. */ while ( i < (size - 1) && *data != 0 ) { data += 2; i += 2; } return i;}int ProcessSMBTreeConnXReq(SMB_HDR *smbHdr, u_int8_t *data, u_int16_t size, u_int16_t total_size){ SMB_TREE_CONNECTX_REQ *treeConnX; u_int16_t byteCount; u_int8_t *tree_data; u_int16_t tree_data_len; u_int8_t *passwd_ptr; u_int16_t passwd_len; u_int8_t *path_ptr; int path_len; u_int8_t *service_ptr; int service_len; int is_ipc; if ( size <= sizeof(SMB_TREE_CONNECTX_REQ) ) { return 0; } treeConnX = (SMB_TREE_CONNECTX_REQ *)data; size -= sizeof(SMB_TREE_CONNECTX_REQ); tree_data = data + sizeof(SMB_TREE_CONNECTX_REQ); byteCount = smb_ntohs(treeConnX->byteCount); tree_data_len = byteCount; passwd_len = smb_ntohs(treeConnX->passwdLen); /* Sanity check */ if ( byteCount > size || passwd_len >= byteCount) return 0; passwd_ptr = tree_data; tree_data += passwd_len; tree_data_len -= passwd_len; /* Get path */ path_len = GetSMBStringLength(tree_data, tree_data_len, HAS_UNICODE_STRINGS(smbHdr)); if (path_len == -1 || path_len == tree_data_len) return 0; path_ptr = tree_data; is_ipc = IsIPC(tree_data, path_len, HAS_UNICODE_STRINGS(smbHdr)); if (is_ipc && _dcerpc->smb_state == STATE_START) { _dcerpc->smb_state = STATE_GOT_TREE_CONNECT; } tree_data += path_len; tree_data_len -= path_len; /* Service field is ALWAYS ascii */ service_len = GetSMBStringLength(tree_data, tree_data_len, 0); if (service_len == -1) return 0; service_ptr = tree_data; /* there shouldn't be any more data */ if (tree_data + service_len != tree_data + tree_data_len) return 0;#ifdef DEBUG_DCERPC_PRINT /* Password data * it seems like the password length has to be an odd number * This passwd will always be ASCII -- equiv of * CaseInsensitivePasswd field from SessSetupAndX message */ if (passwd_len > 0) printf("Password: %02.*X\n", passwd_len, passwd_ptr); if (path_len > 0) PrintSMBString("Path: ", path_ptr, path_len, HAS_UNICODE_STRINGS(smbHdr)); /* 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) SMB_Fragmentation((u_int8_t *) smbHdr, writeX, writeX_data, writeX_data_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, 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) */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -