From 097870d4f18e19ef9a9bcfd26d5708fad8ad057b Mon Sep 17 00:00:00 2001 From: lanjelot Date: Tue, 10 Jul 2012 15:09:59 -1000 Subject: [PATCH] added a timeout option for telnet_login and smtp_* --- patator.py | 78 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/patator.py b/patator.py index f9d7a18..ef20ada 100755 --- a/patator.py +++ b/patator.py @@ -61,14 +61,14 @@ Future modules to be implemented: - pop3_login The name "Patator" comes from http://www.youtube.com/watch?v=xoBkBvnTTjo -"Whatever the payload to fire, always use the same launch tube" +"Whatever the payload to fire, always use the same cannon" * Why ? -Basically, I got tired of using Medusa, Hydra, ncrack, metasploit auxiliary modules, nmap NSE scripts and the like because: +Basically, I got tired of using Medusa, Hydra, Ncrack, Metasploit auxiliary modules, Nmap NSE scripts and the like because: - they either do not work or are not reliable (got me false negatives several times in the past) - - they are slow (not multi-threaded or not testing multiple passwords within the same TCP connection) - - they lack very useful features that are easy to code in python (eg. interactive runtime) + - they are not flexible enough (eg. how to iterate over all wordlists, fuzz any module parameter) + - they lack useful features (eg. display progress or pause during execution) FEATURES @@ -95,12 +95,12 @@ FEATURES * Multi-threaded * Flexible user input - - Any part of a payload is fuzzable: + - Any module parameter can be fuzzed: + use FILE[0-9] keywords to iterate on a file + use COMBO[0-9] keywords to iterate on the combo entries of a file + use NET[0-9] keywords to iterate on every host of a network subnet - - Iteration over the joined wordlists may be done in any order + - Iteration over the joined wordlists can be done in any order * Save every response (along with request) to seperate log files for later reviewing @@ -178,16 +178,16 @@ For instance, this would be the classic order: 10.0.0.1 root 123456 10.0.0.1 root qsdfghj .... -10.0.0.1 test password -10.0.0.1 test 123456 -10.0.0.1 test qsdfghj +10.0.0.1 admin password +10.0.0.1 admin 123456 +10.0.0.1 admin qsdfghj ... 10.0.0.2 root password ... While a smarter way might be: --------- -./module host=FILE2 password=FILE1 user=FILE0 0=logins.txt 1=passwords.txt 2=hosts.txt +./module host=FILE2 user=FILE1 password=FILE0 2=hosts.txt 1=logins.txt 0=passwords.txt 10.0.0.1 root password 10.0.0.2 root password 10.0.0.1 admin password @@ -484,13 +484,6 @@ blacklists the attacker IP address after too many wrong passwords. vnc_login host=10.0.0.1 password=FILE0 0=passwords.txt --threads 1 -x retry:fgrep!='Authentication failure' --max-retries -1 -x quit:code=0 (b) (b) (c) -}}} -{{{ Unzip - -* 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 - }}} {{{ DNS @@ -537,6 +530,13 @@ snmp_login host=10.0.0.1 version=3 user=myuser auth_key=FILE0 0=passwords.txt -x NB0. If you get "notInTimeWindow" error messages, increase the retries option. NB1. SNMPv3 requires passphrases to be at least 8 characters long. +}}} +{{{ Unzip + +* 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 + }}} CHANGELOG @@ -862,7 +862,7 @@ Please read the README inside for more examples and usage information. wlists = {} kargs = [] - for arg in args: # ('host=NET0', '0=10.0.0.0/24', 'user=COMBO10', 'password=COMBO11', '1=combos.txt', 'domain=google.MOD2', '2=TLD') + for arg in args: # ('host=NET0', '0=10.0.0.0/24', 'user=COMBO10', 'password=COMBO11', '1=combos.txt', 'name=google.MOD2', '2=TLD') for k, v in self.expand_key(arg): logger.debug('k: %s, v: %s' % (k, v)) @@ -920,7 +920,7 @@ Please read the README inside for more examples and usage information. else: self.payload[k] = v - logger.debug('iter_keys: %s' % self.iter_keys) # { 0: ('NET', '10.0.0.0/24', ['host']), 1: ('COMBO', 'combos.txt', [(0, 'user'), (1, 'password')]), 2: ('MOD', 'TLD', ['domain']) + logger.debug('iter_keys: %s' % self.iter_keys) # { 0: ('NET', '10.0.0.0/24', ['host']), 1: ('COMBO', 'combos.txt', [(0, 'user'), (1, 'password')]), 2: ('MOD', 'TLD', ['name']) logger.debug('enc_keys: %s' % self.enc_keys) # [('password', 'ENC', hexlify), ('header', 'B64', b64encode), ... logger.debug('payload: %s' % self.payload) @@ -1469,11 +1469,11 @@ class TCP_Cache: for _, c in self.cache.items(): c.close() - def bind(self, *args): - + def bind(self, *args, **kwargs): + # *args identify one connection in the cache while **kwargs are only options key = ':'.join(args) if key not in self.cache: - self.conn = self.cache[key] = self.connect(*args) + self.conn = self.cache[key] = self.connect(*args, **kwargs) else: self.conn = self.cache[key] @@ -1512,15 +1512,15 @@ class FTP_login(TCP_Cache): Response = Response_Base - def connect(self, host, port): - fp = FTP(timeout=int(self.timeout)) + def connect(self, host, port, timeout): + fp = FTP(timeout=int(timeout)) banner = fp.connect(host, int(port)) return TCP_Connection(fp, banner) def execute(self, host, port='21', user=None, password=None, timeout='10', persistent='1'): - self.timeout = timeout - fp, resp = self.bind(host, port) + + fp, resp = self.bind(host, port, timeout=timeout) try: if user is not None: @@ -1690,21 +1690,22 @@ class Telnet_login(TCP_Cache): ('port', 'ports to target [23]'), ('inputs', 'list of values to input'), ('prompt_re', 'regular expression to match prompts [\w+]'), - ('timeout', 'seconds to wait for prompt_re to match received data [20]'), + ('timeout', 'seconds to wait for a response and for prompt_re to match received data [20]'), ) available_options += TCP_Cache.available_options Response = Response_Base - def connect(self, host, port): + def connect(self, host, port, timeout): self.prompt_count = 0 - fp = Telnet(host, int(port)) + fp = Telnet(host, int(port), int(timeout)) return TCP_Connection(fp) def execute(self, host, port='23', inputs=None, prompt_re='\w+:', timeout='20', persistent='1'): - fp, _ = self.bind(host, port) + fp, _ = self.bind(host, port, timeout=timeout) + trace = '' timeout = int(timeout) @@ -1740,6 +1741,7 @@ class SMTP_Base(TCP_Cache): available_options = TCP_Cache.available_options available_options += ( + ('timeout', 'seconds to wait for a response [10]'), ('host', 'hostnames or subnets to target'), ('port', 'ports to target [25]'), ('helo', 'first command to send after connect [None]'), @@ -1748,8 +1750,8 @@ class SMTP_Base(TCP_Cache): Response = Response_Base - def connect(self, host, port, helo): - fp = SMTP() + def connect(self, host, port, helo, timeout): + fp = SMTP(timeout=int(timeout)) resp = fp.connect(host, int(port)) if helo: @@ -1771,9 +1773,9 @@ class SMTP_vrfy(SMTP_Base): ''' -x ignore:fgrep='User unknown' -x ignore,reset,retry:code=421''', ) - def execute(self, host, port='25', helo='', user=None, persistent='1'): + def execute(self, host, port='25', helo='', user=None, timeout='10', persistent='1'): - fp, resp = self.bind(host, port, helo) + fp, resp = self.bind(host, port, helo, timeout=timeout) if user is not None: resp = fp.verify(user) @@ -1798,9 +1800,9 @@ class SMTP_rcpt(SMTP_Base): ('mail_from', 'sender email [test@example.org]'), ) - def execute(self, host, port='25', helo='', mail_from='test@example.org', user=None, persistent='1'): + def execute(self, host, port='25', helo='', mail_from='test@example.org', user=None, timeout='10', persistent='1'): - fp, resp = self.bind(host, port, helo) + fp, resp = self.bind(host, port, helo, timeout=timeout) if mail_from: resp = fp.mail(mail_from) @@ -1830,9 +1832,9 @@ class SMTP_login(SMTP_Base): ('password', 'passwords to test'), ) - def execute(self, host, port='25', helo=None, user=None, password=None, persistent='1'): + def execute(self, host, port='25', helo=None, user=None, password=None, timeout='10', persistent='1'): - fp, resp = self.bind(host, port, helo) + fp, resp = self.bind(host, port, helo, timeout=timeout) try: if user is not None and password is not None: