diff --git a/TraceNinja/traceninja.py b/TraceNinja/traceninja.py index 0cf91ac..079bf4e 100644 --- a/TraceNinja/traceninja.py +++ b/TraceNinja/traceninja.py @@ -1,20 +1,26 @@ import time import datetime import concurrent.futures +import requests from TraceNinja.utils.handler import handler from rich import print as rprint from TraceNinja.modules import crtsh, alienvault, hackertarget, jldc, securitytrails, rapidapi -from importlib_metadata import version as get_installed_version +from importlib.metadata import version as get_installed_version from packaging.version import Version import subprocess import sys -import pkg_resources import os -CURRENT_VERSION = pkg_resources.require("TraceNinja")[0].version +CURRENT_VERSION = get_installed_version("TraceNinja") current_dir = os.path.dirname(__file__) +domain, domains_file, output = handler() + +def read_domains_from_file(file_path): + with open(file_path, 'r') as file: + return [line.strip() for line in file if line.strip()] + def save_subdomains(subdomains, output, current_dir): if output and output.lower() != "none": file_path = os.path.abspath(output) if os.path.isabs(output) else os.path.join(os.getcwd(), output) @@ -43,46 +49,59 @@ def updater(): else: print("Invalid input. Please enter 'yes' or 'no'.") -installed_version = get_installed_version('TraceNinja') +def process_domain(target_domain): + rprint("[deep_sky_blue1][INFO]", f"Starting subdomain enumeration for target: {target_domain}") + scripts = [crtsh, alienvault, hackertarget, jldc, securitytrails, rapidapi] + + with concurrent.futures.ThreadPoolExecutor() as executor: + start_time = time.time() + future_to_script = {executor.submit(script.fetch, target_domain): script for script in scripts} + all_subdomains = [] + rprint("[deep_sky_blue1][INFO]", "Querying subdomains") + for future in concurrent.futures.as_completed(future_to_script): + script = future_to_script[future] + subdomains = future.result() + if subdomains: + all_subdomains.extend(subdomains) -def main(): + subdomains = list(set(all_subdomains)) + rprint("[spring_green1][SUCCESS]", "Retrieved subdomains") + elapsed_time = time.time() - start_time + rprint("[deep_sky_blue1][INFO]", f"Subdomain enumeration completed in {elapsed_time:.2f} seconds") + rprint("[deep_sky_blue1][INFO]", f"Total unique subdomains found: {len(subdomains)}") + return subdomains - domain, output = handler() - +def main(): now = datetime.datetime.now() print("-----------------------------------------------------------------------------") print("🛠️ Version:", CURRENT_VERSION) - print("🎯 Target Domain:" , domain) print("⏰ Starting:", now.strftime("%Y-%m-%d %H:%M:%S")) print("-----------------------------------------------------------------------------") - if Version(CURRENT_VERSION) < Version(installed_version): - print("update your package") + contents = requests.get('https://pypi.org/pypi/TraceNinja/json') + data = contents.json() + latest_version = data['info']['version'] + + if Version(CURRENT_VERSION) < Version(latest_version): + print("Update available. Current version:", CURRENT_VERSION, "Latest version:", latest_version) updater() - elif Version(installed_version) == Version(CURRENT_VERSION): + elif Version(latest_version) == Version(CURRENT_VERSION): print(f"You are running the latest version of TraceNinja. (Version: {CURRENT_VERSION})") - scripts = [crtsh, alienvault, hackertarget, jldc, securitytrails, rapidapi] - rprint("[deep_sky_blue1][INFO]","Starting subdomain enumeration for target: {}".format(domain)) - with concurrent.futures.ThreadPoolExecutor() as executor: - start_time = time.time() - future_to_script = {executor.submit(script.fetch, domain): script for script in scripts} - all_subdomains = [] - rprint("[deep_sky_blue1][INFO]","Querying subdomains") - for future in concurrent.futures.as_completed(future_to_script): - script = future_to_script[future] - subdomains = future.result() - if subdomains: - all_subdomains.extend(subdomains) + all_subdomains = [] + if domains_file: + domains = read_domains_from_file(domains_file) + rprint("[deep_sky_blue1][INFO]", f"Read {len(domains)} domains from file: {domains_file}") + for target_domain in domains: + all_subdomains.extend(process_domain(target_domain)) + else: + all_subdomains = process_domain(domain) - subdomains = list(set(all_subdomains)) - rprint("[spring_green1][SUCCESS]","Retrieved subdomains") - save_subdomains(subdomains, output, current_dir) - elapsed_time = time.time() - start_time - rprint("[deep_sky_blue1][INFO]","Subdomain enumeration completed in {} seconds".format(elapsed_time)) - rprint("[deep_sky_blue1][INFO]","Total unique subdomains found: {}".format(len(subdomains))) - for subdomain in subdomains: + if output: + save_subdomains(all_subdomains, output, current_dir) + + for subdomain in all_subdomains: print(subdomain) if __name__ == '__main__': diff --git a/TraceNinja/utils/cli/cli.py b/TraceNinja/utils/cli/cli.py index a0c9471..2bcde97 100644 --- a/TraceNinja/utils/cli/cli.py +++ b/TraceNinja/utils/cli/cli.py @@ -2,7 +2,8 @@ def cli(): parser = argparse.ArgumentParser() - parser.add_argument('-d', '--domain', type=str, required=True, help='Target Domain.') + parser.add_argument('-d', '--domain', type=str, help='Target Domain.') + parser.add_argument('-l', '--domain-list', type=str, help='List of domains.') parser.add_argument('-o', '--output', type=str, required=False, help='Output to file.') args = parser.parse_args() return args diff --git a/TraceNinja/utils/handler.py b/TraceNinja/utils/handler.py index 5ead089..49e3716 100644 --- a/TraceNinja/utils/handler.py +++ b/TraceNinja/utils/handler.py @@ -5,10 +5,11 @@ def handler(): args = cli() domain = args.domain + domains_file = args.domain_list output = args.output # Just call banner without assigning it banner() # Displays the banner directly - return domain, output + return domain, domains_file, output \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 14bc75c..17f34aa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ -importlib_metadata==8.4.0 packaging==24.1 python-dotenv==1.0.1 Requests==2.32.3 -rich==13.8.0 +rich==13.8.1 setuptools==69.2.0 diff --git a/setup.cfg b/setup.cfg index e3e3186..0cb27a1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = TraceNinja -version = 1.0.4 +version = 1.0.5 author = Mohamed description = TraceNinja is a subdomain enumeration tool for Python that allows you to enumerate domains and gather information about them. And much much more on the future ^_^. It's currently under development. license = MIT diff --git a/setup.py b/setup.py index 47c5239..4ab6e25 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name="TraceNinja", - version="1.0.4", + version="1.0.5", description="""TraceNinja is a subdomain enumeration tool for Python that allows you to enumerate domains and gather information about them. And much much more on the future ^_^. It's currently under development.""", long_description=long_description, long_description_content_type="text/markdown",