Added multithreading.
This commit is contained in:
commit
8dfa70faae
|
@ -0,0 +1,2 @@
|
|||
logs/
|
||||
output/
|
|
@ -0,0 +1,167 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
import traceback
|
||||
from datetime import date, datetime
|
||||
from time import sleep
|
||||
|
||||
import requests
|
||||
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
|
||||
__author__ = 'moony'
|
||||
__version__ = '1.0.0'
|
||||
|
||||
DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
logging.captureWarnings(True)
|
||||
FORMAT = '%(asctime)s (%(levelname)s): %(message)s'
|
||||
logging.basicConfig(filename=DIR + '/logs/aftermath_' +
|
||||
str(datetime.today().date()) +
|
||||
str(datetime.today().time()) + '.log',
|
||||
format=FORMAT,
|
||||
level=logging.INFO)
|
||||
|
||||
|
||||
class ui:
|
||||
END = '\33[0m'
|
||||
BOLD = '\33[1m'
|
||||
RED = '\33[31m'
|
||||
GREEN = '\33[32m'
|
||||
BLUE = '\33[34m'
|
||||
|
||||
def getTime():
|
||||
now = datetime.now()
|
||||
return now.strftime('%H:%M:%S')
|
||||
|
||||
def getDate():
|
||||
today = date.today()
|
||||
return today
|
||||
|
||||
def prompt():
|
||||
now = datetime.now().strftime('%H:%M:%S')
|
||||
prompt = f' {ui.BLUE}[{ui.GREEN}{now}{ui.BLUE}]{ui.END}'
|
||||
return prompt
|
||||
|
||||
|
||||
def scan_target(target, args):
|
||||
try:
|
||||
target = target.replace('\n', '')
|
||||
|
||||
headers = {
|
||||
'User-Agent':
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0',
|
||||
'Accept':
|
||||
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
|
||||
'Accept-Language': 'en-US,en;q=0.5',
|
||||
'Connection': 'keep-alive'
|
||||
}
|
||||
|
||||
r = requests.get(target,
|
||||
headers=headers,
|
||||
timeout=10,
|
||||
allow_redirects=False,
|
||||
verify=False)
|
||||
|
||||
if r.status_code == 200 and 'SCRIPTS MUST BE ENABLED FOR SHELL TO WORK' in r.text:
|
||||
print(
|
||||
f'{ui.prompt()} operational webshell FOUND: {ui.GREEN}{target}{ui.END}'
|
||||
)
|
||||
logging.info(f'operational webshell FOUND: {target}')
|
||||
|
||||
with open(args.output_file, 'a+') as f:
|
||||
f.write(f'{target}\n')
|
||||
f.close()
|
||||
|
||||
else:
|
||||
logging.info(f'no shell found: {target}')
|
||||
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
pass
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-v',
|
||||
dest='verbose',
|
||||
action='count',
|
||||
default=0,
|
||||
help='enable verbose output. (ex: -v, -vv, -vvv)')
|
||||
|
||||
parser.add_argument('-f',
|
||||
'--file',
|
||||
dest='input_file',
|
||||
required=True,
|
||||
metavar='<input_file>',
|
||||
help='input file of urls to scan for shell')
|
||||
|
||||
parser.add_argument(
|
||||
'-o',
|
||||
'--output',
|
||||
dest='output_file',
|
||||
default=f'{DIR}/output/{ui.getDate()}_{ui.getTime()}.txt',
|
||||
metavar='<output_file>',
|
||||
help='output file to save valid urls')
|
||||
|
||||
parser.add_argument('-t',
|
||||
'--threads',
|
||||
type=int,
|
||||
dest='threads',
|
||||
default=5,
|
||||
metavar='<threads>',
|
||||
help='number of threads to use')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
print(
|
||||
f'{ui.prompt()} {ui.BLUE}aftermath{ui.END} v{ui.BLUE}{__version__}{ui.END} by {ui.BLUE}{__author__}{ui.END} - scanning initiated'
|
||||
)
|
||||
logging.info(
|
||||
f'aftermath v{__version__} by {__author__} - scanning initiated')
|
||||
|
||||
f = open(args.input_file, 'r')
|
||||
targets = f.readlines()
|
||||
|
||||
for target in targets:
|
||||
thread = threading.Thread(target=scan_target, args=(target, args))
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
while threading.active_count() > args.threads:
|
||||
sleep(0.001)
|
||||
|
||||
while threading.active_count() > 1:
|
||||
sleep(0.001)
|
||||
|
||||
valid = len(open(args.output_file).readlines())
|
||||
|
||||
print(
|
||||
f'{ui.prompt()} scanning completed. valid webshells: {ui.GREEN}{valid:,}{ui.END}'
|
||||
)
|
||||
|
||||
logging.info(f'scanning completed. valid webshells: {valid}')
|
||||
sys.exit(-1)
|
||||
# scan_targets(args)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print(f'{ui.prompt()} user interrupt detected - exiting')
|
||||
logging.info('user interrupt detected. exiting.')
|
||||
sys.exit(-1)
|
||||
|
||||
except Exception as e:
|
||||
print(
|
||||
f'{ui.prompt()} fatal exception occurred - check the log for detauls'
|
||||
)
|
||||
logging.error(e, exc_info=traceback)
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,2 @@
|
|||
argparse
|
||||
requests
|
Loading…
Reference in New Issue