#!/usr/bin/env python # This file is part of Responder, a network take-over set of tools # created and maintained by Laurent Gaffie. # email: laurent.gaffie@gmail.com # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import settings import codecs import random import re from os import urandom from base64 import b64decode, b64encode from odict import OrderedDict from utils import HTTPCurrentDate, SMBTime, RespondWithIPAton, RespondWithIPPton, RespondWithIP, StructPython2or3, NetworkRecvBufferPython2or3, StructWithLenPython2or3 # Packet class handling all packet generation (see odict.py). class Packet(): fields = OrderedDict([ ("data", ""), ]) def __init__(self, **kw): self.fields = OrderedDict(self.__class__.fields) for k,v in kw.items(): if callable(v): self.fields[k] = v(self.fields[k]) else: self.fields[k] = v def __str__(self): return "".join(map(str, self.fields.values())) # NBT Answer Packet class NBT_Ans(Packet): fields = OrderedDict([ ("Tid", ""), ("Flags", "\x85\x00"), ("Question", "\x00\x00"), ("AnswerRRS", "\x00\x01"), ("AuthorityRRS", "\x00\x00"), ("AdditionalRRS", "\x00\x00"), ("NbtName", ""), ("Type", "\x00\x20"), ("Classy", "\x00\x01"), ("TTL", "\x00\x04\x93\xe0"), #TTL: 3 days, 11 hours, 20 minutes (Default windows behavior) ("Len", "\x00\x06"), ("Flags1", "\x00\x00"), ("IP", "\x00\x00\x00\x00"), ]) def calculate(self,data): self.fields["Tid"] = NetworkRecvBufferPython2or3(data[0:2]) self.fields["NbtName"] = NetworkRecvBufferPython2or3(data[12:46]) self.fields["IP"] = RespondWithIPAton() # DNS Answer Packet class DNS_Ans(Packet): fields = OrderedDict([ ("Tid", ""), ("Flags", "\x85\x10"), ("Question", "\x00\x01"), ("AnswerRRS", "\x00\x01"), ("AuthorityRRS", "\x00\x00"), ("AdditionalRRS", "\x00\x00"), ("QuestionName", ""), ("QuestionNameNull", "\x00"), ("Type", "\x00\x01"), ("Class", "\x00\x01"), ("AnswerPointer", "\xc0\x0c"), ("Type1", "\x00\x01"), ("Class1", "\x00\x01"), ("TTL", "\x00\x00\x00\x1e"), #30 secs, don't mess with their cache for too long.. ("IPLen", "\x00\x04"), ("IP", "\x00\x00\x00\x00"), ]) def calculate(self,data): self.fields["Tid"] = data[0:2] self.fields["QuestionName"] = ''.join(data[12:].split('\x00')[:1]) self.fields["IP"] = RespondWithIPAton() self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"]) # DNS Answer Packet OPT class DNS_AnsOPT(Packet): fields = OrderedDict([ ("Tid", ""), ("Flags", "\x85\x10"), ("Question", "\x00\x01"), ("AnswerRRS", "\x00\x01"), ("AuthorityRRS", "\x00\x00"), ("AdditionalRRS", "\x00\x01"), ("QuestionName", ""), ("QuestionNameNull", "\x00"), ("Type", "\x00\x01"), ("Class", "\x00\x01"), ("AnswerPointer", "\xc0\x0c"), ("Type1", "\x00\x01"), ("Class1", "\x00\x01"), ("TTL", "\x00\x00\x00\x1e"), #30 secs, don't mess with their cache for too long.. ("IPLen", "\x00\x04"), ("IP", "\x00\x00\x00\x00"), ("OPTName", "\x00"), ("OPTType", "\x00\x29"), ("OPTUDPSize", "\x10\x00"), ("OPTRCode", "\x00"), ("OPTEDNSVersion", "\x00"), ("OPTLen", "\x00\x00"),# Hardcoded since it's fixed to 0 in this case. ("OPTStr", "\x00\x00"), ]) def calculate(self,data): self.fields["Tid"] = data[0:2] self.fields["QuestionName"] = ''.join(data[12:].split('\x00')[:1]) self.fields["IP"] = RespondWithIPAton() self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"]) class DNS6_Ans(Packet): fields = OrderedDict([ ("Tid", ""), ("Flags", "\x85\x10"), ("Question", "\x00\x01"), ("AnswerRRS", "\x00\x01"), ("AuthorityRRS", "\x00\x00"), ("AdditionalRRS", "\x00\x00"), ("QuestionName", ""), ("QuestionNameNull", "\x00"), ("Type", "\x00\x1c"), ("Class", "\x00\x01"), ("AnswerPointer", "\xc0\x0c"), ("Type1", "\x00\x1c"), ("Class1", "\x00\x01"), ("TTL", "\x00\x00\x00\x1e"), #30 secs, don't mess with their cache for too long.. ("IPLen", "\x00\x04"), ("IP", "\x00\x00\x00\x00"), ]) def calculate(self,data): self.fields["Tid"] = data[0:2] self.fields["QuestionName"] = ''.join(data[12:].split('\x00')[:1]) self.fields["IP"] = RespondWithIPPton() self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"]) class DNS6_AnsOPT(Packet): fields = OrderedDict([ ("Tid", ""), ("Flags", "\x85\x10"), ("Question", "\x00\x01"), ("AnswerRRS", "\x00\x01"), ("AuthorityRRS", "\x00\x00"), ("AdditionalRRS", "\x00\x01"), ("QuestionName", ""), ("QuestionNameNull", "\x00"), ("Type", "\x00\x1c"), ("Class", "\x00\x01"), ("AnswerPointer", "\xc0\x0c"), ("Type1", "\x00\x1c"), ("Class1", "\x00\x01"), ("TTL", "\x00\x00\x00\x1e"), #30 secs, don't mess with their cache for too long.. ("IPLen", "\x00\x04"), ("IP", "\x00\x00\x00\x00"), ("OPTName", "\x00"), ("OPTType", "\x00\x29"), ("OPTUDPSize", "\x10\x00"), ("OPTRCode", "\x00"), ("OPTEDNSVersion", "\x00"), ("OPTLen", "\x00\x00"),# Hardcoded since it's fixed to 0 in this case. ("OPTStr", "\x00\x00"), ]) def calculate(self,data): self.fields["Tid"] = data[0:2] self.fields["QuestionName"] = ''.join(data[12:].split('\x00')[:1]) self.fields["IP"] = RespondWithIPPton() self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"]) class DNS_SRV_Ans(Packet): fields = OrderedDict([ ("Tid", ""), ("Flags", "\x85\x80"), ("Question", "\x00\x01"), ("AnswerRRS", "\x00\x01"), ("AuthorityRRS", "\x00\x00"), ("AdditionalRRS", "\x00\x00"), ("QuestionName", ""), ("QuestionNameNull", "\x00"), ("Type", "\x00\x21"),#srv ("Class", "\x00\x01"), ("AnswerPointer", "\xc0\x0c"), ("Type1", "\x00\x21"),#srv ("Class1", "\x00\x01"), ("TTL", "\x00\x00\x00\x1e"), #30 secs, don't mess with their cache for too long.. ("RecordLen", ""), ("Priority", "\x00\x00"), ("Weight", "\x00\x64"), ("Port", "\x00\x00"), ("TargetLenPre", "\x0f"), # static, we provide netbios computer name 15 chars like Windows by default. ("TargetPrefix", ""), ("TargetLenSuff", ""), ("TargetSuffix", ""), ("TargetLenSuff2", ""), ("TargetSuffix2", ""), ("TargetNull", "\x00"), ]) def calculate(self,data): self.fields["Tid"] = data[0:2] DNSName = ''.join(data[12:].split('\x00')[:1]) SplitFQDN = re.split(r'\W+', DNSName) # split the ldap.tcp.blah.blah.blah.domain.tld #What's the question? we need it first to calc all other len. self.fields["QuestionName"] = DNSName #Want to be detected that easily by xyz sensor? self.fields["TargetPrefix"] = settings.Config.MachineName #two last parts of the domain are the actual Domain name.. eg: contoso.com self.fields["TargetSuffix"] = SplitFQDN[-2] self.fields["TargetSuffix2"] = SplitFQDN[-1] #We calculate the len for that domain... self.fields["TargetLenSuff2"] = StructPython2or3(">B",self.fields["TargetSuffix2"]) self.fields["TargetLenSuff"] = StructPython2or3(">B",self.fields["TargetSuffix"]) # Calculate Record len. CalcLen = self.fields["Priority"]+self.fields["Weight"]+self.fields["Port"]+self.fields["TargetLenPre"]+self.fields["TargetPrefix"]+self.fields["TargetLenSuff"]+self.fields["TargetSuffix"]+self.fields["TargetLenSuff2"]+self.fields["TargetSuffix2"]+self.fields["TargetNull"] #Our answer len.. self.fields["RecordLen"] = StructPython2or3(">h",CalcLen) #for now we support ldap and kerberos... if "ldap" in DNSName: self.fields["Port"] = StructWithLenPython2or3(">h", 389) if "kerberos" in DNSName: self.fields["Port"] = StructWithLenPython2or3(">h", 88) # LLMNR Answer Packet class LLMNR_Ans(Packet): fields = OrderedDict([ ("Tid", ""), ("Flags", "\x80\x00"), ("Question", "\x00\x01"), ("AnswerRRS", "\x00\x01"), ("AuthorityRRS", "\x00\x00"), ("AdditionalRRS", "\x00\x00"), ("QuestionNameLen", "\x09"), ("QuestionName", ""), ("QuestionNameNull", "\x00"), ("Type", "\x00\x01"), ("Class", "\x00\x01"), ("AnswerNameLen", "\x09"), ("AnswerName", ""), ("AnswerNameNull", "\x00"), ("Type1", "\x00\x01"), ("Class1", "\x00\x01"), ("TTL", "\x00\x00\x00\x1e"),##Poison for 30 sec (Default windows behavior) ("IPLen", "\x00\x04"), ("IP", "\x00\x00\x00\x00"), ]) def calculate(self): self.fields["IP"] = RespondWithIPAton() self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"]) self.fields["AnswerNameLen"] = StructPython2or3(">B",self.fields["AnswerName"]) self.fields["QuestionNameLen"] = StructPython2or3(">B",self.fields["QuestionName"]) class LLMNR6_Ans(Packet): fields = OrderedDict([ ("Tid", ""), ("Flags", "\x80\x00"), ("Question", "\x00\x01"), ("AnswerRRS", "\x00\x01"), ("AuthorityRRS", "\x00\x00"), ("AdditionalRRS", "\x00\x00"), ("QuestionNameLen", "\x09"), ("QuestionName", ""), ("QuestionNameNull", "\x00"), ("Type", "\x00\x1c"), ("Class", "\x00\x01"), ("AnswerNameLen", "\x09"), ("AnswerName", ""), ("AnswerNameNull", "\x00"), ("Type1", "\x00\x1c"), ("Class1", "\x00\x01"), ("TTL", "\x00\x00\x00\x1e"),##Poison for 30 sec (Default windows behavior). ("IPLen", "\x00\x04"), ("IP", "\x00\x00\x00\x00"), ]) def calculate(self): self.fields["IP"] = RespondWithIPPton() self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"]) self.fields["AnswerNameLen"] = StructPython2or3(">B",self.fields["AnswerName"]) self.fields["QuestionNameLen"] = StructPython2or3(">B",self.fields["QuestionName"]) # MDNS Answer Packet class MDNS_Ans(Packet): fields = OrderedDict([ ("Tid", "\x00\x00"), ("Flags", "\x84\x00"), ("Question", "\x00\x00"), ("AnswerRRS", "\x00\x01"), ("AuthorityRRS", "\x00\x00"), ("AdditionalRRS", "\x00\x00"), ("AnswerName", ""), ("AnswerNameNull", "\x00"), ("Type", "\x00\x01"), ("Class", "\x00\x01"), ("TTL", "\x00\x00\x00\x78"),##Poison for 2mn (Default windows behavior) ("IPLen", "\x00\x04"), ("IP", "\x00\x00\x00\x00"), ]) def calculate(self): self.fields["IP"] = RespondWithIPAton() self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"]) # MDNS6 Answer Packet class MDNS6_Ans(Packet): fields = OrderedDict([ ("Tid", "\x00\x00"), ("Flags", "\x84\x00"), ("Question", "\x00\x00"), ("AnswerRRS", "\x00\x01"), ("AuthorityRRS", "\x00\x00"), ("AdditionalRRS", "\x00\x00"), ("AnswerName", ""), ("AnswerNameNull", "\x00"), ("Type", "\x00\x1c"), ("Class", "\x00\x01"), ("TTL", "\x00\x00\x00\x78"),##Poison for 2mn (Default windows behavior) ("IPLen", "\x00\x04"), ("IP", "\x00\x00\x00\x00"), ]) def calculate(self): self.fields["IP"] = RespondWithIPPton() self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"]) ################### DHCP SRV ###################### ##### HTTP Packets ##### class NTLM_Challenge(Packet): fields = OrderedDict([ ("Signature", "NTLMSSP"), ("SignatureNull", "\x00"), ("MessageType", "\x02\x00\x00\x00"), ("TargetNameLen", "\x06\x00"), ("TargetNameMaxLen", "\x06\x00"), ("TargetNameOffset", "\x38\x00\x00\x00"), ("NegoFlags", "\x05\x02\x81\xa2" if settings.Config.NOESS_On_Off else "\x05\x02\x89\xa2"), ("ServerChallenge", ""), ("Reserved", "\x00\x00\x00\x00\x00\x00\x00\x00"), ("TargetInfoLen", "\x7e\x00"), ("TargetInfoMaxLen", "\x7e\x00"), ("TargetInfoOffset", "\x3e\x00\x00\x00"), ("NTLMOsVersion", "\x0a\x00\x7c\x4f\x00\x00\x00\x0f"), ("TargetNameStr", settings.Config.Domain), ("Av1", "\x02\x00"),#nbt name ("Av1Len", "\x06\x00"), ("Av1Str", settings.Config.Domain), ("Av2", "\x01\x00"),#Server name ("Av2Len", "\x14\x00"), ("Av2Str", settings.Config.MachineName), ("Av3", "\x04\x00"),#Full Domain name ("Av3Len", "\x12\x00"), ("Av3Str", settings.Config.DomainName), ("Av4", "\x03\x00"),#Full machine domain name ("Av4Len", "\x28\x00"), ("Av4Str", settings.Config.MachineName+'.'+settings.Config.DomainName), ("Av5", "\x05\x00"),#Domain Forest Name ("Av5Len", "\x12\x00"), ("Av5Str", settings.Config.DomainName), ("Av6", "\x00\x00"),#AvPairs Terminator ("Av6Len", "\x00\x00"), ]) def calculate(self): # First convert to unicode self.fields["TargetNameStr"] = self.fields["TargetNameStr"].encode('utf-16le') self.fields["Av1Str"] = self.fields["Av1Str"].encode('utf-16le') self.fields["Av2Str"] = self.fields["Av2Str"].encode('utf-16le') self.fields["Av3Str"] = self.fields["Av3Str"].encode('utf-16le') self.fields["Av4Str"] = self.fields["Av4Str"].encode('utf-16le') self.fields["Av5Str"] = self.fields["Av5Str"].encode('utf-16le') #Now from bytes to str.. self.fields["TargetNameStr"] = self.fields["TargetNameStr"].decode('latin-1') self.fields["Av1Str"] = self.fields["Av1Str"].decode('latin-1') self.fields["Av2Str"] = self.fields["Av2Str"].decode('latin-1') self.fields["Av3Str"] = self.fields["Av3Str"].decode('latin-1') self.fields["Av4Str"] = self.fields["Av4Str"].decode('latin-1') self.fields["Av5Str"] = self.fields["Av5Str"].decode('latin-1') # Then calculate CalculateNameOffset = str(self.fields["Signature"])+str(self.fields["SignatureNull"])+str(self.fields["MessageType"])+str(self.fields["TargetNameLen"])+str(self.fields["TargetNameMaxLen"])+str(self.fields["TargetNameOffset"])+str(self.fields["NegoFlags"])+str("A"*8)+str(self.fields["Reserved"])+str(self.fields["TargetInfoLen"])+str(self.fields["TargetInfoMaxLen"])+str(self.fields["TargetInfoOffset"])+str(self.fields["NTLMOsVersion"]) CalculateAvPairsOffset = CalculateNameOffset+str(self.fields["TargetNameStr"]) CalculateAvPairsLen = str(self.fields["Av1"])+str(self.fields["Av1Len"])+str(self.fields["Av1Str"])+str(self.fields["Av2"])+str(self.fields["Av2Len"])+str(self.fields["Av2Str"])+str(self.fields["Av3"])+str(self.fields["Av3Len"])+str(self.fields["Av3Str"])+str(self.fields["Av4"])+str(self.fields["Av4Len"])+str(self.fields["Av4Str"])+str(self.fields["Av5"])+str(self.fields["Av5Len"])+str(self.fields["Av5Str"])+str(self.fields["Av6"])+str(self.fields["Av6Len"]) # Target Name Offsets self.fields["TargetNameOffset"] = StructPython2or3(" 401 - Unauthorized: Access is denied due to invalid credentials.

