import socket import threading import struct import logging import string from SocketServer import UDPServer, ThreadingMixIn, BaseRequestHandler from core.responder.fingerprinter.RAPLANMANPackets import * mitmf_logger = logging.getLogger("mitmf") class LANFingerprinter(): def start(self, options): global args; args = options #For now a quick hack to make argparse's namespace object available to all try: mitmf_logger.debug("[LANFingerprinter] online") server = ThreadingUDPServer(("0.0.0.0", 138), Browser) t = threading.Thread(name="LANFingerprinter", target=server.serve_forever) t.setDaemon(True) t.start() except Exception, e: mitmf_logger.error("[LANFingerprinter] Error starting on port 138: {}:".format(e)) class ThreadingUDPServer(ThreadingMixIn, UDPServer): allow_reuse_address = 1 def server_bind(self): UDPServer.server_bind(self) class Browser(BaseRequestHandler): def handle(self): try: request, socket = self.request if args.analyze: ParseDatagramNBTNames(request,self.client_address[0]) BecomeBackup(request,self.client_address[0]) BecomeBackup(request,self.client_address[0]) except Exception: pass def NBT_NS_Role(data): Role = { "\x41\x41\x00":"Workstation/Redirector Service.", "\x42\x4c\x00":"Domain Master Browser. This name is likely a domain controller or a homegroup.)", "\x42\x4d\x00":"Domain controller service. This name is a domain controller.", "\x42\x4e\x00":"Local Master Browser.", "\x42\x4f\x00":"Browser Election Service.", "\x43\x41\x00":"File Server Service.", "\x41\x42\x00":"Browser Service.", } if data in Role: return Role[data] else: return "Service not known." def Decode_Name(nbname): #From http://code.google.com/p/dpkt/ with author's permission. try: if len(nbname) != 32: return nbname l = [] for i in range(0, 32, 2): l.append(chr(((ord(nbname[i]) - 0x41) << 4) | ((ord(nbname[i+1]) - 0x41) & 0xf))) return filter(lambda x: x in string.printable, ''.join(l).split('\x00', 1)[0].replace(' ', '')) except Exception, e: mitmf_logger.debug("[LANFingerprinter] Error parsing NetBIOS name: {}".format(e)) return "Illegal NetBIOS name" def WorkstationFingerPrint(data): Role = { "\x04\x00" :"Windows 95", "\x04\x10" :"Windows 98", "\x04\x90" :"Windows ME", "\x05\x00" :"Windows 2000", "\x05\x00" :"Windows XP", "\x05\x02" :"Windows 2003", "\x06\x00" :"Windows Vista/Server 2008", "\x06\x01" :"Windows 7/Server 2008R2", } if data in Role: return Role[data] else: return False def PrintServerName(data, entries): if entries == 0: pass else: entrieslen = 26*entries chunks, chunk_size = len(data[:entrieslen]), entrieslen/entries ServerName = [data[i:i+chunk_size] for i in range(0, chunks, chunk_size) ] l =[] for x in ServerName: if WorkstationFingerPrint(x[16:18]): l.append(x[:16].replace('\x00', '')+'| OS:%s'%(WorkstationFingerPrint(x[16:18]))) else: l.append(x[:16].replace('\x00', '')) return l def ParsePacket(Payload): PayloadOffset = struct.unpack('