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).
__author__ = 'Sebastien Macke'
__twitter__ = '@lanjelot'
__email__ = 'patator@hsc.fr'
__url__ = 'http://www.hsc.fr/ressources/outils/patator/'
__git__ = 'http://code.google.com/p/patator/'
__version__ = '0.4'
__version__ = '0.5-beta'
__license__ = 'GPLv2'
__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)
* Interactive runtime
+ show verbose progress
+ pause/unpause execution
+ show progress during execution (press Enter)
+ pause/unpause execution (press p)
+ increase/decrease verbosity
+ add new actions & conditions during runtime (eg. to exclude more types of response from showing)
+ ... 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.
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
code "xxx" (--max-retries defaults to 4).
controller will retry 4 more times (see --max-retries) before reporting the
failed payload with logging level ERROR.
* 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 time import localtime, strftime, sleep, time
from functools import reduce
from threading import Thread, active_count, Lock
from threading import Thread, active_count
from select import select
from itertools import product, chain, islice
from string import ascii_lowercase
@ -665,15 +666,14 @@ def create_dir(top_path, from_stdin=False):
files = os.listdir(top_path)
if files:
if not from_stdin:
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):
if dirs:
print("Directory '%s' contains sub-directories, safely aborting..." % root)
exit(0)
for f in files:
os.unlink(os.path.join(root, f))
break
if raw_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)
exit(0)
for f in files:
os.unlink(os.path.join(root, f))
break
else:
os.mkdir(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.start_time = 0
self.total_size = 1
self.stop_now = False
self.quit_now = False
self.log_dir = None
self.thread_report = []
self.thread_progress = []
@ -952,7 +952,7 @@ Please read the README inside for more examples and usage information.
if self.log_dir:
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))
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())))
try:
tryok = False
self.start_threads()
self.monitor_progress()
tryok = True
except SystemExit:
logger.info('Quitting')
except KeyboardInterrupt:
print
self.quit_now = True
except:
self.quit_now = True
logger.exception(exc_info()[1])
if not tryok:
self.stop_now = True
try:
while active_count() > 1:
sleep(.1)
except KeyboardInterrupt:
pass
self.report_progress()
try:
while active_count() > 1:
sleep(.1)
self.report_progress()
except KeyboardInterrupt:
pass
hits_count = sum(p.hits_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
if self.from_stdin:
if tryok:
self.total_size = done_count+skip_count
else:
if self.quit_now:
self.total_size = -1
else:
self.total_size = done_count+skip_count
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,
pprint_seconds(total_time, '%dh %dm %ds')))
if not tryok:
if self.quit_now:
resume = []
for i, p in enumerate(self.thread_progress):
c = p.done_count + p.skip_count
@ -1194,7 +1188,7 @@ Please read the README inside for more examples and usage information.
continue
while True:
if self.stop_now:
if self.quit_now:
return
try:
@ -1217,11 +1211,16 @@ Please read the README inside for more examples and usage information.
module.__del__()
while True:
if self.stop_now:
if self.quit_now:
shutdown()
return
prod = gqueue.get()
try:
prod = gqueue.get_nowait()
except Empty:
sleep(.1)
continue
if prod is None:
shutdown()
return
@ -1257,17 +1256,16 @@ Please read the README inside for more examples and usage information.
while True:
while self.paused and not self.stop_now:
while self.paused and not self.quit_now:
sleep(1)
if self.stop_now:
if self.quit_now:
shutdown()
return
if self.rate_limit:
sleep(self.rate_limit)
if try_count <= self.max_retries or self.max_retries < 0:
actions = {}
@ -1316,7 +1314,7 @@ Please read the README inside for more examples and usage information.
break
def monitor_progress(self):
while active_count() > 1:
while active_count() > 1 and not self.quit_now:
self.report_progress()
if not self.from_stdin:
@ -1330,7 +1328,7 @@ Please read the README inside for more examples and usage information.
try:
actions, current, resp, seconds = pq.get_nowait()
#logger.debug('actions reported: %s' % actions)
#logger.info('actions reported: %s' % '+'.join(actions))
except Empty:
break
@ -1339,14 +1337,31 @@ Please read the README inside for more examples and usage information.
p.skip_count += 1
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.seconds[p.done_count % len(p.seconds)] = seconds
if 'fail' in actions or 'ignore' not in actions:
logger.info('%-15s | %-25s \t | %5d | %s' % (resp.compact(), current, offset, resp))
msg = '%-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
if self.log_dir:
@ -1356,14 +1371,10 @@ Please read the README inside for more examples and usage information.
self.push_final(resp)
if 'retry' not in actions:
p.done_count += 1
p.done_count += 1
if 'fail' in actions:
p.fail_count += 1
if 'quit' in actions and 'retry' not in actions:
raise SystemExit
if 'quit' in actions:
self.quit_now = True
def monitor_interaction(self):
@ -1385,7 +1396,7 @@ Please read the README inside for more examples and usage information.
''')
elif command == 'q':
raise KeyboardInterrupt
self.quit_now = True
elif command == 'p':
self.paused = not self.paused
@ -1402,7 +1413,10 @@ Please read the README inside for more examples and usage information.
elif command.startswith('x'):
_, arg = command.split(' ', 1)
self.update_actions(arg)
try:
self.update_actions(arg)
except ValueError:
logger.warn('usage: x actions:conditions')
else: # show 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)
class MySQL_query(TCP_Cache):
'''Brute-force MySQL queries'''
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''',

Loading…
Cancel
Save