#! /usr/bin/env python # NBT-NS/LLMNR Responder # Created by Laurent Gaffie # Copyright (C) 2014 Trustwave Holdings, Inc. # # 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 from odict import OrderedDict 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())) #Calculate total SMB packet len. def longueur(payload): length = struct.pack(">i", len(''.join(payload))) return length #Set MID SMB Header field. def midcalc(data): pack=data[34:36] return pack #Set UID SMB Header field. def uidcalc(data): pack=data[32:34] return pack #Set PID SMB Header field. def pidcalc(data): pack=data[30:32] return pack #Set TID SMB Header field. def tidcalc(data): pack=data[28:30] return pack ################################################################################## 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"), ]) ################################################################################## #SMB Negotiate Answer LM packet. class SMBNegoAnsLM(Packet): fields = OrderedDict([ ("Wordcount", "\x11"), ("Dialect", ""), ("Securitymode", "\x03"), ("MaxMpx", "\x32\x00"), ("MaxVc", "\x01\x00"), ("Maxbuffsize", "\x04\x41\x00\x00"), ("Maxrawbuff", "\x00\x00\x01\x00"), ("Sessionkey", "\x00\x00\x00\x00"), ("Capabilities", "\xfc\x3e\x01\x00"), ("Systemtime", "\x84\xd6\xfb\xa3\x01\x35\xcd\x01"), ("Srvtimezone", "\x2c\x01"), ("Keylength", "\x08"), ("Bcc", "\x10\x00"), ("Key", ""), ("Domain", "SMB"), ("DomainNull", "\x00\x00"), ("Server", "SMB-TOOLKIT"), ("ServerNull", "\x00\x00"), ]) def calculate(self): ##Convert first.. self.fields["Domain"] = self.fields["Domain"].encode('utf-16le') self.fields["Server"] = self.fields["Server"].encode('utf-16le') ##Then calculate. CompleteBCCLen = str(self.fields["Key"])+str(self.fields["Domain"])+str(self.fields["DomainNull"])+str(self.fields["Server"])+str(self.fields["ServerNull"]) self.fields["Bcc"] = struct.pack("B", len(AsnLen+CalculateSecBlob)-3) self.fields["NegTokenTagASNIdLen"] = struct.pack(">B", len(AsnLen+CalculateSecBlob)-6) self.fields["Tag1ASNIdLen"] = struct.pack(">B", len(str(self.fields["Tag1ASNId2"])+str(self.fields["Tag1ASNId2Len"])+str(self.fields["Tag1ASNId2Str"]))) self.fields["Tag1ASNId2Len"] = struct.pack(">B", len(str(self.fields["Tag1ASNId2Str"]))) self.fields["Tag2ASNIdLen"] = struct.pack(">B", len(CalculateSecBlob+str(self.fields["Tag3ASNId"])+str(self.fields["Tag3ASNIdLenOfLen"])+str(self.fields["Tag3ASNIdLen"]))) self.fields["Tag3ASNIdLen"] = struct.pack(">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"] = struct.pack("