401 - Unauthorized: Access is denied due to invalid credentials.

You do not have permission to view this directory or page using the credentials that you supplied.

"""), ]) def calculate(self): self.fields["ActualLen"] = len(str(self.fields["Payload"])) class IIS_Auth_Granted(Packet): fields = OrderedDict([ ("Code", "HTTP/1.1 200 OK\r\n"), ("ServerType", "Server: Microsoft-IIS/10.0\r\n"), ("Date", "Date: "+HTTPCurrentDate()+"\r\n"), ("Type", "Content-Type: text/html\r\n"), ("WWW-Auth", "WWW-Authenticate: NTLM\r\n"), ("ContentLen", "Content-Length: "), ("ActualLen", "76"), ("CRLF", "\r\n\r\n"), ("Payload", ""), ]) def calculate(self): self.fields["ActualLen"] = len(str(self.fields["Payload"])) class IIS_NTLM_Challenge_Ans(Packet): fields = OrderedDict([ ("Code", "HTTP/1.1 401 Unauthorized\r\n"), ("ServerType", "Server: Microsoft-IIS/10.0\r\n"), ("Date", "Date: "+HTTPCurrentDate()+"\r\n"), ("Type", "Content-Type: text/html\r\n"), ("WWWAuth", "WWW-Authenticate: NTLM "), ("Payload", ""), ("Payload-CRLF", "\r\n"), ("ContentLen", "Content-Length: "), ("ActualLen", "76"), ("CRLF", "\r\n\r\n"), ("Payload2", """ Not Authorized

