diff --git a/Responder.py b/Responder.py
index ed238d5..307fa29 100755
--- a/Responder.py
+++ b/Responder.py
@@ -15,7 +15,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
import optparse
-import ssl
from SocketServer import TCPServer, UDPServer, ThreadingMixIn
from threading import Thread
@@ -23,6 +22,12 @@ from utils import *
import struct
banner()
+try:
+ import ssl
+except ImportError:
+ ssl = False
+ print color("[!] Module 'ssl' is unavailable. HTTPS is disabled")
+
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, you can use 'ALL' as a wildcard for all interfaces", dest="Interface", metavar="eth0", default=None)
@@ -35,7 +40,7 @@ parser.add_option('-r', '--wredir', action="store_true", help="Enable ans
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)
parser.add_option('-f','--fingerprint', action="store_true", help="This option allows you to fingerprint a host that issued an NBT-NS or LLMNR query.", dest="Finger", default=False)
parser.add_option('-w','--wpad', action="store_true", help="Start the WPAD rogue proxy server. Default value is False", dest="WPAD_On_Off", default=False)
-parser.add_option('-u','--upstream-proxy', action="store", help="Upstream HTTP proxy used by the rogue WPAD Proxy for outgoing requests (format: host:port)", dest="Upstream_Proxy", default=None)
+parser.add_option('-u','--upstream-proxy', action="store", help="Upstream HTTP proxy used by the rogue WPAD Proxy for outgoing requests (format: host:port)", dest="Upstream_Proxy", default=False)
parser.add_option('-F','--ForceWpadAuth', action="store_true", help="Force NTLM/Basic authentication on wpad.dat file retrieval. This may cause a login prompt. Default: False", dest="Force_WPAD_Auth", default=False)
parser.add_option('-P','--ProxyAuth', action="store_true", help="Force NTLM (transparently)/Basic (prompt) authentication for the proxy. WPAD doesn't need to be ON. This option is highly effective when combined with -r. Default: False", dest="ProxyAuth_On_Off", default=False)
@@ -237,7 +242,7 @@ def main():
from servers.HTTP import HTTP
threads.append(Thread(target=serve_thread_tcp, args=('', 80, HTTP,)))
- if settings.Config.SSL_On_Off:
+ if settings.Config.SSL_On_Off and ssl:
from servers.HTTP import HTTPS
threads.append(Thread(target=serve_thread_SSL, args=('', 443, HTTPS,)))
diff --git a/packets.py b/packets.py
index 9820e26..435c35b 100644
--- a/packets.py
+++ b/packets.py
@@ -22,7 +22,7 @@ from odict import OrderedDict
from utils import HTTPCurrentDate, RespondWithIPAton
# Packet class handling all packet generation (see odict.py).
-class Packet():
+class Packet:
fields = OrderedDict([
("data", ""),
])
diff --git a/servers/HTTP.py b/servers/HTTP.py
index 6f170fc..85508d5 100644
--- a/servers/HTTP.py
+++ b/servers/HTTP.py
@@ -144,8 +144,10 @@ def ServeOPTIONS(data):
return False
def ServeFile(Filename):
- with open (Filename, "rb") as bk:
- return bk.read()
+ bk = open(Filename, "rb")
+ data = bk.read()
+ bk.close()
+ return data
def RespondWithFile(client, filename, dlname=None):
diff --git a/servers/HTTP_Proxy.py b/servers/HTTP_Proxy.py
index 71e6e75..9ab73af 100644
--- a/servers/HTTP_Proxy.py
+++ b/servers/HTTP_Proxy.py
@@ -236,17 +236,17 @@ class HTTP_Proxy(BaseHTTPServer.BaseHTTPRequestHandler):
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
- if self._connect_to(self.path, soc):
- self.wfile.write(self.protocol_version +" 200 Connection established\r\n")
- self.wfile.write("Proxy-agent: %s\r\n" % self.version_string())
- self.wfile.write("\r\n")
- try:
- self._read_write(soc, 300)
- except:
- pass
- except:
- pass
-
+ try:
+ if self._connect_to(self.path, soc):
+ self.wfile.write(self.protocol_version +" 200 Connection established\r\n")
+ self.wfile.write("Proxy-agent: %s\r\n" % self.version_string())
+ self.wfile.write("\r\n")
+ try:
+ self._read_write(soc, 300)
+ except:
+ pass
+ except:
+ pass
finally:
soc.close()
self.connection.close()
@@ -266,36 +266,36 @@ class HTTP_Proxy(BaseHTTPServer.BaseHTTPRequestHandler):
soc = self.socket_proxy(socket.AF_INET, socket.SOCK_STREAM)
else:
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
try:
- URL_Unparse = urlparse.urlunparse(('', '', path, params, query, ''))
+ try:
+ URL_Unparse = urlparse.urlunparse(('', '', path, params, query, ''))
- if self._connect_to(netloc, soc):
- soc.send("%s %s %s\r\n" % (self.command, URL_Unparse, self.request_version))
+ if self._connect_to(netloc, soc):
+ soc.send("%s %s %s\r\n" % (self.command, URL_Unparse, self.request_version))
- Cookie = self.headers['Cookie'] if "Cookie" in self.headers else ''
+ Cookie = self.headers.get('Cookie', '')
- if settings.Config.Verbose:
- print text("[PROXY] Client : %s" % color(self.client_address[0], 3))
- print text("[PROXY] Requested URL : %s" % color(self.path, 3))
- print text("[PROXY] Cookie : %s" % Cookie)
+ if settings.Config.Verbose:
+ print text("[PROXY] Client : %s" % color(self.client_address[0], 3))
+ print text("[PROXY] Requested URL : %s" % color(self.path, 3))
+ print text("[PROXY] Cookie : %s" % Cookie)
- self.headers['Connection'] = 'close'
- del self.headers['Proxy-Connection']
- del self.headers['If-Range']
- del self.headers['Range']
-
- for k, v in self.headers.items():
- soc.send("%s: %s\r\n" % (k.title(), v))
- soc.send("\r\n")
+ self.headers['Connection'] = 'close'
+ del self.headers['Proxy-Connection']
+ del self.headers['If-Range']
+ del self.headers['Range']
- try:
- self._read_write(soc, netloc)
- except:
- pass
+ for k, v in self.headers.items():
+ soc.send("%s: %s\r\n" % (k.title(), v))
+ soc.send("\r\n")
- except:
- pass
+ try:
+ self._read_write(soc, netloc)
+ except:
+ pass
+
+ except:
+ pass
finally:
soc.close()
diff --git a/settings.py b/settings.py
index e02dff9..abed838 100644
--- a/settings.py
+++ b/settings.py
@@ -22,6 +22,35 @@ from utils import *
__version__ = 'Responder 2.3.3.2'
+# Backport (monkeypatch) check_output and CalledProcessError
+if not hasattr(subprocess, 'CalledProcessError'):
+ class CalledProcessError(Exception):
+ def __init__(self, returncode, cmd, output=None):
+ self.returncode = returncode
+ self.cmd = cmd
+ self.output = output
+
+ def __str__(self):
+ return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
+
+ subprocess.CalledProcessError = CalledProcessError
+
+if not hasattr(subprocess, 'check_output'):
+ def check_output(*popenargs, **kwargs):
+ if 'stdout' in kwargs:
+ raise ValueError('stdout argument not allowed, it will be overridden.')
+ process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
+ output, unused_err = process.communicate()
+ retcode = process.poll()
+ if retcode:
+ cmd = kwargs.get("args")
+ if cmd is None:
+ cmd = popenargs[0]
+ raise subprocess.CalledProcessError(retcode, cmd, output=output)
+ return output
+
+ subprocess.check_output = check_output
+
class Settings:
def __init__(self):
@@ -229,17 +258,17 @@ class Settings:
try:
NetworkCard = subprocess.check_output(["ifconfig", "-a"])
- except subprocess.CalledProcessError as ex:
+ except Exception,ex:
NetworkCard = "Error fetching Network Interfaces:", ex
pass
try:
DNS = subprocess.check_output(["cat", "/etc/resolv.conf"])
- except subprocess.CalledProcessError as ex:
+ except subprocess.CalledProcessError,ex:
DNS = "Error fetching DNS configuration:", ex
pass
try:
RoutingInfo = subprocess.check_output(["netstat", "-rn"])
- except subprocess.CalledProcessError as ex:
+ except subprocess.CalledProcessError,ex:
RoutingInfo = "Error fetching Routing information:", ex
pass
@@ -247,7 +276,7 @@ class Settings:
try:
utils.DumpConfig(self.ResponderConfigDump, Message)
utils.DumpConfig(self.ResponderConfigDump,str(self))
- except AttributeError as ex:
+ except AttributeError, ex:
print "Missing Module:", ex
pass
diff --git a/tools/DHCP.py b/tools/DHCP.py
index 20f02b0..f02c124 100755
--- a/tools/DHCP.py
+++ b/tools/DHCP.py
@@ -222,7 +222,10 @@ class DHCPInformACK(Packet):
self.fields["Op252Len"] = struct.pack(">b",len(str(self.fields["Op252Str"])))
def SpoofIP(Spoof):
- return ROUTERIP if Spoof else Responder_IP
+ if Spoof:
+ return ROUTERIP
+ else:
+ return Responder_IP
def RespondToThisIP(ClientIp):
if ClientIp.startswith('127.0.0.'):
diff --git a/tools/MultiRelay/RelayMultiCore.py b/tools/MultiRelay/RelayMultiCore.py
index 20ccfdb..fc5008a 100644
--- a/tools/MultiRelay/RelayMultiCore.py
+++ b/tools/MultiRelay/RelayMultiCore.py
@@ -39,7 +39,7 @@ def longueur(payload):
length = struct.pack(">i", len(''.join(payload)))
return length
-class Packet():
+class Packet:
fields = OrderedDict([
("data", ""),
])
@@ -55,22 +55,30 @@ class Packet():
# Function used to write captured hashs to a file.
def WriteData(outfile, data, user):
- if not os.path.isfile(outfile):
- with open(outfile,"w") as outf:
- outf.write(data + '\n')
- return
- with open(outfile,"r") as filestr:
- if re.search(user.encode('hex'), filestr.read().encode('hex')):
- return False
- elif re.search(re.escape("$"), user):
- return False
- with open(outfile,"a") as outf2:
- outf2.write(data + '\n')
+ if not os.path.isfile(outfile):
+ outf = open(outfile,"w")
+ outf.write(data + '\n')
+ outf.close()
+ return
+
+ filestr = open(outfile,"r")
+ try:
+ if re.search(user.encode('hex'), filestr.read().encode('hex')):
+ return False
+ elif re.search(re.escape("$"), user):
+ return False
+ finally:
+ filestr.close()
+
+ outf2 = open(outfile,"a")
+ outf2.write(data + '\n')
+ outf2.close()
#Function used to verify if a previous auth attempt was made.
def ReadData(Outfile, Client, User, Domain, Target, cmd):
try:
- with open(Logs_Path+"logs/"+Outfile,"r") as filestr:
+ filestr = open(Logs_Path+"logs/"+Outfile,"r")
+ try:
Login = Client+":"+User+":"+Domain+":"+Target+":Logon Failure"
if re.search(Login.encode('hex'), filestr.read().encode('hex')):
print "[+] User %s\\%s previous login attempt returned logon_failure. Not forwarding anymore to prevent account lockout\n"%(Domain,User)
@@ -78,6 +86,8 @@ def ReadData(Outfile, Client, User, Domain, Target, cmd):
else:
return False
+ finally:
+ filestr.close()
except:
raise
@@ -267,8 +277,9 @@ def GetReadableSize(size,precision=2):
return "%.*f%s"%(precision,size,suffixes[suffixIndex])
def WriteOutputToFile(data, File):
- with open(SaveSam_Path+"/"+File, "wb") as file:
- file.write(data)
+ file = open(SaveSam_Path+"/"+File, "wb")
+ file.write(data)
+ file.close()
##This function is one of the main SMB read function. We request all the time 65520 bytes to the server.
#Add (+32 (SMBHeader) +4 Netbios Session Header + 27 for the ReadAndx structure) +63 and you end up with 65583.
diff --git a/tools/MultiRelay/RelayMultiPackets.py b/tools/MultiRelay/RelayMultiPackets.py
index cedcaaf..0e25134 100644
--- a/tools/MultiRelay/RelayMultiPackets.py
+++ b/tools/MultiRelay/RelayMultiPackets.py
@@ -20,7 +20,7 @@ from odict import OrderedDict
import datetime
from base64 import b64decode, b64encode
-class Packet():
+class Packet:
fields = OrderedDict([
("data", ""),
])
diff --git a/tools/MultiRelay/creddump/framework/win32/hashdump.py b/tools/MultiRelay/creddump/framework/win32/hashdump.py
index 6acc808..59d4543 100644
--- a/tools/MultiRelay/creddump/framework/win32/hashdump.py
+++ b/tools/MultiRelay/creddump/framework/win32/hashdump.py
@@ -176,11 +176,20 @@ def get_user_hashes(user_key, hbootkey):
hash_offset = unpack("