resume wont overwrite logs, interactive -x wont crash

pull/4/merge
lanjelot 11 years ago
parent ba6e6a8c6b
commit 251f33cd08

@ -12,10 +12,11 @@
# details (http://www.gnu.org/licenses/gpl.txt). # details (http://www.gnu.org/licenses/gpl.txt).
__author__ = 'Sebastien Macke' __author__ = 'Sebastien Macke'
__twitter__ = '@lanjelot'
__email__ = 'patator@hsc.fr' __email__ = 'patator@hsc.fr'
__url__ = 'http://www.hsc.fr/ressources/outils/patator/' __url__ = 'http://www.hsc.fr/ressources/outils/patator/'
__git__ = 'http://code.google.com/p/patator/' __git__ = 'http://code.google.com/p/patator/'
__version__ = '0.4' __version__ = '0.5-beta'
__license__ = 'GPLv2' __license__ = 'GPLv2'
__banner__ = 'Patator v%s (%s)' % (__version__, __git__) __banner__ = 'Patator v%s (%s)' % (__version__, __git__)
@ -85,8 +86,8 @@ FEATURES
+ not limited to brute-forcing (eg. remote exploit testing, or vulnerable version probing) + not limited to brute-forcing (eg. remote exploit testing, or vulnerable version probing)
* Interactive runtime * Interactive runtime
+ show verbose progress + show progress during execution (press Enter)
+ pause/unpause execution + pause/unpause execution (press p)
+ increase/decrease verbosity + increase/decrease verbosity
+ add new actions & conditions during runtime (eg. to exclude more types of response from showing) + add new actions & conditions during runtime (eg. to exclude more types of response from showing)
+ ... press h to see all available interactive commands + ... press h to see all available interactive commands
@ -234,8 +235,8 @@ instance. A failure is actually an exception that the module does not expect,
and as a result the exception is caught upstream by the controller. and as a result the exception is caught upstream by the controller.
Such exceptions, or failures, are not immediately reported to the user, the Such exceptions, or failures, are not immediately reported to the user, the
controller will retry 4 more times before reporting the failed payload with the controller will retry 4 more times (see --max-retries) before reporting the
code "xxx" (--max-retries defaults to 4). failed payload with logging level ERROR.
* Read carefully the following examples to get a good understanding of how patator works. * Read carefully the following examples to get a good understanding of how patator works.
@ -608,7 +609,7 @@ import os
from sys import stdin, exc_info, exit, version_info from sys import stdin, exc_info, exit, version_info
from time import localtime, strftime, sleep, time from time import localtime, strftime, sleep, time
from functools import reduce from functools import reduce
from threading import Thread, active_count, Lock from threading import Thread, active_count
from select import select from select import select
from itertools import product, chain, islice from itertools import product, chain, islice
from string import ascii_lowercase from string import ascii_lowercase
@ -665,15 +666,14 @@ def create_dir(top_path, from_stdin=False):
files = os.listdir(top_path) files = os.listdir(top_path)
if files: if files:
if not from_stdin: if not from_stdin:
if raw_input("Directory '%s' is not empty, do you want to wipe it ? [Y/n]: " % top_path) == 'n': if raw_input("Directory '%s' is not empty, do you want to wipe it ? [Y/n]: " % top_path) != 'n':
exit(0) for root, dirs, files in os.walk(top_path):
for root, dirs, files in os.walk(top_path): if dirs:
if dirs: print("Directory '%s' contains sub-directories, safely aborting..." % root)
print("Directory '%s' contains sub-directories, safely aborting..." % root) exit(0)
exit(0) for f in files:
for f in files: os.unlink(os.path.join(root, f))
os.unlink(os.path.join(root, f)) break
break
else: else:
os.mkdir(top_path) os.mkdir(top_path)
return top_path return top_path
@ -854,7 +854,7 @@ Please read the README inside for more examples and usage information.
self.from_stdin = False self.from_stdin = False
self.start_time = 0 self.start_time = 0
self.total_size = 1 self.total_size = 1
self.stop_now = False self.quit_now = False
self.log_dir = None self.log_dir = None
self.thread_report = [] self.thread_report = []
self.thread_progress = [] self.thread_progress = []
@ -952,7 +952,7 @@ Please read the README inside for more examples and usage information.
if self.log_dir: if self.log_dir:
log_file = os.path.join(self.log_dir, 'RUNTIME.log') log_file = os.path.join(self.log_dir, 'RUNTIME.log')
with open(log_file, 'w') as f: with open(log_file, 'a') as f:
f.write('$ %s\n' % ' '.join(argv)) f.write('$ %s\n' % ' '.join(argv))
handler = logging.FileHandler(log_file) handler = logging.FileHandler(log_file)
@ -1015,26 +1015,20 @@ Please read the README inside for more examples and usage information.
logger.info('Starting %s at %s' % (__banner__, strftime('%Y-%m-%d %H:%M %Z', localtime()))) logger.info('Starting %s at %s' % (__banner__, strftime('%Y-%m-%d %H:%M %Z', localtime())))
try: try:
tryok = False
self.start_threads() self.start_threads()
self.monitor_progress() self.monitor_progress()
tryok = True
except SystemExit:
logger.info('Quitting')
except KeyboardInterrupt: except KeyboardInterrupt:
print self.quit_now = True
except: except:
self.quit_now = True
logger.exception(exc_info()[1]) logger.exception(exc_info()[1])
if not tryok: try:
self.stop_now = True while active_count() > 1:
try: sleep(.1)
while active_count() > 1: self.report_progress()
sleep(.1) except KeyboardInterrupt:
except KeyboardInterrupt: pass
pass
self.report_progress()
hits_count = sum(p.hits_count for p in self.thread_progress) hits_count = sum(p.hits_count for p in self.thread_progress)
done_count = sum(p.done_count for p in self.thread_progress) done_count = sum(p.done_count for p in self.thread_progress)
@ -1045,10 +1039,10 @@ Please read the README inside for more examples and usage information.
speed_avg = done_count / total_time speed_avg = done_count / total_time
if self.from_stdin: if self.from_stdin:
if tryok: if self.quit_now:
self.total_size = done_count+skip_count
else:
self.total_size = -1 self.total_size = -1
else:
self.total_size = done_count+skip_count
self.show_final() self.show_final()
@ -1056,7 +1050,7 @@ Please read the README inside for more examples and usage information.
hits_count, done_count, skip_count, fail_count, self.total_size, speed_avg, hits_count, done_count, skip_count, fail_count, self.total_size, speed_avg,
pprint_seconds(total_time, '%dh %dm %ds'))) pprint_seconds(total_time, '%dh %dm %ds')))
if not tryok: if self.quit_now:
resume = [] resume = []
for i, p in enumerate(self.thread_progress): for i, p in enumerate(self.thread_progress):
c = p.done_count + p.skip_count c = p.done_count + p.skip_count
@ -1194,7 +1188,7 @@ Please read the README inside for more examples and usage information.
continue continue
while True: while True:
if self.stop_now: if self.quit_now:
return return
try: try:
@ -1217,11 +1211,16 @@ Please read the README inside for more examples and usage information.
module.__del__() module.__del__()
while True: while True:
if self.stop_now: if self.quit_now:
shutdown() shutdown()
return return
prod = gqueue.get() try:
prod = gqueue.get_nowait()
except Empty:
sleep(.1)
continue
if prod is None: if prod is None:
shutdown() shutdown()
return return
@ -1257,17 +1256,16 @@ Please read the README inside for more examples and usage information.
while True: while True:
while self.paused and not self.stop_now: while self.paused and not self.quit_now:
sleep(1) sleep(1)
if self.stop_now: if self.quit_now:
shutdown() shutdown()
return return
if self.rate_limit: if self.rate_limit:
sleep(self.rate_limit) sleep(self.rate_limit)
if try_count <= self.max_retries or self.max_retries < 0: if try_count <= self.max_retries or self.max_retries < 0:
actions = {} actions = {}
@ -1316,7 +1314,7 @@ Please read the README inside for more examples and usage information.
break break
def monitor_progress(self): def monitor_progress(self):
while active_count() > 1: while active_count() > 1 and not self.quit_now:
self.report_progress() self.report_progress()
if not self.from_stdin: if not self.from_stdin:
@ -1330,7 +1328,7 @@ Please read the README inside for more examples and usage information.
try: try:
actions, current, resp, seconds = pq.get_nowait() actions, current, resp, seconds = pq.get_nowait()
#logger.debug('actions reported: %s' % actions) #logger.info('actions reported: %s' % '+'.join(actions))
except Empty: except Empty:
break break
@ -1339,14 +1337,31 @@ Please read the README inside for more examples and usage information.
p.skip_count += 1 p.skip_count += 1
continue continue
offset = (self.start + p.done_count * self.num_threads) + i + 1 if self.resume:
offset = p.done_count + self.resume[i]
else:
offset = p.done_count
offset = (offset * self.num_threads) + i + 1 + self.start
p.current = current p.current = current
p.seconds[p.done_count % len(p.seconds)] = seconds p.seconds[p.done_count % len(p.seconds)] = seconds
if 'fail' in actions or 'ignore' not in actions: msg = '%-15s | %-25s \t | %5d | %s' % (resp.compact(), current, offset, resp)
logger.info('%-15s | %-25s \t | %5d | %s' % (resp.compact(), current, offset, resp))
if 'fail' in actions:
logger.error(msg)
elif 'ignore' not in actions:
logger.info(msg)
if 'ignore' not in actions: if 'fail' in actions:
p.fail_count += 1
elif 'retry' in actions:
continue
elif 'ignore' not in actions:
p.hits_count += 1 p.hits_count += 1
if self.log_dir: if self.log_dir:
@ -1356,14 +1371,10 @@ Please read the README inside for more examples and usage information.
self.push_final(resp) self.push_final(resp)
if 'retry' not in actions: p.done_count += 1
p.done_count += 1
if 'fail' in actions: if 'quit' in actions:
p.fail_count += 1 self.quit_now = True
if 'quit' in actions and 'retry' not in actions:
raise SystemExit
def monitor_interaction(self): def monitor_interaction(self):
@ -1385,7 +1396,7 @@ Please read the README inside for more examples and usage information.
''') ''')
elif command == 'q': elif command == 'q':
raise KeyboardInterrupt self.quit_now = True
elif command == 'p': elif command == 'p':
self.paused = not self.paused self.paused = not self.paused
@ -1402,7 +1413,10 @@ Please read the README inside for more examples and usage information.
elif command.startswith('x'): elif command.startswith('x'):
_, arg = command.split(' ', 1) _, arg = command.split(' ', 1)
self.update_actions(arg) try:
self.update_actions(arg)
except ValueError:
logger.warn('usage: x actions:conditions')
else: # show progress else: # show progress
total_count = sum(p.done_count+p.skip_count for p in self.thread_progress) total_count = sum(p.done_count+p.skip_count for p in self.thread_progress)
@ -2432,6 +2446,7 @@ class MySQL_login:
return self.Response(code, mesg) return self.Response(code, mesg)
class MySQL_query(TCP_Cache): class MySQL_query(TCP_Cache):
'''Brute-force MySQL queries'''
usage_hints = ( usage_hints = (
'''%prog host=10.0.0.1 user=root password=s3cr3t query="select length(load_file('/home/adam/FILE0'))" 0=files.txt -x ignore:size=0''', '''%prog host=10.0.0.1 user=root password=s3cr3t query="select length(load_file('/home/adam/FILE0'))" 0=files.txt -x ignore:size=0''',

Loading…
Cancel
Save