Not Authorized


HTTP Error 401. The requested resource requires user authentication.

"""), ]) def calculate(self): self.fields["ActualLen"] = len(str(self.fields["Payload2"])) class WinRM_NTLM_Challenge_Ans(Packet): fields = OrderedDict([ ("Code", "HTTP/1.1 401\r\n"), ("WWWAuth", "WWW-Authenticate: Negotiate "), ("Payload", ""), ("Payload-CRLF", "\r\n"), ("ServerType", "Server: Microsoft-HTTPAPI/2.0\r\n"), ("Date", "Date: "+HTTPCurrentDate()+"\r\n"), ("Len", "Content-Length: 0\r\n"), ("CRLF", "\r\n"), ]) def calculate(self,payload): self.fields["Payload"] = b64encode(payload) class IIS_Basic_401_Ans(Packet): fields = OrderedDict([ ("Code", "HTTP/1.1 401 Unauthorized\r\n"), ("ServerType", "Server: Microsoft-IIS/10.0\r\n"), ("Type", "Content-Type: text/html\r\n"), ("WWW-Auth", "WWW-Authenticate: Basic realm=\"Authentication Required\"\r\n"), ("Date", "Date: "+HTTPCurrentDate()+"\r\n"), ("Len", "Content-Length: "), ("ActualLen", "76"), ("CRLF", "\r\n\r\n"), ("Payload", """ 401 - Unauthorized: Access is denied due to invalid credentials.

401 - Unauthorized: Access is denied due to invalid credentials.

You do not have permission to view this directory or page using the credentials that you supplied.

