# Copyright (c) 2003-2006 CORE Security Technologies # # This software is provided under under a slightly modified version # of the Apache Software License. See the accompanying LICENSE file # for more information. # # $Id: dcerpc_v4.py,v 1.10 2006/05/23 22:26:51 gera Exp $ # # Description: # Handle basic DCE/RPC protocol, version 4. # import array import socket import struct from impacket import ImpactPacket from impacket import uuid import dcerpc, conv class MSRPCHeader(ImpactPacket.Header): __SIZE = 80 def __init__(self, aBuffer = None): ImpactPacket.Header.__init__(self, MSRPCHeader.__SIZE) self.set_version(4) self.set_type(dcerpc.MSRPC_REQUEST) self.set_flags((0x08, 0x00)) self.set_representation((0x10, 0x00, 0x00)) self.set_serial((0, 0)) ## self.set_if_version(3) self.set_seq_num(0) self.set_if_hint(0xFFFF) self.set_activity_hint(0xFFFF) if aBuffer: self.load_header(aBuffer) def get_version(self): return self.get_byte(0) def set_version(self, version): self.set_byte(0, version) def get_type(self): return self.get_byte(1) def set_type(self, type): self.set_byte(1, type) def get_flags(self): """ This method returns a tuple in (flags1, flags2) form.""" return (self.get_byte(2), self.get_byte(3)) def set_flags(self, flags): """ This method takes a tuple in (flags1, flags2) form.""" self.set_byte(2, flags[0]) self.set_byte(3, flags[1]) def get_representation(self): """ This method returns a tuple in (major, minor) form.""" return (self.get_byte(4), self.get_byte(5), self.get_byte(6)) def set_representation(self, representation): """ This method takes a tuple in (major, minor) form.""" self.set_byte(4, representation[0]) self.set_byte(5, representation[1]) self.set_byte(6, representation[1]) def get_serial(self): """ This method returns a tuple in (high, low) form.""" return (self.get_byte(7), self.get_byte(79)) def set_serial(self, serial): """ This method takes a tuple in (high, low) form.""" self.set_byte(7, serial[0]) self.set_byte(79, serial[1]) def get_obj_binuuid(self): return self.get_bytes().tolist()[8:8+16] def set_obj_binuuid(self, binuuid): assert 16 == len(binuuid) self.get_bytes()[8:8+16] = array.array('B', binuuid) def get_if_binuuid(self): return self.get_bytes().tolist()[24:24+16] def set_if_binuuid(self, binuuid): assert 16 == len(binuuid) self.get_bytes()[24:24+16] = array.array('B', binuuid) def get_activity_binuuid(self): return self.get_bytes().tolist()[40:40+16] def set_activity_binuuid(self, binuuid): assert 16 == len(binuuid) self.get_bytes()[40:40+16] = array.array('B', binuuid) def get_server_boottime(self): return self.get_long(56, '<') def set_server_boottime(self, time): self.set_long(56, time, '<') def get_if_version(self): return self.get_long(60, '<') def set_if_version(self, version): self.set_long(60, version, '<') def get_seq_num(self): return self.get_long(64, '<') def set_seq_num(self, num): self.set_long(64, num, '<') def get_op_num(self): return self.get_word(68, '<') def set_op_num(self, op): self.set_word(68, op, '<') def get_if_hint(self): return self.get_word(70, '<') def set_if_hint(self, hint): self.set_word(70, hint, '<') def get_activity_hint(self): return self.get_word(72, '<') def set_activity_hint(self, hint): self.set_word(72, hint, '<') def get_frag_len(self): return self.get_word(74, '<') def set_frag_len(self, len): self.set_word(74, len, '<') def get_frag_num(self): return self.get_word(76, '<') def set_frag_num(self, num): self.set_word(76, num, '<') def get_auth_proto(self): return self.get_byte(78) def set_auth_proto(self, proto): self.set_byte(78, proto) def get_header_size(self): return MSRPCHeader.__SIZE def contains(self, aHeader): ImpactPacket.Header.contains(self, aHeader) if self.child(): contents_size = self.child().get_size() self.set_op_num(self.child().OP_NUM) self.set_frag_len(contents_size) def get_ctx_id(self): # return self.get_word(20, '<') return 0 def set_ctx_id(self, id): # self.set_word(20, id, '<') pass class DCERPC_v4(dcerpc.DCERPC): DEFAULT_FRAGMENT_SIZE = 1392 def __init__(self, transport): dcerpc.DCERPC.__init__(self, transport) self.__activity_uuid = uuid.generate() self.__seq_num = 0 self._bind = 0 # Don't attempt binding unless it explicitly requested. self.set_idempotent(0) def set_default_max_fragment_size(self): self.set_max_fragment_size(DCERPC_v4.DEFAULT_FRAGMENT_SIZE) def bind(self, uuid, bogus_binds = ''): """If idempotent is non-zero, the package will be sent with that flag enabled. Certain services react by skiping the CONV phase during the binding. """ self._bind = 1 # Will bind later, when the first packet is transferred. self.__if_uuid = uuid[:16] self.__if_version = struct.unpack('