mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-08-19 21:13:26 -07:00
responder integration complete
This commit is contained in:
parent
4fdf3e6c8b
commit
32bd4b64e4
18 changed files with 273 additions and 164 deletions
|
@ -16,38 +16,55 @@
|
|||
# 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 sys
|
||||
import struct
|
||||
import SocketServer
|
||||
import re
|
||||
import socket
|
||||
import thread
|
||||
import libs.responder.Fingerprint
|
||||
import random
|
||||
import os
|
||||
import ConfigParser
|
||||
import BaseHTTPServer
|
||||
import select
|
||||
import urlparse
|
||||
import zlib
|
||||
import string
|
||||
import logging
|
||||
import time
|
||||
from OpenSSL import SSL
|
||||
import sys,struct,SocketServer,re,socket,thread,Fingerprint,random,os,ConfigParser,BaseHTTPServer, select,urlparse,zlib, string, time
|
||||
from SocketServer import TCPServer, UDPServer, ThreadingMixIn, StreamRequestHandler, BaseRequestHandler,BaseServer
|
||||
from libs.responder.Fingerprint import RunSmbFinger, OsNameClientVersion
|
||||
from libs.responder.odict import OrderedDict
|
||||
from libs.responder.RAPLANMANPackets import *
|
||||
from libs.responder.SMBPackets import *
|
||||
from libs.responder.SQLPackets import *
|
||||
from libs.responder.HTTPPackets import *
|
||||
from libs.responder.HTTPProxy import *
|
||||
from libs.responder.LDAPPackets import *
|
||||
from libs.responder.SMTPPackets import *
|
||||
from libs.responder.IMAPPackets import *
|
||||
from Fingerprint import RunSmbFinger,OsNameClientVersion
|
||||
from odict import OrderedDict
|
||||
from socket import inet_aton
|
||||
from random import randrange
|
||||
|
||||
VERSION = '2.1.2'
|
||||
|
||||
#Config parsing
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read("./config/responder.conf")
|
||||
|
||||
# Set some vars.
|
||||
On_Off = config.get('Responder Core', 'HTTP').upper()
|
||||
SSL_On_Off = config.get('Responder Core', 'HTTPS').upper()
|
||||
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()
|
||||
IMAP_On_Off = config.get('Responder Core', 'IMAP').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()
|
||||
Krb_On_Off = config.get('Responder Core', 'Kerberos').upper()
|
||||
NumChal = config.get('Responder Core', 'Challenge')
|
||||
SessionLog = config.get('Responder Core', 'SessionLog')
|
||||
Exe_On_Off = config.get('HTTP Server', 'Serve-Exe').upper()
|
||||
Exec_Mode_On_Off = config.get('HTTP Server', 'Serve-Always').upper()
|
||||
FILENAME = config.get('HTTP Server', 'Filename')
|
||||
WPAD_Script = config.get('HTTP Server', 'WPADScript')
|
||||
HTMLToServe = config.get('HTTP Server', 'HTMLToServe')
|
||||
RespondTo = config.get('Responder Core', 'RespondTo').strip()
|
||||
RespondTo.split(",")
|
||||
RespondToName = config.get('Responder Core', 'RespondToName').strip()
|
||||
RespondToName.split(",")
|
||||
DontRespondTo = config.get('Responder Core', 'DontRespondTo').strip()
|
||||
DontRespondTo.split(",")
|
||||
DontRespondToName = config.get('Responder Core', 'DontRespondToName').strip()
|
||||
DontRespondToName.split(",")
|
||||
|
||||
if HTMLToServe == None:
|
||||
HTMLToServe = ''
|
||||
|
||||
if len(NumChal) is not 16:
|
||||
print "The challenge must be exactly 16 chars long.\nExample: -c 1122334455667788\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
|
||||
def IsOsX():
|
||||
Os_version = sys.platform
|
||||
if Os_version == "darwin":
|
||||
|
@ -70,6 +87,21 @@ def Analyze(AnalyzeMode):
|
|||
else:
|
||||
return False
|
||||
|
||||
#Logger
|
||||
#CommandLine = str(sys.argv)
|
||||
import logging
|
||||
#logging.basicConfig(filename="./logs/" + SessionLog, level=logging.INFO, format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
|
||||
#StartMessage = 'Responder Started\nCommand line args:%s' %(CommandLine)
|
||||
#logging.warning(StartMessage)
|
||||
|
||||
Log2Filename = "./logs/LLMNR-NBT-NS.log"
|
||||
logger2 = logging.getLogger('LLMNR/NBT-NS')
|
||||
logger2.addHandler(logging.FileHandler(Log2Filename,'a'))
|
||||
|
||||
AnalyzeFilename = "./logs/Analyze-LLMNR-NBT-NS.log"
|
||||
logger3 = logging.getLogger('Analyze LLMNR/NBT-NS')
|
||||
logger3.addHandler(logging.FileHandler(AnalyzeFilename,'a'))
|
||||
|
||||
#Function used to write captured hashs to a file.
|
||||
def WriteData(outfile,data, user):
|
||||
if os.path.isfile(outfile) == False:
|
||||
|
@ -120,6 +152,12 @@ def PrintLLMNRNBTNS(outfile,Message):
|
|||
else:
|
||||
return True
|
||||
|
||||
|
||||
# Break out challenge for the hexidecimally challenged. Also, avoid 2 different challenges by accident.
|
||||
Challenge = ""
|
||||
for i in range(0,len(NumChal),2):
|
||||
Challenge += NumChal[i:i+2].decode("hex")
|
||||
|
||||
#Packet class handling all packet generation (see odict.py).
|
||||
class Packet():
|
||||
fields = OrderedDict([
|
||||
|
@ -395,6 +433,7 @@ class NB(BaseRequestHandler):
|
|||
##################################################################################
|
||||
#Browser Listener and Lanman Finger
|
||||
##################################################################################
|
||||
from RAPLANMANPackets import *
|
||||
|
||||
def WorkstationFingerPrint(data):
|
||||
Role = {
|
||||
|
@ -566,6 +605,8 @@ class Browser(BaseRequestHandler):
|
|||
##################################################################################
|
||||
#SMB Server
|
||||
##################################################################################
|
||||
from SMBPackets import *
|
||||
|
||||
#Detect if SMB auth was Anonymous
|
||||
def Is_Anonymous(data):
|
||||
SecBlobLen = struct.unpack('<H',data[51:53])[0]
|
||||
|
@ -999,6 +1040,8 @@ class KerbUDP(BaseRequestHandler):
|
|||
##################################################################################
|
||||
#SQL Stuff
|
||||
##################################################################################
|
||||
from SQLPackets import *
|
||||
|
||||
#This function parse SQL NTLMv1/v2 hash and dump it into a specific file.
|
||||
def ParseSQLHash(data,client):
|
||||
SSPIStart = data[8:]
|
||||
|
@ -1461,6 +1504,9 @@ class MDNS(BaseRequestHandler):
|
|||
##################################################################################
|
||||
#HTTP Stuff
|
||||
##################################################################################
|
||||
from HTTPPackets import *
|
||||
from HTTPProxy import *
|
||||
|
||||
#Parse NTLMv1/v2 hash.
|
||||
def ParseHTTPHash(data,client):
|
||||
LMhashLen = struct.unpack('<H',data[12:14])[0]
|
||||
|
@ -1885,6 +1931,7 @@ class ProxyHandler (BaseHTTPServer.BaseHTTPRequestHandler):
|
|||
##################################################################################
|
||||
#HTTPS Server
|
||||
##################################################################################
|
||||
from OpenSSL import SSL
|
||||
#Parse NTLMv1/v2 hash.
|
||||
def ParseHTTPSHash(data,client):
|
||||
LMhashLen = struct.unpack('<H',data[12:14])[0]
|
||||
|
@ -2050,6 +2097,8 @@ class FTP(BaseRequestHandler):
|
|||
##################################################################################
|
||||
#LDAP Stuff
|
||||
##################################################################################
|
||||
from LDAPPackets import *
|
||||
|
||||
def ParseSearch(data):
|
||||
Search1 = re.search('(objectClass)', data)
|
||||
Search2 = re.search('(?i)(objectClass0*.*supportedCapabilities)', data)
|
||||
|
@ -2179,6 +2228,8 @@ class POP(BaseRequestHandler):
|
|||
##################################################################################
|
||||
#ESMTP Stuff
|
||||
##################################################################################
|
||||
from SMTPPackets import *
|
||||
|
||||
#ESMTP server class.
|
||||
class ESMTP(BaseRequestHandler):
|
||||
|
||||
|
@ -2209,6 +2260,8 @@ class ESMTP(BaseRequestHandler):
|
|||
##################################################################################
|
||||
#IMAP4 Stuff
|
||||
##################################################################################
|
||||
from IMAPPackets import *
|
||||
|
||||
#ESMTP server class.
|
||||
class IMAP(BaseRequestHandler):
|
||||
|
||||
|
@ -2258,7 +2311,7 @@ def Is_WPAD_On(on_off):
|
|||
return False
|
||||
|
||||
#Function name self-explanatory
|
||||
def Is_SMB_On(SMB_On_Off, LM_On_Off):
|
||||
def Is_SMB_On(SMB_On_Off):
|
||||
if SMB_On_Off == "ON":
|
||||
if LM_On_Off == True:
|
||||
return thread.start_new(serve_thread_tcp, ('', 445,SMB1LM)),thread.start_new(serve_thread_tcp,('', 139,SMB1LM))
|
||||
|
@ -2328,7 +2381,7 @@ class ThreadingUDPServer(ThreadingMixIn, UDPServer):
|
|||
def server_bind(self):
|
||||
if OsInterfaceIsSupported(INTERFACE):
|
||||
try:
|
||||
self.socket.setsockopt(socket.SOL_SOCKET, 25, BIND_TO_Interface)
|
||||
self.socket.setsockopt(socket.SOL_SOCKET, 25, BIND_TO_Interface+'\0')
|
||||
except:
|
||||
pass
|
||||
UDPServer.server_bind(self)
|
||||
|
@ -2387,22 +2440,21 @@ def serve_thread_udp(host, port, handler):
|
|||
server = ThreadingUDPServer((host, port), handler)
|
||||
server.serve_forever()
|
||||
except Exception, e:
|
||||
print "[-] Error starting TCP server on port " + str(port) + ": " + str(e)
|
||||
print "Check that you have the necessary permissions (i.e. root), no other servers are running and the correct network interface is set in Responder.conf."
|
||||
print "[-] Error starting TCP server on port " + str(port) + ": " + str(e)
|
||||
|
||||
def serve_thread_udp_MDNS(host, port, handler):
|
||||
try:
|
||||
server = ThreadingUDPMDNSServer((host, port), handler)
|
||||
server.serve_forever()
|
||||
except:
|
||||
print "Error starting UDP server on port " + str(port) + ". Check that you have the necessary permissions (i.e. root), no other servers are running and the correct network interface is set in Responder.conf."
|
||||
except Exception, e:
|
||||
print "[-] Error starting UDP server on port " + str(port) + ": " + str(e)
|
||||
|
||||
def serve_thread_udp_LLMNR(host, port, handler):
|
||||
try:
|
||||
server = ThreadingUDPLLMNRServer((host, port), handler)
|
||||
server.serve_forever()
|
||||
except:
|
||||
print "Error starting UDP server on port " + str(port) + ". Check that you have the necessary permissions (i.e. root), no other servers are running and the correct network interface is set in Responder.conf."
|
||||
except Exception, e:
|
||||
print "[-] Error starting UDP server on port " + str(port) + ": " + str(e)
|
||||
|
||||
def serve_thread_tcp(host, port, handler):
|
||||
try:
|
||||
|
@ -2413,8 +2465,8 @@ def serve_thread_tcp(host, port, handler):
|
|||
else:
|
||||
server = ThreadingTCPServer((host, port), handler)
|
||||
server.serve_forever()
|
||||
except:
|
||||
print "Error starting TCP server on port " + str(port) + ". Check that you have the necessary permissions (i.e. root), no other servers are running and the correct network interface is set in Responder.conf."
|
||||
except Exception, e:
|
||||
print "[-] Error starting TCP server on port " + str(port) + ": " + str(e)
|
||||
|
||||
def serve_thread_SSL(host, port, handler):
|
||||
try:
|
||||
|
@ -2427,130 +2479,61 @@ def serve_thread_SSL(host, port, handler):
|
|||
server.serve_forever()
|
||||
except Exception, e:
|
||||
print "[-] Error starting TCP server on port " + str(port) + ": " + str(e)
|
||||
print "Check that you have the necessary permissions (i.e. root), no other servers/services are running and the correct network interface was chosen"
|
||||
|
||||
def start_responder(options, ipaddr):
|
||||
def start_responder(options, ip_address):
|
||||
|
||||
VERSION = '2.1.2'
|
||||
|
||||
global OURIP; OURIP = ipaddr
|
||||
#Cli options.
|
||||
global OURIP; OURIP = ip_address
|
||||
global LM_On_Off; LM_On_Off = options.LM_On_Off
|
||||
global WPAD_On_Off; WPAD_On_Off = options.WPAD_On_Off
|
||||
global Wredirect; Wredirect= options.Wredirect
|
||||
global Wredirect; Wredirect = options.Wredirect
|
||||
global NBTNSDomain; NBTNSDomain = options.NBTNSDomain
|
||||
global Basic; Basic = options.Basic
|
||||
global Finger_On_Off; Finger_On_Off = options.Finger
|
||||
global INTERFACE; INTERFACE = options.interface
|
||||
global BIND_TO_Interface; BIND_TO_Interface = options.interface
|
||||
global INTERFACE; INTERFACE = "Not set"
|
||||
global Verbose; Verbose = options.Verbose
|
||||
global Force_WPAD_Auth; Force_WPAD_Auth = options.Force_WPAD_Auth
|
||||
global AnalyzeMode; AnalyzeMode = options.Analyse
|
||||
|
||||
global ResponderPATH; ResponderPATH = "./logs/"
|
||||
|
||||
#Read the responder.conf file
|
||||
global config
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read('./config/responder.conf')
|
||||
|
||||
On_Off = config.get('Responder Core', 'HTTP').upper()
|
||||
SSL_On_Off = config.get('Responder Core', 'HTTPS').upper()
|
||||
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()
|
||||
IMAP_On_Off = config.get('Responder Core', 'IMAP').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()
|
||||
Krb_On_Off = config.get('Responder Core', 'Kerberos').upper()
|
||||
|
||||
NumChal = config.get('Responder Core', 'Challenge')
|
||||
if len(NumChal) is not 16:
|
||||
sys.exit("[-] The challenge must be exactly 16 chars long.\nExample: -c 1122334455667788\n")
|
||||
|
||||
# Break out challenge for the hexidecimally challenged. Also, avoid 2 different challenges by accident.
|
||||
Challenge = ""
|
||||
for i in range(0,len(NumChal),2):
|
||||
Challenge += NumChal[i:i+2].decode("hex")
|
||||
|
||||
SessionLog = config.get('Responder Core', 'SessionLog')
|
||||
Exe_On_Off = config.get('HTTP Server', 'Serve-Exe').upper()
|
||||
Exec_Mode_On_Off = config.get('HTTP Server', 'Serve-Always').upper()
|
||||
FILENAME = config.get('HTTP Server', 'Filename')
|
||||
WPAD_Script = config.get('HTTP Server', 'WPADScript')
|
||||
|
||||
HTMLToServe = config.get('HTTP Server', 'HTMLToServe')
|
||||
if HTMLToServe == None:
|
||||
HTMLToServe = ''
|
||||
|
||||
RespondTo = config.get('Responder Core', 'RespondTo').strip()
|
||||
RespondTo.split(",")
|
||||
RespondToName = config.get('Responder Core', 'RespondToName').strip()
|
||||
RespondToName.split(",")
|
||||
DontRespondTo = config.get('Responder Core', 'DontRespondTo').strip()
|
||||
DontRespondTo.split(",")
|
||||
DontRespondToName = config.get('Responder Core', 'DontRespondToName').strip()
|
||||
DontRespondToName.split(",")
|
||||
|
||||
#Logger
|
||||
#CommandLine = str(sys.argv)
|
||||
#logging.basicConfig(filename=str(os.path.join(ResponderPATH,SessionLog)),level=logging.INFO,format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
|
||||
#StartMessage = 'Responder Started\nCommand line args:%s' %(CommandLine)
|
||||
#logging.warning(StartMessage)
|
||||
|
||||
|
||||
global Log2Filename
|
||||
Log2Filename = str("./logs/LLMNR-NBT-NS.log")
|
||||
global logger2
|
||||
logger2 = logging.getLogger('LLMNR/NBT-NS')
|
||||
logger2.addHandler(logging.FileHandler(Log2Filename,'w'))
|
||||
|
||||
global AnalyzeFilename
|
||||
AnalyzeFilename = str("./logs/Analyze-LLMNR-NBT-NS.log")
|
||||
global logger3
|
||||
logger3 = logging.getLogger('Analyze LLMNR/NBT-NS')
|
||||
logger3.addHandler(logging.FileHandler(AnalyzeFilename,'a'))
|
||||
global BIND_TO_Interface; BIND_TO_Interface = "ALL"
|
||||
|
||||
AnalyzeICMPRedirect()
|
||||
|
||||
print "[*] NBT-NS, LLMNR & MDNS Responder v%s by Laurent Gaffie online" % VERSION
|
||||
if AnalyzeMode:
|
||||
print '[*] Responder is in analyze mode. No NBT-NS, LLMNR, MDNS requests will be poisoned\n'
|
||||
|
||||
start_message = "Respoder will redirect requests to: %s\n" % ip_address
|
||||
start_message += "Challenge set: %s\n" % NumChal
|
||||
start_message += "WPAD Proxy Server: %s\n" % WPAD_On_Off
|
||||
start_message += "WPAD script loaded: %s\n" % WPAD_Script
|
||||
start_message += "HTTP Server: %s\n" % On_Off
|
||||
start_message += "HTTPS Server: %s\n" % SSL_On_Off
|
||||
start_message += "SMB Server: %s\n" % SMB_On_Off
|
||||
start_message += "SMB LM support: %s\n" % LM_On_Off
|
||||
start_message += "Kerberos Server: %s\n" % Krb_On_Off
|
||||
start_message += "SQL Server: %s\n" % SQL_On_Off
|
||||
start_message += "FTP Server: %s\n" % FTP_On_Off
|
||||
start_message += "IMAP Server: %s\n" % IMAP_On_Off
|
||||
start_message += "POP3 Server: %s\n" % POP_On_Off
|
||||
start_message += "SMTP Server: %s\n" % SMTP_On_Off
|
||||
start_message += "DNS Server: %s\n" % DNS_On_Off
|
||||
start_message += "LDAP Server: %s\n" % LDAP_On_Off
|
||||
start_message += "FingerPrint hosts: %s\n" % Finger_On_Off
|
||||
start_message += "Serving Executable via HTTP&WPAD: %s\n" % Exe_On_Off
|
||||
start_message += "Always Serving a Specific File via HTTP&WPAD: %s\n" % Exec_Mode_On_Off
|
||||
|
||||
print start_message
|
||||
|
||||
try:
|
||||
|
||||
banner = "[*] NBT-NS, LLMNR & MDNS Responder v%s by Laurent Gaffie online\n" % VERSION
|
||||
start_message = "Global Parameters set:\n"
|
||||
start_message += "Responder is bound to interface: %s\n" % INTERFACE
|
||||
start_message += "Challenge set: %s\n" % NumChal
|
||||
start_message += "WPAD Proxy Server: %s\n" % WPAD_On_Off
|
||||
start_message += "WPAD script loaded: %s\n" % WPAD_Script
|
||||
start_message += "HTTP Server: %s\n" % On_Off
|
||||
start_message += "HTTPS Server: %s\n" % SSL_On_Off
|
||||
start_message += "SMB Server: %s\n" % SMB_On_Off
|
||||
start_message += "SMB LM support: %s\n" % LM_On_Off
|
||||
start_message += "Kerberos Server: %s\n" % Krb_On_Off
|
||||
start_message += "SQL Server: %s\n" % SQL_On_Off
|
||||
start_message += "FTP Server: %s\n" % FTP_On_Off
|
||||
start_message += "IMAP Server: %s\n" % IMAP_On_Off
|
||||
start_message += "POP3 Server: %s\n" % POP_On_Off
|
||||
start_message += "SMTP Server: %s\n" % SMTP_On_Off
|
||||
start_message += "DNS Server: %s\n" % DNS_On_Off
|
||||
start_message += "LDAP Server: %s\n" % LDAP_On_Off
|
||||
start_message += "FingerPrint hosts: %s\n" % Finger_On_Off
|
||||
start_message += "Serving Executable via HTTP&WPAD: %s\n" % Exe_On_Off
|
||||
start_message += "Always Serving a Specific File via HTTP&WPAD: %s\n" % Exec_Mode_On_Off
|
||||
|
||||
print banner
|
||||
print start_message
|
||||
|
||||
|
||||
if AnalyzeMode:
|
||||
print '[*] Responder is in analyze mode. No NBT-NS, LLMNR, MDNS requests will be poisoned'
|
||||
|
||||
num_thrd = 1
|
||||
Is_FTP_On(FTP_On_Off)
|
||||
Is_HTTP_On(On_Off)
|
||||
Is_HTTPS_On(SSL_On_Off)
|
||||
Is_WPAD_On(WPAD_On_Off)
|
||||
Is_Kerberos_On(Krb_On_Off)
|
||||
Is_SMB_On(SMB_On_Off, LM_On_Off)
|
||||
Is_SMB_On(SMB_On_Off)
|
||||
Is_SQL_On(SQL_On_Off)
|
||||
Is_LDAP_On(LDAP_On_Off)
|
||||
Is_DNS_On(DNS_On_Off)
|
||||
|
@ -2564,8 +2547,7 @@ def start_responder(options, ipaddr):
|
|||
thread.start_new(serve_thread_udp,('', 88, KerbUDP))
|
||||
thread.start_new(serve_thread_udp,('', 137,NB)) #NBNS
|
||||
thread.start_new(serve_thread_udp_LLMNR,('', 5355, LLMNR)) #LLMNR
|
||||
|
||||
while num_thrd > 0:
|
||||
time.sleep(0.1)
|
||||
time.sleep(1)
|
||||
except KeyboardInterrupt:
|
||||
exit()
|
||||
exit()
|
Loading…
Add table
Add a link
Reference in a new issue