"""), ]) def calculate(self): self.fields["ActualLen"] = len(str(self.fields["Payload"])) ##### Proxy mode Packets ##### class WPADScript(Packet): fields = OrderedDict([ ("Code", "HTTP/1.1 200 OK\r\n"), ("Type", "Content-Type: application/x-ns-proxy-autoconfig\r\n"), ("Cache", "Pragma: no-cache\r\n"), ("Server", "Server: BigIP\r\n"), ("ContentLen", "Content-Length: "), ("ActualLen", "76"), ("CRLF", "\r\n\r\n"), ("Payload", "function FindProxyForURL(url, host){return 'PROXY "+RespondWithIP()+":3141; DIRECT';}"), ]) def calculate(self): self.fields["ActualLen"] = len(str(self.fields["Payload"])) class ServeExeFile(Packet): fields = OrderedDict([ ("Code", "HTTP/1.1 200 OK\r\n"), ("ContentType", "Content-Type: application/octet-stream\r\n"), ("LastModified", "Last-Modified: "+HTTPCurrentDate()+"\r\n"), ("AcceptRanges", "Accept-Ranges: bytes\r\n"), ("Server", "Server: Microsoft-IIS/10.0\r\n"), ("ContentDisp", "Content-Disposition: attachment; filename="), ("ContentDiFile", ""), ("FileCRLF", ";\r\n"), ("ContentLen", "Content-Length: "), ("ActualLen", "76"), ("Date", "\r\nDate: "+HTTPCurrentDate()+"\r\n"), ("Connection", "Connection: keep-alive\r\n"), ("X-CCC", "US\r\n"), ("X-CID", "2\r\n"), ("CRLF", "\r\n"), ("Payload", "jj"), ]) def calculate(self): self.fields["ActualLen"] = len(str(self.fields["Payload"])) class ServeHtmlFile(Packet): fields = OrderedDict([ ("Code", "HTTP/1.1 200 OK\r\n"), ("ContentType", "Content-Type: text/html\r\n"), ("LastModified", "Last-Modified: "+HTTPCurrentDate()+"\r\n"), ("AcceptRanges", "Accept-Ranges: bytes\r\n"), ("Server", "Server: Microsoft-IIS/10.0\r\n"), ("ContentLen", "Content-Length: "), ("ActualLen", "76"), ("Date", "\r\nDate: "+HTTPCurrentDate()+"\r\n"), ("Connection", "Connection: keep-alive\r\n"), ("CRLF", "\r\n"), ("Payload", "jj"), ]) def calculate(self): self.fields["ActualLen"] = len(str(self.fields["Payload"])) ##### WPAD Auth Packets ##### class WPAD_Auth_407_Ans(Packet): fields = OrderedDict([ ("Code", "HTTP/1.1 407 Unauthorized\r\n"), ("ServerType", "Server: Microsoft-IIS/10.0\r\n"), ("Date", "Date: "+HTTPCurrentDate()+"\r\n"), ("Type", "Content-Type: text/html\r\n"), ("WWW-Auth", "Proxy-Authenticate: NTLM\r\n"), ("Connection", "Proxy-Connection: close\r\n"), ("Cache-Control", "Cache-Control: no-cache\r\n"), ("Pragma", "Pragma: no-cache\r\n"), ("Proxy-Support", "Proxy-Support: Session-Based-Authentication\r\n"), ("Len", "Content-Length: 0\r\n"), ("CRLF", "\r\n"), ]) class WPAD_NTLM_Challenge_Ans(Packet): fields = OrderedDict([ ("Code", "HTTP/1.1 407 Unauthorized\r\n"), ("ServerType", "Server: Microsoft-IIS/10.0\r\n"), ("Date", "Date: "+HTTPCurrentDate()+"\r\n"), ("Type", "Content-Type: text/html\r\n"), ("WWWAuth", "Proxy-Authenticate: NTLM "), ("Payload", ""), ("Payload-CRLF", "\r\n"), ("Len", "Content-Length: 0\r\n"), ("CRLF", "\r\n"), ]) def calculate(self,payload): self.fields["Payload"] = b64encode(payload) class WPAD_Basic_407_Ans(Packet): fields = OrderedDict([ ("Code", "HTTP/1.1 407 Unauthorized\r\n"), ("ServerType", "Server: Microsoft-IIS/10.0\r\n"), ("Date", "Date: "+HTTPCurrentDate()+"\r\n"), ("Type", "Content-Type: text/html\r\n"), ("WWW-Auth", "Proxy-Authenticate: Basic realm=\"Authentication Required\"\r\n"), ("Connection", "Proxy-Connection: close\r\n"), ("Cache-Control", "Cache-Control: no-cache\r\n"), ("Pragma", "Pragma: no-cache\r\n"), ("Proxy-Support", "Proxy-Support: Session-Based-Authentication\r\n"), ("Len", "Content-Length: 0\r\n"), ("CRLF", "\r\n"), ]) ##### WEB Dav Stuff ##### class WEBDAV_Options_Answer(Packet): fields = OrderedDict([ ("Code", "HTTP/1.1 200 OK\r\n"), ("Date", "Date: "+HTTPCurrentDate()+"\r\n"), ("ServerType", "Server: Microsoft-IIS/10.0\r\n"), ("Allow", "Allow: GET,HEAD,POST,OPTIONS,TRACE\r\n"), ("Len", "Content-Length: 0\r\n"), ("Keep-Alive:", "Keep-Alive: timeout=5, max=100\r\n"), ("Connection", "Connection: Keep-Alive\r\n"), ("Content-Type", "Content-Type: text/html\r\n"), ("CRLF", "\r\n"), ]) ##### FTP Packets ##### class FTPPacket(Packet): fields = OrderedDict([ ("Code", "220"), ("Separator", "\x20"), ("Message", "Welcome"), ("Terminator", "\x0d\x0a"), ]) ##### SQL Packets ##### class MSSQLPreLoginAnswer(Packet): fields = OrderedDict([ ("PacketType", "\x04"), ("Status", "\x01"), ("Len", "\x00\x25"), ("SPID", "\x00\x00"), ("PacketID", "\x01"), ("Window", "\x00"), ("TokenType", "\x00"), ("VersionOffset", "\x00\x15"), ("VersionLen", "\x00\x06"), ("TokenType1", "\x01"), ("EncryptionOffset", "\x00\x1b"), ("EncryptionLen", "\x00\x01"), ("TokenType2", "\x02"), ("InstOptOffset", "\x00\x1c"), ("InstOptLen", "\x00\x01"), ("TokenTypeThrdID", "\x03"), ("ThrdIDOffset", "\x00\x1d"), ("ThrdIDLen", "\x00\x00"), ("ThrdIDTerminator", "\xff"), ("VersionStr", "\x09\x00\x0f\xc3"), ("SubBuild", "\x00\x00"), ("EncryptionStr", "\x02"), ("InstOptStr", "\x00"), ]) def calculate(self): CalculateCompletePacket = str(self.fields["PacketType"])+str(self.fields["Status"])+str(self.fields["Len"])+str(self.fields["SPID"])+str(self.fields["PacketID"])+str(self.fields["Window"])+str(self.fields["TokenType"])+str(self.fields["VersionOffset"])+str(self.fields["VersionLen"])+str(self.fields["TokenType1"])+str(self.fields["EncryptionOffset"])+str(self.fields["EncryptionLen"])+str(self.fields["TokenType2"])+str(self.fields["InstOptOffset"])+str(self.fields["InstOptLen"])+str(self.fields["TokenTypeThrdID"])+str(self.fields["ThrdIDOffset"])+str(self.fields["ThrdIDLen"])+str(self.fields["ThrdIDTerminator"])+str(self.fields["VersionStr"])+str(self.fields["SubBuild"])+str(self.fields["EncryptionStr"])+str(self.fields["InstOptStr"]) VersionOffset = str(self.fields["TokenType"])+str(self.fields["VersionOffset"])+str(self.fields["VersionLen"])+str(self.fields["TokenType1"])+str(self.fields["EncryptionOffset"])+str(self.fields["EncryptionLen"])+str(self.fields["TokenType2"])+str(self.fields["InstOptOffset"])+str(self.fields["InstOptLen"])+str(self.fields["TokenTypeThrdID"])+str(self.fields["ThrdIDOffset"])+str(self.fields["ThrdIDLen"])+str(self.fields["ThrdIDTerminator"]) EncryptionOffset = VersionOffset+str(self.fields["VersionStr"])+str(self.fields["SubBuild"]) InstOpOffset = EncryptionOffset+str(self.fields["EncryptionStr"]) ThrdIDOffset = InstOpOffset+str(self.fields["InstOptStr"]) self.fields["Len"] = StructWithLenPython2or3(">h",len(CalculateCompletePacket)) #Version self.fields["VersionLen"] = StructWithLenPython2or3(">h",len(self.fields["VersionStr"]+self.fields["SubBuild"])) self.fields["VersionOffset"] = StructWithLenPython2or3(">h",len(VersionOffset)) #Encryption self.fields["EncryptionLen"] = StructWithLenPython2or3(">h",len(self.fields["EncryptionStr"])) self.fields["EncryptionOffset"] = StructWithLenPython2or3(">h",len(EncryptionOffset)) #InstOpt self.fields["InstOptLen"] = StructWithLenPython2or3(">h",len(self.fields["InstOptStr"])) self.fields["EncryptionOffset"] = StructWithLenPython2or3(">h",len(InstOpOffset)) #ThrdIDOffset self.fields["ThrdIDOffset"] = StructWithLenPython2or3(">h",len(ThrdIDOffset)) class MSSQLNTLMChallengeAnswer(Packet): fields = OrderedDict([ ("PacketType", "\x04"), ("Status", "\x01"), ("Len", "\x00\xc7"), ("SPID", "\x00\x00"), ("PacketID", "\x01"), ("Window", "\x00"), ("TokenType", "\xed"), ("SSPIBuffLen", "\xbc\x00"), ("Signature", "NTLMSSP"), ("SignatureNull", "\x00"), ("MessageType", "\x02\x00\x00\x00"), ("TargetNameLen", "\x06\x00"), ("TargetNameMaxLen", "\x06\x00"), ("TargetNameOffset", "\x38\x00\x00\x00"), ("NegoFlags", "\x05\x02\x89\xa2"), ("ServerChallenge", ""), ("Reserved", "\x00\x00\x00\x00\x00\x00\x00\x00"), ("TargetInfoLen", "\x7e\x00"), ("TargetInfoMaxLen", "\x7e\x00"), ("TargetInfoOffset", "\x3e\x00\x00\x00"), ("NTLMOsVersion", "\x0a\x00\x7c\x4f\x00\x00\x00\x0f"), ("TargetNameStr", settings.Config.Domain), ("Av1", "\x02\x00"),#nbt name ("Av1Len", "\x06\x00"), ("Av1Str", settings.Config.Domain), ("Av2", "\x01\x00"),#Server name ("Av2Len", "\x14\x00"), ("Av2Str", settings.Config.MachineName), ("Av3", "\x04\x00"),#Full Domain name ("Av3Len", "\x12\x00"), ("Av3Str", settings.Config.DomainName), ("Av4", "\x03\x00"),#Full machine domain name ("Av4Len", "\x28\x00"), ("Av4Str", settings.Config.MachineName+'.'+settings.Config.DomainName), ("Av5", "\x05\x00"),#Domain Forest Name ("Av5Len", "\x12\x00"), ("Av5Str", settings.Config.DomainName), ("Av6", "\x00\x00"),#AvPairs Terminator ("Av6Len", "\x00\x00"), ]) def calculate(self): # First convert to unicode self.fields["TargetNameStr"] = self.fields["TargetNameStr"].encode('utf-16le').decode('latin-1') self.fields["Av1Str"] = self.fields["Av1Str"].encode('utf-16le').decode('latin-1') self.fields["Av2Str"] = self.fields["Av2Str"].encode('utf-16le').decode('latin-1') self.fields["Av3Str"] = self.fields["Av3Str"].encode('utf-16le').decode('latin-1') self.fields["Av4Str"] = self.fields["Av4Str"].encode('utf-16le').decode('latin-1') self.fields["Av5Str"] = self.fields["Av5Str"].encode('utf-16le').decode('latin-1') # Then calculate CalculateCompletePacket = str(self.fields["PacketType"])+str(self.fields["Status"])+str(self.fields["Len"])+str(self.fields["SPID"])+str(self.fields["PacketID"])+str(self.fields["Window"])+str(self.fields["TokenType"])+str(self.fields["SSPIBuffLen"])+str(self.fields["Signature"])+str(self.fields["SignatureNull"])+str(self.fields["MessageType"])+str(self.fields["TargetNameLen"])+str(self.fields["TargetNameMaxLen"])+str(self.fields["TargetNameOffset"])+str(self.fields["NegoFlags"])+str(self.fields["ServerChallenge"])+str(self.fields["Reserved"])+str(self.fields["TargetInfoLen"])+str(self.fields["TargetInfoMaxLen"])+str(self.fields["TargetInfoOffset"])+str(self.fields["NTLMOsVersion"])+str(self.fields["TargetNameStr"])+str(self.fields["Av1"])+str(self.fields["Av1Len"])+str(self.fields["Av1Str"])+str(self.fields["Av2"])+str(self.fields["Av2Len"])+str(self.fields["Av2Str"])+str(self.fields["Av3"])+str(self.fields["Av3Len"])+str(self.fields["Av3Str"])+str(self.fields["Av4"])+str(self.fields["Av4Len"])+str(self.fields["Av4Str"])+str(self.fields["Av5"])+str(self.fields["Av5Len"])+str(self.fields["Av5Str"])+str(self.fields["Av6"])+str(self.fields["Av6Len"]) CalculateSSPI = str(self.fields["Signature"])+str(self.fields["SignatureNull"])+str(self.fields["MessageType"])+str(self.fields["TargetNameLen"])+str(self.fields["TargetNameMaxLen"])+str(self.fields["TargetNameOffset"])+str(self.fields["NegoFlags"])+str(self.fields["ServerChallenge"])+str(self.fields["Reserved"])+str(self.fields["TargetInfoLen"])+str(self.fields["TargetInfoMaxLen"])+str(self.fields["TargetInfoOffset"])+str(self.fields["NTLMOsVersion"])+str(self.fields["TargetNameStr"])+str(self.fields["Av1"])+str(self.fields["Av1Len"])+str(self.fields["Av1Str"])+str(self.fields["Av2"])+str(self.fields["Av2Len"])+str(self.fields["Av2Str"])+str(self.fields["Av3"])+str(self.fields["Av3Len"])+str(self.fields["Av3Str"])+str(self.fields["Av4"])+str(self.fields["Av4Len"])+str(self.fields["Av4Str"])+str(self.fields["Av5"])+str(self.fields["Av5Len"])+str(self.fields["Av5Str"])+str(self.fields["Av6"])+str(self.fields["Av6Len"]) CalculateNameOffset = str(self.fields["Signature"])+str(self.fields["SignatureNull"])+str(self.fields["MessageType"])+str(self.fields["TargetNameLen"])+str(self.fields["TargetNameMaxLen"])+str(self.fields["TargetNameOffset"])+str(self.fields["NegoFlags"])+str(self.fields["ServerChallenge"])+str(self.fields["Reserved"])+str(self.fields["TargetInfoLen"])+str(self.fields["TargetInfoMaxLen"])+str(self.fields["TargetInfoOffset"])+str(self.fields["NTLMOsVersion"]) CalculateAvPairsOffset = CalculateNameOffset+str(self.fields["TargetNameStr"]) CalculateAvPairsLen = str(self.fields["Av1"])+str(self.fields["Av1Len"])+str(self.fields["Av1Str"])+str(self.fields["Av2"])+str(self.fields["Av2Len"])+str(self.fields["Av2Str"])+str(self.fields["Av3"])+str(self.fields["Av3Len"])+str(self.fields["Av3Str"])+str(self.fields["Av4"])+str(self.fields["Av4Len"])+str(self.fields["Av4Str"])+str(self.fields["Av5"])+str(self.fields["Av5Len"])+str(self.fields["Av5Str"])+str(self.fields["Av6"])+str(self.fields["Av6Len"]) self.fields["Len"] = StructWithLenPython2or3(">h",len(CalculateCompletePacket)) self.fields["SSPIBuffLen"] = StructWithLenPython2or3("i", len(CalculatePacketLen)) self.fields["OpHeadASNIDLen"] = StructWithLenPython2or3(">i", len(OperationPacketLen)) self.fields["SequenceHeaderLen"] = StructWithLenPython2or3(">B", len(NTLMMessageLen)) ##### Workstation Offset Calculation: self.fields["NTLMSSPNtWorkstationBuffOffset"] = StructWithLenPython2or3("B", len(CalculateNetlogonLen)) self.fields["NetAttribLen"] = StructWithLenPython2or3(">L", len(CalculateNetlogonLen)+2) self.fields["PartAttribHeadLen"] = StructWithLenPython2or3(">L", len(CalculateNetlogonLen)+18) self.fields["SequenceHeaderLen"] = StructWithLenPython2or3(">L", len(CalculateNetlogonLen)+24) self.fields["OpHeadASNIDLen"] = StructWithLenPython2or3(">L", len(CalculateNetlogonLen)+32) self.fields["ParserHeadASNLen"] = StructWithLenPython2or3(">L", len(CalculateNetlogonLen)+42) ###### self.fields["ClientSiteNamePtrOffset"] = StructWithLenPython2or3(">B", len(CalculateNetlogonOffset)-1) ##### SMB Packets ##### class SMBHeader(Packet): fields = OrderedDict([ ("proto", "\xff\x53\x4d\x42"), ("cmd", "\x72"), ("errorcode", "\x00\x00\x00\x00"), ("flag1", "\x00"), ("flag2", "\x00\x00"), ("pidhigh", "\x00\x00"), ("signature", "\x00\x00\x00\x00\x00\x00\x00\x00"), ("reserved", "\x00\x00"), ("tid", "\x00\x00"), ("pid", "\x00\x00"), ("uid", "\x00\x00"), ("mid", "\x00\x00"), ]) class SMBNego(Packet): fields = OrderedDict([ ("wordcount", "\x00"), ("bcc", "\x62\x00"), ("data", "") ]) def calculate(self): self.fields["bcc"] = StructPython2or3("B", len(AsnLen+CalculateSecBlob)-3) self.fields["NegTokenTagASNIdLen"] = StructWithLenPython2or3(">B", len(AsnLen+CalculateSecBlob)-6) self.fields["Tag1ASNIdLen"] = StructWithLenPython2or3(">B", len(str(self.fields["Tag1ASNId2"])+str(self.fields["Tag1ASNId2Len"])+str(self.fields["Tag1ASNId2Str"]))) self.fields["Tag1ASNId2Len"] = StructWithLenPython2or3(">B", len(str(self.fields["Tag1ASNId2Str"]))) self.fields["Tag2ASNIdLen"] = StructWithLenPython2or3(">B", len(CalculateSecBlob+str(self.fields["Tag3ASNId"])+str(self.fields["Tag3ASNIdLenOfLen"])+str(self.fields["Tag3ASNIdLen"]))) self.fields["Tag3ASNIdLen"] = StructWithLenPython2or3(">B", len(CalculateSecBlob)) ###### Andxoffset calculation. CalculateCompletePacket = str(self.fields["Wordcount"])+str(self.fields["AndXCommand"])+str(self.fields["Reserved"])+str(self.fields["Andxoffset"])+str(self.fields["Action"])+str(self.fields["SecBlobLen"])+str(self.fields["Bcc"])+BccLen self.fields["Andxoffset"] = StructWithLenPython2or3(" 255: self.fields["Tag3ASNIdLen"] = StructWithLenPython2or3(">H", len(CalculateSecBlob)) else: self.fields["Tag3ASNIdLenOfLen"] = "\x81" self.fields["Tag3ASNIdLen"] = StructWithLenPython2or3(">B", len(CalculateSecBlob)) if len(AsnLen+CalculateSecBlob)-3 > 255: self.fields["ChoiceTagASNIdLen"] = StructWithLenPython2or3(">H", len(AsnLen+CalculateSecBlob)-4) else: self.fields["ChoiceTagASNLenOfLen"] = "\x81" self.fields["ChoiceTagASNIdLen"] = StructWithLenPython2or3(">B", len(AsnLen+CalculateSecBlob)-3) if len(AsnLen+CalculateSecBlob)-7 > 255: self.fields["NegTokenTagASNIdLen"] = StructWithLenPython2or3(">H", len(AsnLen+CalculateSecBlob)-8) else: self.fields["NegTokenTagASNLenOfLen"] = "\x81" self.fields["NegTokenTagASNIdLen"] = StructWithLenPython2or3(">B", len(AsnLen+CalculateSecBlob)-7) tag2length = CalculateSecBlob+str(self.fields["Tag3ASNId"])+str(self.fields["Tag3ASNIdLenOfLen"])+str(self.fields["Tag3ASNIdLen"]) if len(tag2length) > 255: self.fields["Tag2ASNIdLen"] = StructWithLenPython2or3(">H", len(tag2length)) else: self.fields["Tag2ASNIdLenOfLen"] = "\x81" self.fields["Tag2ASNIdLen"] = StructWithLenPython2or3(">B", len(tag2length)) self.fields["Tag1ASNIdLen"] = StructWithLenPython2or3(">B", len(str(self.fields["Tag1ASNId2"])+str(self.fields["Tag1ASNId2Len"])+str(self.fields["Tag1ASNId2Str"]))) self.fields["Tag1ASNId2Len"] = StructWithLenPython2or3(">B", len(str(self.fields["Tag1ASNId2Str"]))) ###### Workstation Offset CalculateOffsetWorkstation = str(self.fields["NTLMSSPSignature"])+str(self.fields["NTLMSSPSignatureNull"])+str(self.fields["NTLMSSPMessageType"])+str(self.fields["NTLMSSPNtWorkstationLen"])+str(self.fields["NTLMSSPNtWorkstationMaxLen"])+str(self.fields["NTLMSSPNtWorkstationBuffOffset"])+str(self.fields["NTLMSSPNtNegotiateFlags"])+str(self.fields["NTLMSSPNtServerChallenge"])+str(self.fields["NTLMSSPNtReserved"])+str(self.fields["NTLMSSPNtTargetInfoLen"])+str(self.fields["NTLMSSPNtTargetInfoMaxLen"])+str(self.fields["NTLMSSPNtTargetInfoBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"]) ###### AvPairs Offset CalculateLenAvpairs = str(self.fields["NTLMSSPNTLMChallengeAVPairsId"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsLen"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs2Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs3Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs5Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs7Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs7Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs7UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs6Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs6Len"]) ##### Workstation Offset Calculation: self.fields["NTLMSSPNtWorkstationBuffOffset"] = StructWithLenPython2or3("h",len(str(self.fields["Data"]))+4)#Data+own header. class X224(Packet): fields = OrderedDict([ ("Length", "\x0e"), ("Cmd", "\xd0"), ("Dstref", "\x00\x00"), ("Srcref", "\x12\x34"), ("Class", "\x00"), ("Data", "") ]) def calculate(self): self.fields["Length"] = StructWithLenPython2or3(">B",len(str(self.fields["Data"]))+6) class RDPNEGOAnswer(Packet): fields = OrderedDict([ ("Cmd", "\x02"), ("Flags", "\x00"), ("Length", "\x08\x00"), ("SelectedProto", "\x02\x00\x00\x00"),#CredSSP ]) def calculate(self): self.fields["Length"] = StructWithLenPython2or3("B ("PacketStartASNTag0", "\xa0"), ("PacketStartASNTag0Len", "\x03"), #Static for TSVersion ("PacketStartASNTag0Len2", "\x02"), ("PacketStartASNTag0Len3", "\x01"), ("PacketStartASNTag0CredSSPVersion", "\x05"),##TSVersion: Since padding oracle, v2,v3,v4 are rejected by win7.. ("ParserHeadASNID1", "\xa1"), ("ParserHeadASNLenOfLen1", "\x81"), ("ParserHeadASNLen1", "\xfa"), ("MessageIDASNID", "\x30"), ("MessageIDASNLen", "\x81"), ("MessageIDASNLen2", "\xf7"), ("OpHeadASNID", "\x30"), ("OpHeadASNIDLenOfLen", "\x81"), ("OpHeadASNIDLen", "\xf4"), ("StatusASNID", "\xa0"), ("MatchedDN", "\x81"), ("ASNLen01", "\xf1"), ("SequenceHeader", "\x04"), ("SequenceHeaderLenOfLen", "\x81"), ("SequenceHeaderLen", "\xee"), ####### ("NTLMSSPSignature", "NTLMSSP"), ("NTLMSSPSignatureNull", "\x00"), ("NTLMSSPMessageType", "\x02\x00\x00\x00"), ("NTLMSSPNtWorkstationLen", "\x1e\x00"), ("NTLMSSPNtWorkstationMaxLen", "\x1e\x00"), ("NTLMSSPNtWorkstationBuffOffset", "\x38\x00\x00\x00"), ("NTLMSSPNtNegotiateFlags", "\x15\x82\x8a\xe2"), ("NTLMSSPNtServerChallenge", "\x81\x22\x33\x34\x55\x46\xe7\x88"), ("NTLMSSPNtReserved", "\x00\x00\x00\x00\x00\x00\x00\x00"), ("NTLMSSPNtTargetInfoLen", "\x94\x00"), ("NTLMSSPNtTargetInfoMaxLen", "\x94\x00"), ("NTLMSSPNtTargetInfoBuffOffset", "\x56\x00\x00\x00"), ("NegTokenInitSeqMechMessageVersionHigh", "\x05"), ("NegTokenInitSeqMechMessageVersionLow", "\x02"), ("NegTokenInitSeqMechMessageVersionBuilt", "\xce\x0e"), ("NegTokenInitSeqMechMessageVersionReserved", "\x00\x00\x00"), ("NegTokenInitSeqMechMessageVersionNTLMType", "\x0f"), ("NTLMSSPNtWorkstationName", settings.Config.Domain), ("NTLMSSPNTLMChallengeAVPairsId", "\x02\x00"), ("NTLMSSPNTLMChallengeAVPairsLen", "\x0a\x00"), ("NTLMSSPNTLMChallengeAVPairsUnicodeStr", settings.Config.Domain), ("NTLMSSPNTLMChallengeAVPairs1Id", "\x01\x00"), ("NTLMSSPNTLMChallengeAVPairs1Len", "\x1e\x00"), ("NTLMSSPNTLMChallengeAVPairs1UnicodeStr", settings.Config.MachineName), ("NTLMSSPNTLMChallengeAVPairs2Id", "\x04\x00"), ("NTLMSSPNTLMChallengeAVPairs2Len", "\x1e\x00"), ("NTLMSSPNTLMChallengeAVPairs2UnicodeStr", settings.Config.MachineName+'.'+settings.Config.DomainName), ("NTLMSSPNTLMChallengeAVPairs3Id", "\x03\x00"), ("NTLMSSPNTLMChallengeAVPairs3Len", "\x1e\x00"), ("NTLMSSPNTLMChallengeAVPairs3UnicodeStr", settings.Config.DomainName), ("NTLMSSPNTLMChallengeAVPairs5Id", "\x05\x00"), ("NTLMSSPNTLMChallengeAVPairs5Len", "\x04\x00"), ("NTLMSSPNTLMChallengeAVPairs5UnicodeStr", settings.Config.DomainName), ("NTLMSSPNTLMChallengeAVPairs6Id", "\x00\x00"), ("NTLMSSPNTLMChallengeAVPairs6Len", "\x00\x00"), ]) def calculate(self): ###### Convert strings to Unicode first self.fields["NTLMSSPNtWorkstationName"] = self.fields["NTLMSSPNtWorkstationName"].encode('utf-16le').decode('latin-1') self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"].encode('utf-16le').decode('latin-1') self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"].encode('utf-16le').decode('latin-1') self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"].encode('utf-16le').decode('latin-1') self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"].encode('utf-16le').decode('latin-1') self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"].encode('utf-16le').decode('latin-1') ###### Workstation Offset CalculateOffsetWorkstation = str(self.fields["NTLMSSPSignature"])+str(self.fields["NTLMSSPSignatureNull"])+str(self.fields["NTLMSSPMessageType"])+str(self.fields["NTLMSSPNtWorkstationLen"])+str(self.fields["NTLMSSPNtWorkstationMaxLen"])+str(self.fields["NTLMSSPNtWorkstationBuffOffset"])+str(self.fields["NTLMSSPNtNegotiateFlags"])+str(self.fields["NTLMSSPNtServerChallenge"])+str(self.fields["NTLMSSPNtReserved"])+str(self.fields["NTLMSSPNtTargetInfoLen"])+str(self.fields["NTLMSSPNtTargetInfoMaxLen"])+str(self.fields["NTLMSSPNtTargetInfoBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"]) ###### AvPairs Offset CalculateLenAvpairs = str(self.fields["NTLMSSPNTLMChallengeAVPairsId"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsLen"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs2Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs3Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs5Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs6Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs6Len"]) ###### RDP Packet Len NTLMMessageLen = CalculateOffsetWorkstation+str(self.fields["NTLMSSPNtWorkstationName"])+CalculateLenAvpairs ##### RDP Len Calculation: self.fields["SequenceHeaderLen"] = StructWithLenPython2or3(">B", len(NTLMMessageLen)) self.fields["ASNLen01"] = StructWithLenPython2or3(">B", len(NTLMMessageLen)+3) self.fields["OpHeadASNIDLen"] = StructWithLenPython2or3(">B", len(NTLMMessageLen)+6) self.fields["MessageIDASNLen2"] = StructWithLenPython2or3(">B", len(NTLMMessageLen)+9) self.fields["ParserHeadASNLen1"] = StructWithLenPython2or3(">B", len(NTLMMessageLen)+12) self.fields["PacketStartASNStr"] = StructWithLenPython2or3(">B", len(NTLMMessageLen)+20) ##### Workstation Offset Calculation: self.fields["NTLMSSPNtWorkstationBuffOffset"] = StructWithLenPython2or3("H", self.fields["TowerPortNumberStr"]) self.fields["TowerIPAddressStr"] = RespondWithIPAton() Data= str(self.fields["TowerTotalLen"])+str(self.fields["Tower1Len"])+str(self.fields["Tower1FloorsCount"])+str(self.fields["Tower1ByteCount"])+str(self.fields["Tower1IntUID"])+str(self.fields["Tower1UID"])+str(self.fields["Tower1Version"])+str(self.fields["Tower1VersionMinBC"])+str(self.fields["Tower1VersionMinimum"])+str(self.fields["Tower2ByteCount"])+str(self.fields["Tower2IntUID"])+str(self.fields["Tower2UID"])+str(self.fields["Tower2Version"])+str(self.fields["Tower2VersionMinBC"])+str(self.fields["Tower2VersionMinimum"])+str(self.fields["TowerRpcByteCount"])+str(self.fields["TowerRpctIdentifier"])+str(self.fields["TowerRpcByteCount2"])+str(self.fields["TowerRpcMinimum"])+str(self.fields["TowerPortNumberBC"])+str(self.fields["TowerPortNumberOpcode"])+str(self.fields["TowerPortNumberBC2"])+str(self.fields["TowerPortNumberStr"])+str(self.fields["TowerIPAddressBC"])+str(self.fields["TowerIPAddressOpcode"])+str(self.fields["TowerIPAddressBC2"])+str(self.fields["TowerIPAddressStr"]) self.fields["Data"] = Data class NTLMChallenge(Packet): fields = OrderedDict([ ("NTLMSSPSignature", "NTLMSSP"), ("NTLMSSPSignatureNull", "\x00"), ("NTLMSSPMessageType", "\x02\x00\x00\x00"), ("NTLMSSPNtWorkstationLen", "\x1e\x00"), ("NTLMSSPNtWorkstationMaxLen", "\x1e\x00"), ("NTLMSSPNtWorkstationBuffOffset", "\x38\x00\x00\x00"), ("NTLMSSPNtNegotiateFlags", "\x15\x82\x8a\xe2"), ("NTLMSSPNtServerChallenge", "\x81\x22\x33\x34\x55\x46\xe7\x88"), ("NTLMSSPNtReserved", "\x00\x00\x00\x00\x00\x00\x00\x00"), ("NTLMSSPNtTargetInfoLen", "\x94\x00"), ("NTLMSSPNtTargetInfoMaxLen", "\x94\x00"), ("NTLMSSPNtTargetInfoBuffOffset", "\x56\x00\x00\x00"), ("NegTokenInitSeqMechMessageVersionHigh", "\x05"), ("NegTokenInitSeqMechMessageVersionLow", "\x02"), ("NegTokenInitSeqMechMessageVersionBuilt", "\xce\x0e"), ("NegTokenInitSeqMechMessageVersionReserved", "\x00\x00\x00"), ("NegTokenInitSeqMechMessageVersionNTLMType", "\x0f"), ("NTLMSSPNtWorkstationName", settings.Config.Domain), ("NTLMSSPNTLMChallengeAVPairsId", "\x02\x00"), ("NTLMSSPNTLMChallengeAVPairsLen", "\x0a\x00"), ("NTLMSSPNTLMChallengeAVPairsUnicodeStr", settings.Config.Domain), ("NTLMSSPNTLMChallengeAVPairs1Id", "\x01\x00"), ("NTLMSSPNTLMChallengeAVPairs1Len", "\x1e\x00"), ("NTLMSSPNTLMChallengeAVPairs1UnicodeStr", settings.Config.MachineName), ("NTLMSSPNTLMChallengeAVPairs2Id", "\x04\x00"), ("NTLMSSPNTLMChallengeAVPairs2Len", "\x1e\x00"), ("NTLMSSPNTLMChallengeAVPairs2UnicodeStr", settings.Config.MachineName+'.'+settings.Config.DomainName), ("NTLMSSPNTLMChallengeAVPairs3Id", "\x03\x00"), ("NTLMSSPNTLMChallengeAVPairs3Len", "\x1e\x00"), ("NTLMSSPNTLMChallengeAVPairs3UnicodeStr", settings.Config.DomainName), ("NTLMSSPNTLMChallengeAVPairs5Id", "\x05\x00"), ("NTLMSSPNTLMChallengeAVPairs5Len", "\x04\x00"), ("NTLMSSPNTLMChallengeAVPairs5UnicodeStr", settings.Config.DomainName), ("NTLMSSPNTLMChallengeAVPairs6Id", "\x00\x00"), ("NTLMSSPNTLMChallengeAVPairs6Len", "\x00\x00"), ]) def calculate(self): ###### Convert strings to Unicode first self.fields["NTLMSSPNtWorkstationName"] = self.fields["NTLMSSPNtWorkstationName"].encode('utf-16le').decode('latin-1') self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"].encode('utf-16le').decode('latin-1') self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"].encode('utf-16le').decode('latin-1') self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"].encode('utf-16le').decode('latin-1') self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"].encode('utf-16le').decode('latin-1') self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"].encode('utf-16le').decode('latin-1') ###### Workstation Offset CalculateOffsetWorkstation = str(self.fields["NTLMSSPSignature"])+str(self.fields["NTLMSSPSignatureNull"])+str(self.fields["NTLMSSPMessageType"])+str(self.fields["NTLMSSPNtWorkstationLen"])+str(self.fields["NTLMSSPNtWorkstationMaxLen"])+str(self.fields["NTLMSSPNtWorkstationBuffOffset"])+str(self.fields["NTLMSSPNtNegotiateFlags"])+str(self.fields["NTLMSSPNtServerChallenge"])+str(self.fields["NTLMSSPNtReserved"])+str(self.fields["NTLMSSPNtTargetInfoLen"])+str(self.fields["NTLMSSPNtTargetInfoMaxLen"])+str(self.fields["NTLMSSPNtTargetInfoBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"]) ###### AvPairs Offset CalculateLenAvpairs = str(self.fields["NTLMSSPNTLMChallengeAVPairsId"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsLen"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs2Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs3Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs5Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs6Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs6Len"]) ##### Workstation Offset Calculation: self.fields["NTLMSSPNtWorkstationBuffOffset"] = StructWithLenPython2or3("h",len(DataGramLen)) class SMBTransMailslot(Packet): fields = OrderedDict([ ("Wordcount", "\x11"), ("TotalParamCount", "\x00\x00"), ("TotalDataCount", "\x00\x00"), ("MaxParamCount", "\x02\x00"), ("MaxDataCount", "\x00\x00"), ("MaxSetupCount", "\x00"), ("Reserved", "\x00"), ("Flags", "\x00\x00"), ("Timeout", "\xff\xff\xff\xff"), ("Reserved2", "\x00\x00"), ("ParamCount", "\x00\x00"), ("ParamOffset", "\x00\x00"), ("DataCount", "\x00\x00"), ("DataOffset", "\x00\x00"), ("SetupCount", "\x03"), ("Reserved3", "\x00"), ("Opcode", "\x01\x00"), ("Priority", "\x00\x00"), ("Class", "\x02\x00"), ("Bcc", "\x00\x00"), ("MailSlot", "\\MAILSLOT\\NET\\NETLOGON"), ("MailSlotNull", "\x00"), ("Padding", "\x00\x00\x00"), ("Data", ""), ]) def calculate(self): #Padding if len(str(self.fields["Data"]))%2==0: self.fields["Padding"] = "\x00\x00\x00\x00" else: self.fields["Padding"] = "\x00\x00\x00" BccLen = str(self.fields["MailSlot"])+str(self.fields["MailSlotNull"])+str(self.fields["Padding"])+str(self.fields["Data"]) PacketOffsetLen = str(self.fields["Wordcount"])+str(self.fields["TotalParamCount"])+str(self.fields["TotalDataCount"])+str(self.fields["MaxParamCount"])+str(self.fields["MaxDataCount"])+str(self.fields["MaxSetupCount"])+str(self.fields["Reserved"])+str(self.fields["Flags"])+str(self.fields["Timeout"])+str(self.fields["Reserved2"])+str(self.fields["ParamCount"])+str(self.fields["ParamOffset"])+str(self.fields["DataCount"])+str(self.fields["DataOffset"])+str(self.fields["SetupCount"])+str(self.fields["Reserved3"])+str(self.fields["Opcode"])+str(self.fields["Priority"])+str(self.fields["Class"])+str(self.fields["Bcc"])+str(self.fields["MailSlot"])+str(self.fields["MailSlotNull"])+str(self.fields["Padding"]) self.fields["DataCount"] = StructWithLenPython2or3("