|
|
|
@ -135,7 +135,9 @@ ajpy | AJP | https://github.com/hypn0s/AJPy/
|
|
|
|
|
--------------------------------------------------------------------------------------------------
|
|
|
|
|
openldap | LDAP | http://www.openldap.org/ | 2.4.24 |
|
|
|
|
|
--------------------------------------------------------------------------------------------------
|
|
|
|
|
impacket | SMB | https://github.com/CoreSecurity/impacket | 0.9.12 |
|
|
|
|
|
impacket | SMB, MSSQL | https://github.com/CoreSecurity/impacket | 0.9.12 |
|
|
|
|
|
--------------------------------------------------------------------------------------------------
|
|
|
|
|
pyOpenSSL | impacket | https://pyopenssl.org/ | 17.5.0 |
|
|
|
|
|
--------------------------------------------------------------------------------------------------
|
|
|
|
|
cx_Oracle | Oracle | http://cx-oracle.sourceforge.net/ | 5.1.1 |
|
|
|
|
|
--------------------------------------------------------------------------------------------------
|
|
|
|
@ -145,7 +147,7 @@ xfreerdp | RDP (NLA) | https://github.com/FreeRDP/FreeRDP/
|
|
|
|
|
--------------------------------------------------------------------------------------------------
|
|
|
|
|
psycopg | PostgreSQL | http://initd.org/psycopg/ | 2.4.5 |
|
|
|
|
|
--------------------------------------------------------------------------------------------------
|
|
|
|
|
pycrypto | VNC | http://www.dlitz.net/software/pycrypto/ | 2.3 |
|
|
|
|
|
pycrypto | VNC, impacket | http://www.dlitz.net/software/pycrypto/ | 2.6.1 |
|
|
|
|
|
--------------------------------------------------------------------------------------------------
|
|
|
|
|
dnspython | DNS | http://www.dnspython.org/ | 1.10.0 |
|
|
|
|
|
--------------------------------------------------------------------------------------------------
|
|
|
|
@ -153,7 +155,7 @@ IPy | NET keyword | https://github.com/haypo/python-ipy
|
|
|
|
|
--------------------------------------------------------------------------------------------------
|
|
|
|
|
pysnmp | SNMP | http://pysnmp.sourceforge.net/ | 4.2.1 |
|
|
|
|
|
--------------------------------------------------------------------------------------------------
|
|
|
|
|
pyasn1 | SNMP | http://sourceforge.net/projects/pyasn1/ | 0.1.2 |
|
|
|
|
|
pyasn1 | SNMP, impacket | http://sourceforge.net/projects/pyasn1/ | 0.1.2 |
|
|
|
|
|
--------------------------------------------------------------------------------------------------
|
|
|
|
|
ike-scan | IKE | http://www.nta-monitor.com/tools-resources/ | 1.9 |
|
|
|
|
|
--------------------------------------------------------------------------------------------------
|
|
|
|
@ -577,7 +579,7 @@ NB1. SNMPv3 requires passphrases to be at least 8 characters long.
|
|
|
|
|
|
|
|
|
|
* Brute-force the ZIP file password (cracking older pkzip encryption used to be not supported in JtR).
|
|
|
|
|
----------
|
|
|
|
|
unzip_pass zipfile=path/to/file.zip password=FILE0 0=passwords.txt -x ignore:code!=0
|
|
|
|
|
unzip_pass zipfile=file.zip password=FILE0 0=passwords.txt -x ignore:code!=0
|
|
|
|
|
|
|
|
|
|
}}}
|
|
|
|
|
|
|
|
|
@ -676,16 +678,21 @@ class TXTFormatter(logging.Formatter):
|
|
|
|
|
|
|
|
|
|
def format(self, record):
|
|
|
|
|
if not record.msg or record.msg == 'headers':
|
|
|
|
|
self._fmt = self.resultfmt
|
|
|
|
|
fmt = self.resultfmt
|
|
|
|
|
|
|
|
|
|
if not all(True if 0x20 <= ord(c) < 0x7f else False for c in record.candidate):
|
|
|
|
|
record.candidate = repr(record.candidate)
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
if record.levelno == logging.DEBUG:
|
|
|
|
|
self._fmt = '%(asctime)s %(name)-7s %(levelname)7s [%(pname)s] %(message)s'
|
|
|
|
|
fmt = '%(asctime)s %(name)-7s %(levelname)7s [%(pname)s] %(message)s'
|
|
|
|
|
else:
|
|
|
|
|
self._fmt = '%(asctime)s %(name)-7s %(levelname)7s - %(message)s'
|
|
|
|
|
fmt = '%(asctime)s %(name)-7s %(levelname)7s - %(message)s'
|
|
|
|
|
|
|
|
|
|
if PY3:
|
|
|
|
|
self._style._fmt = fmt
|
|
|
|
|
else:
|
|
|
|
|
self._fmt = fmt
|
|
|
|
|
|
|
|
|
|
return logging.Formatter.format(self, record)
|
|
|
|
|
|
|
|
|
@ -714,8 +721,8 @@ class XMLFormatter(logging.Formatter):
|
|
|
|
|
|
|
|
|
|
def format(self, record):
|
|
|
|
|
|
|
|
|
|
for k, v in record.__dict__.iteritems():
|
|
|
|
|
if isinstance(v, basestring):
|
|
|
|
|
for k, v in record.__dict__.items():
|
|
|
|
|
if isinstance(v, str):
|
|
|
|
|
record.__dict__[k] = xmlescape(v)
|
|
|
|
|
|
|
|
|
|
return super(XMLFormatter, self).format(record)
|
|
|
|
@ -793,7 +800,7 @@ def process_logs(queue, indicatorsfmt, argv, log_dir):
|
|
|
|
|
|
|
|
|
|
else: # remove "</results>...</root>"
|
|
|
|
|
with open(results_xml, 'r+b') as f:
|
|
|
|
|
offset = f.read().find('</results>')
|
|
|
|
|
offset = f.read().find(b'</results>')
|
|
|
|
|
if offset != -1:
|
|
|
|
|
f.seek(offset)
|
|
|
|
|
f.truncate(f.tell())
|
|
|
|
@ -896,6 +903,23 @@ except ImportError:
|
|
|
|
|
from cStringIO import StringIO
|
|
|
|
|
from sys import maxint
|
|
|
|
|
|
|
|
|
|
PY3 = sys.version_info >= (3,)
|
|
|
|
|
if PY3: # http://python3porting.com/problems.html
|
|
|
|
|
def b(x):
|
|
|
|
|
return x.encode('ISO-8859-1')
|
|
|
|
|
def B(x):
|
|
|
|
|
return x.decode()
|
|
|
|
|
else:
|
|
|
|
|
def b(x):
|
|
|
|
|
return x
|
|
|
|
|
def B(x):
|
|
|
|
|
return x
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
input = raw_input
|
|
|
|
|
except NameError:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
notfound = []
|
|
|
|
|
try:
|
|
|
|
|
from IPy import IP
|
|
|
|
@ -904,33 +928,40 @@ except ImportError:
|
|
|
|
|
has_ipy = False
|
|
|
|
|
notfound.append('IPy')
|
|
|
|
|
|
|
|
|
|
import multiprocessing.forking
|
|
|
|
|
class _Popen(multiprocessing.forking.Popen):
|
|
|
|
|
try:
|
|
|
|
|
# Python 3.4+
|
|
|
|
|
if sys.platform.startswith('win'):
|
|
|
|
|
import multiprocessing.popen_spawn_win32 as forking
|
|
|
|
|
else:
|
|
|
|
|
import multiprocessing.popen_fork as forking
|
|
|
|
|
except ImportError:
|
|
|
|
|
import multiprocessing.forking as forking
|
|
|
|
|
|
|
|
|
|
if sys.platform.startswith('win'):
|
|
|
|
|
# First define a modified version of Popen.
|
|
|
|
|
class _Popen(forking.Popen):
|
|
|
|
|
def __init__(self, *args, **kw):
|
|
|
|
|
if hasattr(sys, 'frozen'):
|
|
|
|
|
# We have to set original _MEIPASS2 value from sys._MEIPASS
|
|
|
|
|
# to get --onefile mode working.
|
|
|
|
|
os.putenv('_MEIPASS2', sys._MEIPASS)
|
|
|
|
|
try:
|
|
|
|
|
super(_Popen, self).__init__(*args, **kw)
|
|
|
|
|
finally:
|
|
|
|
|
if hasattr(sys, 'frozen'):
|
|
|
|
|
# We have to set original _MEIPASS2 value from sys._MEIPASS
|
|
|
|
|
# to get --onefile mode working.
|
|
|
|
|
os.putenv('_MEIPASS2', sys._MEIPASS)
|
|
|
|
|
try:
|
|
|
|
|
super(_Popen, self).__init__(*args, **kw)
|
|
|
|
|
finally:
|
|
|
|
|
if hasattr(sys, 'frozen'):
|
|
|
|
|
# On some platforms (e.g. AIX) 'os.unsetenv()' is not
|
|
|
|
|
# available. In those cases we cannot delete the variable
|
|
|
|
|
# but only set it to the empty string. The bootloader
|
|
|
|
|
# can handle this case.
|
|
|
|
|
if hasattr(os, 'unsetenv'):
|
|
|
|
|
os.unsetenv('_MEIPASS2')
|
|
|
|
|
else:
|
|
|
|
|
os.putenv('_MEIPASS2', '')
|
|
|
|
|
# On some platforms (e.g. AIX) 'os.unsetenv()' is not
|
|
|
|
|
# available. In those cases we cannot delete the variable
|
|
|
|
|
# but only set it to the empty string. The bootloader
|
|
|
|
|
# can handle this case.
|
|
|
|
|
if hasattr(os, 'unsetenv'):
|
|
|
|
|
os.unsetenv('_MEIPASS2')
|
|
|
|
|
else:
|
|
|
|
|
os.putenv('_MEIPASS2', '')
|
|
|
|
|
|
|
|
|
|
class Process(multiprocessing.Process):
|
|
|
|
|
_Popen = _Popen
|
|
|
|
|
# Second override 'Popen' class with our modified version.
|
|
|
|
|
forking.Popen = _Popen
|
|
|
|
|
|
|
|
|
|
# So BaseManager.start() uses this new Process class
|
|
|
|
|
multiprocessing.Process = Process
|
|
|
|
|
from multiprocessing.managers import SyncManager
|
|
|
|
|
|
|
|
|
|
# imports }}}
|
|
|
|
|
|
|
|
|
|
# utils {{{
|
|
|
|
@ -975,7 +1006,7 @@ def create_dir(top_path):
|
|
|
|
|
if os.path.isdir(top_path):
|
|
|
|
|
files = os.listdir(top_path)
|
|
|
|
|
if files:
|
|
|
|
|
if raw_input("Directory '%s' is not empty, do you want to wipe it ? [Y/n]: " % top_path) != 'n':
|
|
|
|
|
if input("Directory '%s' is not empty, do you want to wipe it ? [Y/n]: " % top_path) != 'n':
|
|
|
|
|
for root, dirs, files in os.walk(top_path):
|
|
|
|
|
if dirs:
|
|
|
|
|
print("Directory '%s' contains sub-directories, safely aborting..." % root)
|
|
|
|
@ -1400,7 +1431,7 @@ Please read the README inside for more examples and usage information.
|
|
|
|
|
|
|
|
|
|
log_queue = multiprocessing.Queue()
|
|
|
|
|
|
|
|
|
|
logsvc = Process(name='LogSvc', target=process_logs, args=(log_queue, module.Response.indicatorsfmt, argv, build_logdir(opts.log_dir, opts.auto_log)))
|
|
|
|
|
logsvc = multiprocessing.Process(name='LogSvc', target=process_logs, args=(log_queue, module.Response.indicatorsfmt, argv, build_logdir(opts.log_dir, opts.auto_log)))
|
|
|
|
|
logsvc.daemon = True
|
|
|
|
|
logsvc.start()
|
|
|
|
|
|
|
|
|
@ -1426,6 +1457,7 @@ Please read the README inside for more examples and usage information.
|
|
|
|
|
p = expand_path(v[1:])
|
|
|
|
|
with open(p) as f:
|
|
|
|
|
v = f.read()
|
|
|
|
|
|
|
|
|
|
kargs.append((k, v))
|
|
|
|
|
|
|
|
|
|
iter_vals = [v for k, v in sorted(wlists.items())]
|
|
|
|
@ -1619,14 +1651,14 @@ Please read the README inside for more examples and usage information.
|
|
|
|
|
# consumers
|
|
|
|
|
for num in range(self.num_threads):
|
|
|
|
|
report_queue = multiprocessing.Queue(maxsize=1000)
|
|
|
|
|
t = Process(name='Consumer-%d' % num, target=self.consume, args=(task_queues[num], report_queue, logger.queue))
|
|
|
|
|
t = multiprocessing.Process(name='Consumer-%d' % num, target=self.consume, args=(task_queues[num], report_queue, logger.queue))
|
|
|
|
|
t.daemon = True
|
|
|
|
|
t.start()
|
|
|
|
|
self.thread_report.append(report_queue)
|
|
|
|
|
self.thread_progress.append(Progress())
|
|
|
|
|
|
|
|
|
|
# producer
|
|
|
|
|
t = Process(name='Producer', target=self.produce, args=(task_queues, logger.queue))
|
|
|
|
|
t = multiprocessing.Process(name='Producer', target=self.produce, args=(task_queues, logger.queue))
|
|
|
|
|
t.daemon = True
|
|
|
|
|
t.start()
|
|
|
|
|
|
|
|
|
@ -2130,7 +2162,6 @@ class Timing:
|
|
|
|
|
|
|
|
|
|
# TCP_Cache {{{
|
|
|
|
|
class TCP_Connection:
|
|
|
|
|
|
|
|
|
|
def __init__(self, fp, banner=None):
|
|
|
|
|
self.fp = fp
|
|
|
|
|
self.banner = banner
|
|
|
|
@ -2197,16 +2228,16 @@ class TCP_Cache:
|
|
|
|
|
# FTP {{{
|
|
|
|
|
from ftplib import FTP, Error as FTP_Error
|
|
|
|
|
try:
|
|
|
|
|
from ftplib import FTP_TLS # New in python 2.7
|
|
|
|
|
from ftplib import FTP_TLS # only available since python 2.7
|
|
|
|
|
except ImportError:
|
|
|
|
|
notfound.append('ftp-tls')
|
|
|
|
|
notfound.append('python')
|
|
|
|
|
|
|
|
|
|
class FTP_login(TCP_Cache):
|
|
|
|
|
'''Brute-force FTP'''
|
|
|
|
|
|
|
|
|
|
usage_hints = (
|
|
|
|
|
"""%prog host=10.0.0.1 user=FILE0 password=FILE1 0=logins.txt 1=passwords.txt"""
|
|
|
|
|
""" -x ignore:mesg='Login incorrect.' -x ignore,reset,retry:code=500""",
|
|
|
|
|
'''%prog host=10.0.0.1 user=FILE0 password=FILE1 0=logins.txt 1=passwords.txt'''
|
|
|
|
|
''' -x ignore:mesg='Login incorrect.' -x ignore,reset,retry:code=500''',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
available_options = (
|
|
|
|
@ -2237,23 +2268,25 @@ class FTP_login(TCP_Cache):
|
|
|
|
|
|
|
|
|
|
def execute(self, host, port='21', tls='0', user=None, password=None, timeout='10', persistent='1'):
|
|
|
|
|
|
|
|
|
|
with Timing() as timing:
|
|
|
|
|
fp, resp = self.bind(host, port, tls, timeout=timeout)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
with Timing() as timing:
|
|
|
|
|
fp, resp = self.bind(host, port, tls, timeout=timeout)
|
|
|
|
|
|
|
|
|
|
if user is not None or password is not None:
|
|
|
|
|
with Timing() as timing:
|
|
|
|
|
|
|
|
|
|
if user is not None:
|
|
|
|
|
resp = fp.sendcmd('USER ' + user)
|
|
|
|
|
|
|
|
|
|
if password is not None:
|
|
|
|
|
resp = fp.sendcmd('PASS ' + password)
|
|
|
|
|
|
|
|
|
|
logger.debug('No error: %s' % resp)
|
|
|
|
|
logger.debug('No error: %r' % resp)
|
|
|
|
|
self.reset()
|
|
|
|
|
|
|
|
|
|
except FTP_Error as e:
|
|
|
|
|
logger.debug('FTP_Error: %s' % e)
|
|
|
|
|
resp = str(e)
|
|
|
|
|
logger.debug('FTP_Error: %s' % resp)
|
|
|
|
|
|
|
|
|
|
if persistent == '0':
|
|
|
|
|
self.reset()
|
|
|
|
@ -2264,7 +2297,6 @@ class FTP_login(TCP_Cache):
|
|
|
|
|
# }}}
|
|
|
|
|
|
|
|
|
|
# SSH {{{
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
from logging import NullHandler # only available since python 2.7
|
|
|
|
|
except ImportError:
|
|
|
|
@ -2314,10 +2346,10 @@ class SSH_login(TCP_Cache):
|
|
|
|
|
|
|
|
|
|
def execute(self, host, port='22', user=None, password=None, auth_type='password', keyfile=None, persistent='1'):
|
|
|
|
|
|
|
|
|
|
with Timing() as timing:
|
|
|
|
|
fp, banner = self.bind(host, port, user)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
with Timing() as timing:
|
|
|
|
|
fp, banner = self.bind(host, port, user)
|
|
|
|
|
|
|
|
|
|
if user is not None:
|
|
|
|
|
|
|
|
|
|
if keyfile is not None:
|
|
|
|
@ -2359,6 +2391,7 @@ class SSH_login(TCP_Cache):
|
|
|
|
|
|
|
|
|
|
# Telnet {{{
|
|
|
|
|
from telnetlib import Telnet
|
|
|
|
|
|
|
|
|
|
class Telnet_login(TCP_Cache):
|
|
|
|
|
'''Brute-force Telnet'''
|
|
|
|
|
|
|
|
|
@ -2389,7 +2422,8 @@ class Telnet_login(TCP_Cache):
|
|
|
|
|
with Timing() as timing:
|
|
|
|
|
fp, _ = self.bind(host, port, timeout=timeout)
|
|
|
|
|
|
|
|
|
|
trace = ''
|
|
|
|
|
trace = b''
|
|
|
|
|
prompt_re = b(prompt_re)
|
|
|
|
|
timeout = int(timeout)
|
|
|
|
|
|
|
|
|
|
if self.prompt_count == 0:
|
|
|
|
@ -2400,9 +2434,10 @@ class Telnet_login(TCP_Cache):
|
|
|
|
|
|
|
|
|
|
if inputs is not None:
|
|
|
|
|
with Timing() as timing:
|
|
|
|
|
|
|
|
|
|
for val in inputs.split(r'\n'):
|
|
|
|
|
logger.debug('input: %s' % val)
|
|
|
|
|
cmd = val + '\n' #'\r\x00'
|
|
|
|
|
cmd = b(val + '\n') #'\r\x00'
|
|
|
|
|
fp.write(cmd)
|
|
|
|
|
trace += cmd
|
|
|
|
|
|
|
|
|
@ -2414,13 +2449,17 @@ class Telnet_login(TCP_Cache):
|
|
|
|
|
if persistent == '0':
|
|
|
|
|
self.reset()
|
|
|
|
|
|
|
|
|
|
raw = B(raw)
|
|
|
|
|
trace = B(trace)
|
|
|
|
|
|
|
|
|
|
mesg = repr(raw)[1:-1] # strip enclosing single quotes
|
|
|
|
|
return self.Response(0, mesg, timing, trace)
|
|
|
|
|
|
|
|
|
|
# }}}
|
|
|
|
|
|
|
|
|
|
# SMTP {{{
|
|
|
|
|
from smtplib import SMTP, SMTP_SSL, SMTPAuthenticationError, SMTPHeloError, SMTPException
|
|
|
|
|
from smtplib import SMTP, SMTP_SSL, SMTPException, SMTPResponseException
|
|
|
|
|
|
|
|
|
|
class SMTP_Base(TCP_Cache):
|
|
|
|
|
|
|
|
|
|
available_options = TCP_Cache.available_options
|
|
|
|
@ -2482,7 +2521,7 @@ class SMTP_vrfy(SMTP_Base):
|
|
|
|
|
self.reset()
|
|
|
|
|
|
|
|
|
|
code, mesg = resp
|
|
|
|
|
return self.Response(code, mesg, timing)
|
|
|
|
|
return self.Response(code, B(mesg), timing)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SMTP_rcpt(SMTP_Base):
|
|
|
|
@ -2516,7 +2555,7 @@ class SMTP_rcpt(SMTP_Base):
|
|
|
|
|
self.reset()
|
|
|
|
|
|
|
|
|
|
code, mesg = resp
|
|
|
|
|
return self.Response(code, mesg, timing)
|
|
|
|
|
return self.Response(code, B(mesg), timing)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SMTP_login(SMTP_Base):
|
|
|
|
@ -2545,14 +2584,19 @@ class SMTP_login(SMTP_Base):
|
|
|
|
|
logger.debug('No error: %s' % str(resp))
|
|
|
|
|
self.reset()
|
|
|
|
|
|
|
|
|
|
except (SMTPHeloError,SMTPAuthenticationError,SMTPException) as resp:
|
|
|
|
|
logger.debug('SMTPError: %s' % str(resp))
|
|
|
|
|
except SMTPResponseException as e:
|
|
|
|
|
logger.debug('SMTPResponseException: %s' % e)
|
|
|
|
|
resp = e.args
|
|
|
|
|
|
|
|
|
|
except SMTPException as e:
|
|
|
|
|
logger.debug('SMTPException: %s' % e)
|
|
|
|
|
resp = '1', b(str(e))
|
|
|
|
|
|
|
|
|
|
if persistent == '0':
|
|
|
|
|
self.reset()
|
|
|
|
|
|
|
|
|
|
code, mesg = resp
|
|
|
|
|
return self.Response(code, mesg, timing)
|
|
|
|
|
return self.Response(code, B(mesg), timing)
|
|
|
|
|
|
|
|
|
|
# }}}
|
|
|
|
|
|
|
|
|
@ -2595,10 +2639,10 @@ class Finger_lookup:
|
|
|
|
|
s.connect((host, int(port)))
|
|
|
|
|
|
|
|
|
|
if user:
|
|
|
|
|
s.send(user)
|
|
|
|
|
s.send('\r\n')
|
|
|
|
|
s.send(b(user))
|
|
|
|
|
s.send(b'\r\n')
|
|
|
|
|
|
|
|
|
|
data = ''
|
|
|
|
|
data = b''
|
|
|
|
|
with Timing() as timing:
|
|
|
|
|
while True:
|
|
|
|
|
raw = s.recv(1024)
|
|
|
|
@ -2610,7 +2654,7 @@ class Finger_lookup:
|
|
|
|
|
|
|
|
|
|
logger.debug('recv: %r' % data)
|
|
|
|
|
|
|
|
|
|
data = data.strip()
|
|
|
|
|
data = B(data).strip()
|
|
|
|
|
mesg = repr(data)
|
|
|
|
|
|
|
|
|
|
resp = self.Response(0, mesg, timing, data)
|
|
|
|
@ -2668,14 +2712,13 @@ class LDAP_login:
|
|
|
|
|
try:
|
|
|
|
|
from impacket.smbconnection import SMBConnection, SessionError
|
|
|
|
|
from impacket import nt_errors
|
|
|
|
|
from impacket.dcerpc.v5 import transport, lsat, lsad
|
|
|
|
|
from impacket.dcerpc.v5 import transport, lsat, lsad
|
|
|
|
|
from impacket.dcerpc.v5.dtypes import MAXIMUM_ALLOWED
|
|
|
|
|
from impacket.dcerpc.v5.samr import SID_NAME_USE
|
|
|
|
|
except ImportError:
|
|
|
|
|
notfound.append('impacket')
|
|
|
|
|
|
|
|
|
|
class SMB_Connection(TCP_Connection):
|
|
|
|
|
|
|
|
|
|
def close(self):
|
|
|
|
|
self.fp.getSMBServer().get_socket().close()
|
|
|
|
|
|
|
|
|
@ -2743,7 +2786,6 @@ class SMB_login(TCP_Cache):
|
|
|
|
|
return self.Response(code, mesg, timing)
|
|
|
|
|
|
|
|
|
|
class DCE_Connection(TCP_Connection):
|
|
|
|
|
|
|
|
|
|
def __init__(self, fp, smbt):
|
|
|
|
|
self.smbt = smbt
|
|
|
|
|
TCP_Connection.__init__(self, fp)
|
|
|
|
@ -2816,6 +2858,7 @@ class SMB_lookupsid(TCP_Cache):
|
|
|
|
|
|
|
|
|
|
# POP {{{
|
|
|
|
|
from poplib import POP3, POP3_SSL, error_proto as pop_error
|
|
|
|
|
|
|
|
|
|
class POP_Connection(TCP_Connection):
|
|
|
|
|
def close(self):
|
|
|
|
|
self.fp.quit()
|
|
|
|
@ -2916,8 +2959,8 @@ class POP_passd:
|
|
|
|
|
trace += '%s\r\n%s\r\n' % (cmd, resp)
|
|
|
|
|
|
|
|
|
|
except LineReceiver_Error as e:
|
|
|
|
|
logger.debug('LineReceiver_Error: %s' % e)
|
|
|
|
|
resp = str(e)
|
|
|
|
|
logger.debug('LineReceiver_Error: %s' % resp)
|
|
|
|
|
trace += '%s\r\n%s\r\n' % (cmd, resp)
|
|
|
|
|
|
|
|
|
|
finally:
|
|
|
|
@ -2930,6 +2973,7 @@ class POP_passd:
|
|
|
|
|
|
|
|
|
|
# IMAP {{{
|
|
|
|
|
from imaplib import IMAP4, IMAP4_SSL
|
|
|
|
|
|
|
|
|
|
class IMAP_login:
|
|
|
|
|
'''Brute-force IMAP4'''
|
|
|
|
|
|
|
|
|
@ -3019,34 +3063,40 @@ class Rlogin_login(TCP_Cache):
|
|
|
|
|
|
|
|
|
|
fp, _ = self.bind(host, port, timeout=int(timeout))
|
|
|
|
|
|
|
|
|
|
trace = ''
|
|
|
|
|
trace = b''
|
|
|
|
|
timeout = int(timeout)
|
|
|
|
|
|
|
|
|
|
with Timing() as timing:
|
|
|
|
|
if self.need_handshake:
|
|
|
|
|
fp.write('\x00%s\x00%s\x00vt100/9600\x00' % (luser, user))
|
|
|
|
|
fp.write(b('\x00%s\x00%s\x00vt100/9600\x00' % (luser, user)))
|
|
|
|
|
self.need_handshake = False
|
|
|
|
|
else:
|
|
|
|
|
fp.write('%s\r' % user)
|
|
|
|
|
fp.write(b('%s\r' % user))
|
|
|
|
|
|
|
|
|
|
_, _, resp = fp.expect([prompt_re], timeout=timeout) # expecting the Password: prompt
|
|
|
|
|
trace += resp
|
|
|
|
|
|
|
|
|
|
if password is not None:
|
|
|
|
|
fp.write('%s\r' % password)
|
|
|
|
|
fp.write(b('%s\r' % password))
|
|
|
|
|
_, _, resp = fp.expect([prompt_re], timeout=timeout) # expecting the login: prompt
|
|
|
|
|
trace += resp
|
|
|
|
|
|
|
|
|
|
if persistent == '0':
|
|
|
|
|
self.reset()
|
|
|
|
|
|
|
|
|
|
resp = B(resp)
|
|
|
|
|
trace = B(trace)
|
|
|
|
|
|
|
|
|
|
mesg = repr(resp.strip())[1:-1]
|
|
|
|
|
return self.Response(0, mesg, timing, trace)
|
|
|
|
|
# }}}
|
|
|
|
|
|
|
|
|
|
# VMauthd {{{
|
|
|
|
|
from ssl import wrap_socket
|
|
|
|
|
class LineReceiver_Error(Exception): pass
|
|
|
|
|
|
|
|
|
|
class LineReceiver_Error(Exception):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
class LineReceiver:
|
|
|
|
|
|
|
|
|
|
def connect(self, host, port, timeout, ssl=False):
|
|
|
|
@ -3062,15 +3112,15 @@ class LineReceiver:
|
|
|
|
|
self.sock.close()
|
|
|
|
|
|
|
|
|
|
def sendcmd(self, cmd):
|
|
|
|
|
self.sock.sendall(cmd + '\r\n')
|
|
|
|
|
self.sock.sendall(b(cmd + '\r\n'))
|
|
|
|
|
return self.getresp()
|
|
|
|
|
|
|
|
|
|
def getresp(self):
|
|
|
|
|
resp = self.sock.recv(1024)
|
|
|
|
|
while not resp.endswith('\n'):
|
|
|
|
|
while not resp.endswith(b'\n'):
|
|
|
|
|
resp += self.sock.recv(1024)
|
|
|
|
|
|
|
|
|
|
resp = resp.rstrip()
|
|
|
|
|
resp = B(resp).rstrip()
|
|
|
|
|
code, _ = self.parse(resp)
|
|
|
|
|
|
|
|
|
|
if not code.isdigit():
|
|
|
|
@ -3133,8 +3183,8 @@ class VMauthd_login(TCP_Cache):
|
|
|
|
|
trace += '%s\r\n%s\r\n' % (cmd, resp)
|
|
|
|
|
|
|
|
|
|
except LineReceiver_Error as e:
|
|
|
|
|
logger.debug('LineReceiver_Error: %s' % e)
|
|
|
|
|
resp = str(e)
|
|
|
|
|
logger.debug('LineReceiver_Error: %s' % resp)
|
|
|
|
|
trace += '%s\r\n%s\r\n' % (cmd, resp)
|
|
|
|
|
|
|
|
|
|
if persistent == '0':
|
|
|
|
@ -3228,7 +3278,8 @@ try:
|
|
|
|
|
from impacket import tds
|
|
|
|
|
from impacket.tds import TDS_ERROR_TOKEN, TDS_LOGINACK_TOKEN
|
|
|
|
|
except ImportError:
|
|
|
|
|
notfound.append('impacket')
|
|
|
|
|
notfound.append('pyopenssl')
|
|
|
|
|
|
|
|
|
|
class MSSQL_login:
|
|
|
|
|
'''Brute-force MSSQL'''
|
|
|
|
|
|
|
|
|
@ -3291,8 +3342,8 @@ class Oracle_login:
|
|
|
|
|
'''Brute-force Oracle'''
|
|
|
|
|
|
|
|
|
|
usage_hints = (
|
|
|
|
|
"""%prog host=10.0.0.1 sid=FILE0 0=sids.txt -x ignore:code=ORA-12505""",
|
|
|
|
|
"""%prog host=10.0.0.1 user=SYS password=FILE0 0=passwords.txt -x ignore:code=ORA-01017""",
|
|
|
|
|
'''%prog host=10.0.0.1 sid=FILE0 0=sids.txt -x ignore:code=ORA-12505''',
|
|
|
|
|
'''%prog host=10.0.0.1 user=SYS password=FILE0 0=passwords.txt -x ignore:code=ORA-01017''',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
available_options = (
|
|
|
|
@ -3418,14 +3469,18 @@ class Response_HTTP(Response_Base):
|
|
|
|
|
return re.search(val, self.mesg, re.M)
|
|
|
|
|
|
|
|
|
|
def str_target(self):
|
|
|
|
|
return ' '.join('%s=%s' % (k, xmlquoteattr(str(v))) for k, v in self.target.iteritems())
|
|
|
|
|
return ' '.join('%s=%s' % (k, xmlquoteattr(str(v))) for k, v in self.target.items())
|
|
|
|
|
|
|
|
|
|
available_conditions = Response_Base.available_conditions
|
|
|
|
|
available_conditions += (
|
|
|
|
|
('clen', 'match Content-Length header (N or N-M or N- or -N)'),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
from BaseHTTPServer import BaseHTTPRequestHandler
|
|
|
|
|
try:
|
|
|
|
|
from http.server import BaseHTTPRequestHandler
|
|
|
|
|
except ImportError:
|
|
|
|
|
from BaseHTTPServer import BaseHTTPRequestHandler
|
|
|
|
|
|
|
|
|
|
class HTTPRequestParser(BaseHTTPRequestHandler):
|
|
|
|
|
def __init__(self, fd):
|
|
|
|
|
self.rfile = fd
|
|
|
|
@ -3435,7 +3490,8 @@ class HTTPRequestParser(BaseHTTPRequestHandler):
|
|
|
|
|
self.parse_request()
|
|
|
|
|
|
|
|
|
|
if self.command == 'POST':
|
|
|
|
|
self.body = self.rfile.read(-1).rstrip('\r\n')
|
|
|
|
|
self.body = B(self.rfile.read(-1)).rstrip('\r\n')
|
|
|
|
|
|
|
|
|
|
if 'Content-Length' in self.headers:
|
|
|
|
|
del self.headers['Content-Length']
|
|
|
|
|
|
|
|
|
@ -3448,7 +3504,7 @@ class Controller_HTTP(Controller):
|
|
|
|
|
key, val = arg.split('=', 1)
|
|
|
|
|
if key == 'raw_request':
|
|
|
|
|
|
|
|
|
|
with open(val) as fd:
|
|
|
|
|
with open(val, 'rb') as fd:
|
|
|
|
|
r = HTTPRequestParser(fd)
|
|
|
|
|
|
|
|
|
|
if r.error:
|
|
|
|
@ -3466,7 +3522,7 @@ class Controller_HTTP(Controller):
|
|
|
|
|
opts['method'] = r.command
|
|
|
|
|
opts['body'] = r.body
|
|
|
|
|
|
|
|
|
|
for key, val in opts.iteritems():
|
|
|
|
|
for key, val in opts.items():
|
|
|
|
|
if val:
|
|
|
|
|
yield (key, val)
|
|
|
|
|
|
|
|
|
@ -3477,13 +3533,10 @@ class HTTP_fuzz(TCP_Cache):
|
|
|
|
|
'''Brute-force HTTP'''
|
|
|
|
|
|
|
|
|
|
usage_hints = [
|
|
|
|
|
"""%prog url=http://10.0.0.1/FILE0 0=paths.txt -x ignore:code=404 -x ignore,retry:code=500""",
|
|
|
|
|
|
|
|
|
|
"""%prog url=http://10.0.0.1/manager/html user_pass=COMBO00:COMBO01 0=combos.txt"""
|
|
|
|
|
""" -x ignore:code=401""",
|
|
|
|
|
|
|
|
|
|
"""%prog url=http://10.0.0.1/phpmyadmin/index.php method=POST"""
|
|
|
|
|
""" body='pma_username=root&pma_password=FILE0&server=1&lang=en' 0=passwords.txt follow=1"""
|
|
|
|
|
'''%prog url=http://10.0.0.1/FILE0 0=paths.txt -x ignore:code=404 -x ignore,retry:code=500''',
|
|
|
|
|
'''%prog url=http://10.0.0.1/manager/html user_pass=COMBO00:COMBO01 0=combos.txt -x ignore:code=401''',
|
|
|
|
|
'''%prog url=http://10.0.0.1/phpmyadmin/index.php method=POST'''
|
|
|
|
|
''' body='pma_username=root&pma_password=FILE0&server=1&lang=en' 0=passwords.txt follow=1'''
|
|
|
|
|
""" accept_cookie=1 -x ignore:fgrep='Cannot log in to the MySQL server'""",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
@ -3574,9 +3627,14 @@ class HTTP_fuzz(TCP_Cache):
|
|
|
|
|
if max_mem > 0 and trace.tell() > max_mem:
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
s = B(s)
|
|
|
|
|
|
|
|
|
|
if t in (pycurl.INFOTYPE_HEADER_OUT, pycurl.INFOTYPE_DATA_OUT):
|
|
|
|
|
trace.write(s)
|
|
|
|
|
|
|
|
|
|
elif t == pycurl.INFOTYPE_TEXT and b'upload completely sent off' in s:
|
|
|
|
|
trace.write('\n\n')
|
|
|
|
|
|
|
|
|
|
elif t in (pycurl.INFOTYPE_HEADER_IN, pycurl.INFOTYPE_DATA_IN):
|
|
|
|
|
trace.write(s)
|
|
|
|
|
response.write(s)
|
|
|
|
@ -3697,12 +3755,12 @@ class Response_AJP(Response_HTTP):
|
|
|
|
|
self.status_msg = status_msg
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return self.status_msg or self.mesg
|
|
|
|
|
return self.status_msg or self.mesg
|
|
|
|
|
|
|
|
|
|
def prepare_ajp_forward_request(target_host, req_uri, method):
|
|
|
|
|
fr = AjpForwardRequest(AjpForwardRequest.SERVER_TO_CONTAINER)
|
|
|
|
|
fr.method = method
|
|
|
|
|
fr.protocol = "HTTP/1.1"
|
|
|
|
|
fr.protocol = 'HTTP/1.1'
|
|
|
|
|
fr.req_uri = req_uri
|
|
|
|
|
fr.remote_addr = target_host
|
|
|
|
|
fr.remote_host = None
|
|
|
|
@ -3728,9 +3786,8 @@ class AJP_fuzz(TCP_Cache):
|
|
|
|
|
'''Brute-force AJP'''
|
|
|
|
|
|
|
|
|
|
usage_hints = [
|
|
|
|
|
"""%prog url=ajp://10.0.0.1/FILE0 0=paths.txt -x ignore:code=404 -x ignore,retry:code=500""",
|
|
|
|
|
"""%prog url=ajp://10.0.0.1/manager/html user_pass=COMBO00:COMBO01 0=combos.txt"""
|
|
|
|
|
""" -x ignore:code=401""",
|
|
|
|
|
'''%prog url=ajp://10.0.0.1/FILE0 0=paths.txt -x ignore:code=404 -x ignore,retry:code=500''',
|
|
|
|
|
'''%prog url=ajp://10.0.0.1/manager/html user_pass=COMBO00:COMBO01 0=combos.txt -x ignore:code=401''',
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
available_options = (
|
|
|
|
@ -3801,7 +3858,7 @@ class RDP_login:
|
|
|
|
|
'''Brute-force RDP (NLA)'''
|
|
|
|
|
|
|
|
|
|
usage_hints = (
|
|
|
|
|
"""%prog host=10.0.0.1 user='administrator' password=FILE0 0=passwords.txt""",
|
|
|
|
|
'''%prog host=10.0.0.1 user='administrator' password=FILE0 0=passwords.txt''',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
available_options = (
|
|
|
|
@ -3820,7 +3877,7 @@ class RDP_login:
|
|
|
|
|
|
|
|
|
|
with Timing() as timing:
|
|
|
|
|
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
|
out, err = p.communicate()
|
|
|
|
|
out, err = map(B, p.communicate())
|
|
|
|
|
code = p.returncode
|
|
|
|
|
|
|
|
|
|
err = err.replace('''Authentication only. Don't connect to X.
|
|
|
|
@ -3847,35 +3904,37 @@ try:
|
|
|
|
|
except ImportError:
|
|
|
|
|
notfound.append('pycrypto')
|
|
|
|
|
|
|
|
|
|
class VNC_Error(Exception): pass
|
|
|
|
|
class VNC_Error(Exception):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
class VNC:
|
|
|
|
|
def connect(self, host, port, timeout):
|
|
|
|
|
self.fp = socket.create_connection((host, port), timeout=timeout)
|
|
|
|
|
resp = self.fp.recv(99) # banner
|
|
|
|
|
|
|
|
|
|
logger.debug('banner: %r' % resp)
|
|
|
|
|
self.version = resp[:11].decode('ascii')
|
|
|
|
|
self.version = B(resp[:11])
|
|
|
|
|
|
|
|
|
|
if len(resp) > 12:
|
|
|
|
|
raise VNC_Error('%s %s' % (self.version, resp[12:].decode('ascii', 'ignore')))
|
|
|
|
|
raise VNC_Error('%s %r' % (self.version, B(resp[12:])))
|
|
|
|
|
|
|
|
|
|
return self.version
|
|
|
|
|
|
|
|
|
|
def login(self, password):
|
|
|
|
|
logger.debug('Remote version: %s' % self.version)
|
|
|
|
|
logger.debug('Remote version: %r' % self.version)
|
|
|
|
|
major, minor = self.version[6], self.version[10]
|
|
|
|
|
|
|
|
|
|
if (major, minor) in [('3', '8'), ('4', '1')]:
|
|
|
|
|
proto = b'RFB 003.008\n'
|
|
|
|
|
proto = 'RFB 003.008\n'
|
|
|
|
|
|
|
|
|
|
elif (major, minor) == ('3', '7'):
|
|
|
|
|
proto = b'RFB 003.007\n'
|
|
|
|
|
proto = 'RFB 003.007\n'
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
proto = b'RFB 003.003\n'
|
|
|
|
|
proto = 'RFB 003.003\n'
|
|
|
|
|
|
|
|
|
|
logger.debug('Client version: %s' % proto[:-1])
|
|
|
|
|
self.fp.sendall(proto)
|
|
|
|
|
logger.debug('Client version: %r' % proto[:-1])
|
|
|
|
|
self.fp.sendall(b(proto))
|
|
|
|
|
|
|
|
|
|
sleep(0.5)
|
|
|
|
|
|
|
|
|
@ -3885,7 +3944,7 @@ class VNC:
|
|
|
|
|
if major == '4' or (major == '3' and int(minor) >= 7):
|
|
|
|
|
code = ord(resp[0:1])
|
|
|
|
|
if code == 0:
|
|
|
|
|
raise VNC_Error('Session setup failed: %s' % resp.decode('ascii', 'ignore'))
|
|
|
|
|
raise VNC_Error('Session setup failed: %s' % B(resp))
|
|
|
|
|
|
|
|
|
|
self.fp.sendall(b'\x02') # always use classic VNC authentication
|
|
|
|
|
resp = self.fp.recv(99)
|
|
|
|
@ -3893,7 +3952,7 @@ class VNC:
|
|
|
|
|
else: # minor == '3':
|
|
|
|
|
code = ord(resp[3:4])
|
|
|
|
|
if code != 2:
|
|
|
|
|
raise VNC_Error('Session setup failed: %s' % resp.decode('ascii', 'ignore'))
|
|
|
|
|
raise VNC_Error('Session setup failed: %s' % B(resp))
|
|
|
|
|
|
|
|
|
|
resp = resp[-16:]
|
|
|
|
|
|
|
|
|
@ -3916,7 +3975,7 @@ class VNC:
|
|
|
|
|
logger.debug('resp: %r' % resp)
|
|
|
|
|
|
|
|
|
|
code = ord(resp[3:4])
|
|
|
|
|
mesg = resp[8:].decode('ascii', 'ignore')
|
|
|
|
|
mesg = B(resp[8:])
|
|
|
|
|
|
|
|
|
|
if code == 1:
|
|
|
|
|
return code, mesg or 'Authentication failure'
|
|
|
|
@ -3938,17 +3997,16 @@ class VNC:
|
|
|
|
|
btgt = btgt | (1 << 7-i)
|
|
|
|
|
newkey.append(btgt)
|
|
|
|
|
|
|
|
|
|
if sys.version_info[0] == 2:
|
|
|
|
|
return ''.join(chr(c) for c in newkey)
|
|
|
|
|
else:
|
|
|
|
|
if PY3:
|
|
|
|
|
return bytes(newkey)
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
return ''.join(chr(c) for c in newkey)
|
|
|
|
|
|
|
|
|
|
class VNC_login:
|
|
|
|
|
'''Brute-force VNC'''
|
|
|
|
|
|
|
|
|
|
usage_hints = (
|
|
|
|
|
"""%prog host=10.0.0.1 password=FILE0 0=passwords.txt -t 1 -x retry:fgrep!='Authentication failure' --max-retries -1 -x quit:code=0""",
|
|
|
|
|
'''%prog host=10.0.0.1 password=FILE0 0=passwords.txt -t 1 -x retry:fgrep!='Authentication failure' --max-retries -1 -x quit:code=0''',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
available_options = (
|
|
|
|
@ -3981,7 +4039,6 @@ class VNC_login:
|
|
|
|
|
# }}}
|
|
|
|
|
|
|
|
|
|
# DNS {{{
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
import dns.rdatatype
|
|
|
|
|
import dns.message
|
|
|
|
@ -4252,13 +4309,12 @@ class Controller_DNS(Controller):
|
|
|
|
|
name, data = name[:-1], data[:-1]
|
|
|
|
|
self.hostmap[data].alias.add(name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DNS_reverse:
|
|
|
|
|
'''Reverse DNS lookup'''
|
|
|
|
|
|
|
|
|
|
usage_hints = [
|
|
|
|
|
"""%prog host=NET0 0=192.168.0.0/24 -x ignore:code=3""",
|
|
|
|
|
"""%prog host=NET0 0=216.239.32.0-216.239.47.255,8.8.8.0/24 -x ignore:code=3 -x ignore:fgrep!=google.com -x ignore:fgrep=216-239-""",
|
|
|
|
|
'''%prog host=NET0 0=192.168.0.0/24 -x ignore:code=3''',
|
|
|
|
|
'''%prog host=NET0 0=216.239.32.0-216.239.47.255,8.8.8.0/24 -x ignore:code=3 -x ignore:fgrep!=google.com -x ignore:fgrep=216-239-''',
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
available_options = (
|
|
|
|
@ -4291,9 +4347,9 @@ class DNS_forward:
|
|
|
|
|
'''Forward DNS lookup'''
|
|
|
|
|
|
|
|
|
|
usage_hints = [
|
|
|
|
|
"""%prog name=FILE0.google.com 0=names.txt -x ignore:code=3""",
|
|
|
|
|
"""%prog name=google.MOD0 0=TLD -x ignore:code=3""",
|
|
|
|
|
"""%prog name=MOD0.microsoft.com 0=SRV qtype=SRV -x ignore:code=3""",
|
|
|
|
|
'''%prog name=FILE0.google.com 0=names.txt -x ignore:code=3''',
|
|
|
|
|
'''%prog name=google.MOD0 0=TLD -x ignore:code=3''',
|
|
|
|
|
'''%prog name=MOD0.microsoft.com 0=SRV qtype=SRV -x ignore:code=3''',
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
available_options = (
|
|
|
|
@ -4337,6 +4393,11 @@ try:
|
|
|
|
|
except ImportError:
|
|
|
|
|
notfound.append('pysnmp')
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
import pyasn1
|
|
|
|
|
except ImportError:
|
|
|
|
|
notfound.append('pyasn1')
|
|
|
|
|
|
|
|
|
|
class SNMP_login:
|
|
|
|
|
'''Brute-force SNMP v1/2/3'''
|
|
|
|
|
|
|
|
|
@ -4412,7 +4473,7 @@ IKE_GROUP = [('1', 'modp768'), ('2', 'modp1024'), ('5', 'modp1536'),
|
|
|
|
|
# '27', '28', '29', '30', # RFC6932
|
|
|
|
|
|
|
|
|
|
def generate_transforms():
|
|
|
|
|
lists = map(lambda l: [i[0] for i in l], [IKE_ENC, IKE_HASH, IKE_AUTH, IKE_GROUP])
|
|
|
|
|
lists = list(map(lambda l: [i[0] for i in l], [IKE_ENC, IKE_HASH, IKE_AUTH, IKE_GROUP]))
|
|
|
|
|
return map(lambda p: ','.join(p), product(*[chain(l) for l in lists])), reduce(lambda x,y: x*y, map(len, lists))
|
|
|
|
|
|
|
|
|
|
class Controller_IKE(Controller):
|
|
|
|
@ -4443,7 +4504,7 @@ class Controller_IKE(Controller):
|
|
|
|
|
ike_ath = dict(IKE_AUTH)
|
|
|
|
|
ike_grp = dict(IKE_GROUP)
|
|
|
|
|
|
|
|
|
|
for endpoint, transforms in self.results.iteritems():
|
|
|
|
|
for endpoint, transforms in self.results.items():
|
|
|
|
|
print('\n+ %s' % endpoint)
|
|
|
|
|
print(' %10s %10s %12s %10s' % ('Encryption', 'Hash', 'Auth', 'Group'))
|
|
|
|
|
print(' %10s %10s %12s %10s' % ('-'*10, '-'*10, '-'*10, '-'*10))
|
|
|
|
@ -4464,8 +4525,8 @@ class IKE_enum:
|
|
|
|
|
'''Enumerate IKE transforms'''
|
|
|
|
|
|
|
|
|
|
usage_hints = [
|
|
|
|
|
"""%prog host=10.0.0.1 transform=MOD0 0=TRANS -x ignore:fgrep=NO-PROPOSAL""",
|
|
|
|
|
"""%prog host=10.0.0.1 transform=MOD0 0=TRANS -x ignore:fgrep=NO-PROPOSAL aggressive=RANGE1 1=int:0-1""",
|
|
|
|
|
'''%prog host=10.0.0.1 transform=MOD0 0=TRANS -x ignore:fgrep=NO-PROPOSAL''',
|
|
|
|
|
'''%prog host=10.0.0.1 transform=MOD0 0=TRANS -x ignore:fgrep=NO-PROPOSAL aggressive=RANGE1 1=int:0-1''',
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
available_options = (
|
|
|
|
@ -4486,7 +4547,7 @@ class IKE_enum:
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
uid = multiprocessing.current_process().name[9:]
|
|
|
|
|
self.sport = '51%s' % uid
|
|
|
|
|
self.sport = '51%d' % int(uid)
|
|
|
|
|
|
|
|
|
|
def execute(self, host, port='500', transform='5,1,1,2', aggressive='0', groupname='foo', vid=''):
|
|
|
|
|
|
|
|
|
@ -4500,7 +4561,7 @@ class IKE_enum:
|
|
|
|
|
|
|
|
|
|
with Timing() as timing:
|
|
|
|
|
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
|
out, err = p.communicate()
|
|
|
|
|
out, err = map(B, p.communicate())
|
|
|
|
|
code = p.returncode
|
|
|
|
|
|
|
|
|
|
trace = '%s\n[out]\n%s\n[err]\n%s' % (cmd, out, err)
|
|
|
|
@ -4532,7 +4593,7 @@ class Unzip_pass:
|
|
|
|
|
'''Brute-force the password of encrypted ZIP files'''
|
|
|
|
|
|
|
|
|
|
usage_hints = [
|
|
|
|
|
"""%prog zipfile=path/to/file.zip password=FILE0 0=passwords.txt -x ignore:code!=0""",
|
|
|
|
|
"""%prog zipfile=file.zip password=FILE0 0=passwords.txt -x ignore:code!=0""",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
available_options = (
|
|
|
|
@ -4550,7 +4611,7 @@ class Unzip_pass:
|
|
|
|
|
|
|
|
|
|
with Timing() as timing:
|
|
|
|
|
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
|
out, err = p.communicate()
|
|
|
|
|
out, err = map(B, p.communicate())
|
|
|
|
|
code = p.returncode
|
|
|
|
|
|
|
|
|
|
mesg = repr(out.strip())[1:-1]
|
|
|
|
@ -4568,7 +4629,7 @@ class Keystore_pass:
|
|
|
|
|
'''Brute-force the password of Java keystore files'''
|
|
|
|
|
|
|
|
|
|
usage_hints = [
|
|
|
|
|
"""%prog keystore=path/to/keystore.jks password=FILE0 0=passwords.txt -x ignore:fgrep='password was incorrect'""",
|
|
|
|
|
"""%prog keystore=keystore.jks password=FILE0 0=passwords.txt -x ignore:fgrep='password was incorrect'""",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
available_options = (
|
|
|
|
@ -4587,7 +4648,7 @@ class Keystore_pass:
|
|
|
|
|
|
|
|
|
|
with Timing() as timing:
|
|
|
|
|
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
|
out, err = p.communicate()
|
|
|
|
|
out, err = map(B, p.communicate())
|
|
|
|
|
code = p.returncode
|
|
|
|
|
|
|
|
|
|
mesg = repr(out.strip())[1:-1]
|
|
|
|
@ -4607,7 +4668,7 @@ class SQLCipher_pass:
|
|
|
|
|
'''Brute-force the password of SQLCipher-encrypted databases'''
|
|
|
|
|
|
|
|
|
|
usage_hints = [
|
|
|
|
|
"""%prog database=path/to/db.sqlite password=FILE0 0=passwords.txt -x ignore:fgrep='file is encrypted'""",
|
|
|
|
|
"""%prog database=db.sqlite password=FILE0 0=passwords.txt -x ignore:fgrep='file is encrypted'""",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
available_options = (
|
|
|
|
@ -4636,11 +4697,12 @@ class SQLCipher_pass:
|
|
|
|
|
|
|
|
|
|
# Umbraco {{{
|
|
|
|
|
import hmac
|
|
|
|
|
|
|
|
|
|
class Umbraco_crack:
|
|
|
|
|
'''Crack Umbraco HMAC-SHA1 password hashes'''
|
|
|
|
|
|
|
|
|
|
usage_hints = (
|
|
|
|
|
"""%prog hashlist=@umbraco_users.pw password=FILE0 0=rockyou.txt""",
|
|
|
|
|
'''%prog hashlist=@umbraco_users.pw password=FILE0 0=passwords.txt''',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
available_options = (
|
|
|
|
@ -4654,7 +4716,7 @@ class Umbraco_crack:
|
|
|
|
|
def execute(self, password, hashlist):
|
|
|
|
|
|
|
|
|
|
p = password.encode('utf-16-le')
|
|
|
|
|
h = b64encode(hmac.new(p, p, digestmod=hashlib.sha1).digest())
|
|
|
|
|
h = B(b64encode(hmac.new(p, p, digestmod=hashlib.sha1).digest()))
|
|
|
|
|
|
|
|
|
|
if h not in hashlist:
|
|
|
|
|
code, mesg = 1, 'fail'
|
|
|
|
@ -4768,25 +4830,27 @@ modules = [
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
dependencies = {
|
|
|
|
|
'paramiko': [('ssh_login',), 'http://www.lag.net/paramiko/', '1.7.7.1'],
|
|
|
|
|
'pycurl': [('http_fuzz',), 'http://pycurl.sourceforge.net/', '7.43.0'],
|
|
|
|
|
'paramiko': [('ssh_login',), 'http://www.paramiko.org/', '1.7.7.1'],
|
|
|
|
|
'pycurl': [('http_fuzz',), 'http://pycurl.io/', '7.43.0'],
|
|
|
|
|
'libcurl': [('http_fuzz',), 'https://curl.haxx.se/', '7.21.0'],
|
|
|
|
|
'ajpy': [('ajp_fuzz',), 'https://github.com/hypn0s/AJPy/', '0.0.1'],
|
|
|
|
|
'openldap': [('ldap_login',), 'http://www.openldap.org/', '2.4.24'],
|
|
|
|
|
'impacket': [('smb_login','smb_lookupsid','mssql_login'), 'https://github.com/CoreSecurity/impacket', '0.9.12'],
|
|
|
|
|
'impacket': [('smb_login', 'smb_lookupsid', 'mssql_login'), 'https://github.com/CoreSecurity/impacket', '0.9.12'],
|
|
|
|
|
'pyopenssl': [('mssql_login',), 'https://pyopenssl.org/', '17.5.0'],
|
|
|
|
|
'cx_Oracle': [('oracle_login',), 'http://cx-oracle.sourceforge.net/', '5.1.1'],
|
|
|
|
|
'mysqlclient': [('mysql_login',), 'https://github.com/PyMySQL/mysqlclient-python', '1.3.12'],
|
|
|
|
|
'xfreerdp': [('rdp_login',), 'https://github.com/FreeRDP/FreeRDP.git', '1.2.0-beta1'],
|
|
|
|
|
'psycopg': [('pgsql_login',), 'http://initd.org/psycopg/', '2.4.5'],
|
|
|
|
|
'pycrypto': [('vnc_login',), 'http://www.dlitz.net/software/pycrypto/', '2.3'],
|
|
|
|
|
'pycrypto': [('smb_login', 'smb_lookupsid', 'mssql_login', 'vnc_login',), 'http://www.dlitz.net/software/pycrypto/', '2.6.1'],
|
|
|
|
|
'dnspython': [('dns_reverse', 'dns_forward'), 'http://www.dnspython.org/', '1.10.0'],
|
|
|
|
|
'IPy': [('dns_reverse', 'dns_forward'), 'https://github.com/haypo/python-ipy', '0.75'],
|
|
|
|
|
'pysnmp': [('snmp_login',), 'http://pysnmp.sf.net/', '4.2.1'],
|
|
|
|
|
'pyasn1': [('smb_login', 'smb_lookupsid', 'mssql_login', 'snmp_login'), 'http://sourceforge.net/projects/pyasn1/', '0.1.2'],
|
|
|
|
|
'ike-scan': [('ike_enum',), 'http://www.nta-monitor.com/tools-resources/security-tools/ike-scan', '1.9'],
|
|
|
|
|
'unzip': [('unzip_pass',), 'http://www.info-zip.org/', '6.0'],
|
|
|
|
|
'java': [('keystore_pass',), 'http://www.oracle.com/technetwork/java/javase/', '6'],
|
|
|
|
|
'pysqlcipher': [('sqlcipher_pass',), 'https://github.com/leapcode/pysqlcipher/', '2.6.10'],
|
|
|
|
|
'ftp-tls': [('ftp_login',), 'TLS support unavailable before python 2.7'],
|
|
|
|
|
'python': [('ftp_login',), 'Patator requires Python 2.7 or above. Some features may be unavailable otherwise, such as TLS support for FTP.'],
|
|
|
|
|
}
|
|
|
|
|
# }}}
|
|
|
|
|
|
|
|
|
|