def construct(flags, domainname=None, workstationname=None, version=None): nego = NTLMNegotiate() nego.NegotiateFlags = flags nego.Payload = b'' payload_pos = 32 if flags & NegotiateFlags.NEGOTIATE_VERSION: if not version: raise Exception( 'NEGOTIATE_VERSION set but no Version supplied!') payload_pos += 8 nego.Version = version if nego.NegotiateFlags & NegotiateFlags.NEGOTIATE_OEM_DOMAIN_SUPPLIED and domainname: data = domainname.encode('utf-16le') nego.Payload += data nego.DomainNameFields = Fields(len(data), payload_pos) payload_pos += len(data) nego.Domain = data else: nego.DomainNameFields = Fields(0, 0) if nego.NegotiateFlags & NegotiateFlags.NEGOTIATE_OEM_WORKSTATION_SUPPLIED and workstationname: data = workstationname.encode('utf-16le') nego.Payload += data nego.WorkstationFields = Fields(len(data), payload_pos) payload_pos += len(data) nego.Workstation = data else: nego.WorkstationFields = Fields(0, 0) return nego
def from_buffer(buff): t = NTLMChallenge() t.Signature = buff.read(8) t.MessageType = int.from_bytes(buff.read(4), byteorder='little', signed=False) t.TargetNameFields = Fields.from_buffer(buff) t.NegotiateFlags = NegotiateFlags( int.from_bytes(buff.read(4), byteorder='little', signed=False)) t.ServerChallenge = buff.read(8) t.Reserved = buff.read(8) t.TargetInfoFields = Fields.from_buffer(buff) if t.NegotiateFlags & NegotiateFlags.NEGOTIATE_VERSION: t.Version = Version.from_buffer(buff) currPos = buff.tell() t.Payload = buff.read() if t.TargetNameFields.length != 0: buff.seek(t.TargetNameFields.offset, io.SEEK_SET) raw_data = buff.read(t.TargetNameFields.length) try: t.TargetName = raw_data.decode('utf-16le') except UnicodeDecodeError: # yet another cool bug. t.TargetName = raw_data.decode('utf-8') if t.TargetInfoFields.length != 0: buff.seek(t.TargetInfoFields.offset, io.SEEK_SET) raw_data = buff.read(t.TargetInfoFields.length) t.TargetInfo = AVPairs.from_bytes(raw_data) return t
def construct(challenge = os.urandom(8), targetName = None, targetInfo = None, version = None, flags = None): pos = 48 if version: pos += 8 t = NTLMChallenge() t.NegotiateFlags = flags t.Version = version t.ServerChallenge = challenge t.TargetName = targetName t.TargetInfo = targetInfo t.TargetNameFields = Fields(len(t.TargetName.encode('utf-16le')),pos) t.TargetInfoFields = Fields(len(t.TargetInfo.to_bytes()), pos + len(t.TargetName.encode('utf-16le'))) t.Payload = t.TargetName.encode('utf-16le') t.Payload += t.TargetInfo.to_bytes() return t
def from_buffer(buff): t = NTLMNegotiate() t.Signature = buff.read(8) t.MessageType = int.from_bytes(buff.read(4), byteorder='little', signed=False) t.NegotiateFlags = NegotiateFlags( int.from_bytes(buff.read(4), byteorder='little', signed=False)) t.DomainNameFields = Fields.from_buffer(buff) t.WorkstationFields = Fields.from_buffer(buff) if t.NegotiateFlags & NegotiateFlags.NEGOTIATE_VERSION: t.Version = Version.from_buffer(buff) currPos = buff.tell() t.Payload = buff.read() #currPos = buff.tell() if t.DomainNameFields.length != 0: buff.seek(t.DomainNameFields.offset, io.SEEK_SET) raw_data = buff.read(t.WorkstationFields.length) #print(raw_data) #print(t.DomainNameFields.length) try: t.Domain = raw_data.decode('utf-16le') except UnicodeDecodeError: # yet another cool bug. t.Domain = raw_data.decode('utf-8') if t.WorkstationFields.length != 0: buff.seek(t.WorkstationFields.offset, io.SEEK_SET) raw_data = buff.read(t.WorkstationFields.length) try: t.Workstation = raw_data.decode('utf-16le') except UnicodeDecodeError: # yet another cool bug. t.Workstation = raw_data.decode('utf-8') #buff.seek(currPos, io.SEEK_SET) return t
def from_buffer(buff, _use_NTLMv2=True): auth = NTLMAuthenticate(_use_NTLMv2) auth.Signature = buff.read(8) auth.MessageType = int.from_bytes(buff.read(4), byteorder='little', signed=False) auth.LmChallengeResponseFields = Fields.from_buffer(buff) auth.NtChallengeResponseFields = Fields.from_buffer(buff) auth.DomainNameFields = Fields.from_buffer(buff) auth.UserNameFields = Fields.from_buffer(buff) auth.WorkstationFields = Fields.from_buffer(buff) auth.EncryptedRandomSessionKeyFields = Fields.from_buffer(buff) auth.NegotiateFlags = NegotiateFlags( int.from_bytes(buff.read(4), byteorder='little', signed=False)) if auth.NegotiateFlags & NegotiateFlags.NEGOTIATE_VERSION: auth.Version = Version.from_buffer(buff) # TODO: I'm not sure about this condition!!! Need to test this! if auth.NegotiateFlags & NegotiateFlags.NEGOTIATE_ALWAYS_SIGN: auth.MIC = buff.read(16) currPos = buff.tell() auth.Payload = buff.read() if auth._use_NTLMv2 and auth.NtChallengeResponseFields.length > 24: buff.seek(auth.LmChallengeResponseFields.offset, io.SEEK_SET) auth.LMChallenge = LMv2Response.from_buffer(buff) buff.seek(auth.NtChallengeResponseFields.offset, io.SEEK_SET) auth.NTChallenge = NTLMv2Response.from_buffer(buff) else: buff.seek(auth.LmChallengeResponseFields.offset, io.SEEK_SET) auth.LMChallenge = LMResponse.from_buffer(buff) buff.seek(auth.NtChallengeResponseFields.offset, io.SEEK_SET) auth.NTChallenge = NTLMv1Response.from_buffer(buff) buff.seek(auth.DomainNameFields.offset, io.SEEK_SET) auth.DomainName = buff.read( auth.DomainNameFields.length).decode('utf-16le') buff.seek(auth.UserNameFields.offset, io.SEEK_SET) auth.UserName = buff.read( auth.UserNameFields.length).decode('utf-16le') buff.seek(auth.WorkstationFields.offset, io.SEEK_SET) auth.Workstation = buff.read( auth.WorkstationFields.length).decode('utf-16le') buff.seek(auth.EncryptedRandomSessionKeyFields.offset, io.SEEK_SET) auth.EncryptedRandomSession = buff.read( auth.EncryptedRandomSessionKeyFields.length) buff.seek(currPos, io.SEEK_SET) return auth
def construct(flags, domainname=None, workstationname=None, username=None, encrypted_session=None, lm_response=None, nt_response=None, version=None, mic=b'\x00' * 16): auth = NTLMAuthenticate() auth.Payload = b'' payload_pos = 8 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 if flags & NegotiateFlags.NEGOTIATE_VERSION: if not version: raise Exception( 'NEGOTIATE_VERSION set but no Version supplied!') auth.Version = version payload_pos += 8 if mic is not None: auth.MIC = mic payload_pos += 16 if lm_response: data = lm_response.to_bytes() auth.Payload += data auth.LmChallengeResponseFields = Fields(len(data), payload_pos) payload_pos += len(data) auth.LMChallenge = lm_response else: auth.LmChallengeResponseFields = Fields(0, 0) if nt_response: data = nt_response.to_bytes() auth.Payload += data auth.NtChallengeResponseFields = Fields(len(data), payload_pos) payload_pos += len(data) auth.NTChallenge = nt_response else: auth.NtChallengeResponseFields = Fields(0, 0) if domainname: data = domainname.encode('utf-16le') auth.Payload += data auth.DomainNameFields = Fields(len(data), payload_pos) payload_pos += len(data) auth.DomainName = domainname else: auth.DomainNameFields = Fields(0, 0) if username: data = username.encode('utf-16le') auth.Payload += data auth.UserNameFields = Fields(len(data), payload_pos) payload_pos += len(data) auth.UserName = username else: auth.UserNameFields = Fields(0, 0) if workstationname: data = workstationname.encode('utf-16le') auth.Payload += data auth.WorkstationFields = Fields(len(data), payload_pos) payload_pos += len(data) auth.Workstation = workstationname else: auth.WorkstationFields = Fields(0, 0) if encrypted_session: data = encrypted_session auth.Payload += data auth.EncryptedRandomSessionKeyFields = Fields( len(data), payload_pos) payload_pos += len(data) auth.EncryptedRandomSession = encrypted_session else: auth.EncryptedRandomSessionKeyFields = Fields(0, 0) auth.NegotiateFlags = flags return auth