From 9b751284e4965bf538b8814266358940152afd32 Mon Sep 17 00:00:00 2001 From: mdazazahmedmridul025-droid Date: Mon, 13 Apr 2026 21:44:44 +0600 Subject: [PATCH 1/3] Add files via upload --- nextscan.py.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 nextscan.py.md diff --git a/nextscan.py.md b/nextscan.py.md new file mode 100644 index 0000000..06d247b --- /dev/null +++ b/nextscan.py.md @@ -0,0 +1,2 @@ +[nextscan.py](Python%25203.13) + From fc0eae90b6b3ae09bcc7bea361da85cf6d8435e4 Mon Sep 17 00:00:00 2001 From: mdazazahmedmridul025-droid Date: Mon, 13 Apr 2026 22:17:56 +0600 Subject: [PATCH 2/3] Create nextscan.py with subdomain scanner and other features --- nextscan.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 nextscan.py diff --git a/nextscan.py b/nextscan.py new file mode 100644 index 0000000..37236ae --- /dev/null +++ b/nextscan.py @@ -0,0 +1,44 @@ +import os +import socket +import threading +import requests +from colorama import Fore, Style +from queue import Queue + +# API Key storage +API_KEYS = {"service_name": "your_api_key_here"} + +def subdomain_scanner(domain): + # Placeholder for subdomain scanning logic + pass + +def reverse_ip_lookup(ip_address): + # Placeholder for reverse IP lookup logic + pass + +def worker(queue): + while not queue.empty(): + domain = queue.get() + print(f"{Fore.GREEN}Scanning {domain}{Style.RESET_ALL}") + subdomain_scanner(domain) + queue.task_done() + +def main(domains): + queue = Queue() + for domain in domains: + queue.put(domain) + + threads = [] + for _ in range(10): # Using 10 threads + thread = threading.Thread(target=worker, args=(queue,)) + thread.start() + threads.append(thread) + + queue.join() + + for thread in threads: + thread.join() + +if __name__ == "__main__": + target_domains = ["example.com", "testsite.com"] # Replace with actual domains + main(target_domains) \ No newline at end of file From e63a7ee645c014ce4f0fb989d553a55edacadbf0 Mon Sep 17 00:00:00 2001 From: mdazazahmedmridul025-droid Date: Mon, 13 Apr 2026 22:29:30 +0600 Subject: [PATCH 3/3] Update nextscan.py with a complete implementation for subdomain scanning and other features. --- nextscan.py | 369 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 338 insertions(+), 31 deletions(-) diff --git a/nextscan.py b/nextscan.py index 37236ae..987a9d1 100644 --- a/nextscan.py +++ b/nextscan.py @@ -1,44 +1,351 @@ +#!/usr/bin/env python3 +""" +NextScan - Complete Subdomain & Reverse IP Scanner +Features: +- Real subdomain enumeration via DNS +- Reverse IP lookup +- DNS A/AAAA/CNAME/MX record queries +- Nextscan.cc API integration +- Multi-threaded processing +""" + +import sys import os +import requests +import dns.resolver import socket import threading -import requests -from colorama import Fore, Style +import configparser +import json +import time +from concurrent.futures import ThreadPoolExecutor from queue import Queue +from urllib.parse import urljoin + +# Color support +class Colors: + GREEN = '\033[92m' + RED = '\033[91m' + YELLOW = '\033[93m' + BLUE = '\033[94m' + CYAN = '\033[96m' + WHITE = '\033[97m' + GRAY = '\033[90m' + RESET = '\033[0m' + BOLD = '\033[1m' + +def color_print(text, color=Colors.WHITE): + print(f"{color}{text}{Colors.RESET}") + +# Configuration +CONFIG_FILE = "nextscan_config.ini" +NEXTSCAN_API_URL = "https://nextscan.cc/api.php" + +def save_api_key(api_key): + """Save API key to config file""" + config = configparser.ConfigParser() + config['nextscan'] = {'api_key': api_key} + try: + with open(CONFIG_FILE, 'w') as f: + config.write(f) + color_print("[+] API key saved!", Colors.GREEN) + return True + except Exception as e: + color_print(f"[-] Error saving API key: {e}", Colors.RED) + return False -# API Key storage -API_KEYS = {"service_name": "your_api_key_here"} +def load_api_key(): + """Load API key from config file""" + config = configparser.ConfigParser() + try: + config.read(CONFIG_FILE) + return config.get('nextscan', 'api_key', fallback='') + except: + return '' -def subdomain_scanner(domain): - # Placeholder for subdomain scanning logic - pass +def validate_api_key(api_key): + """Validate API key with nextscan.cc""" + try: + params = { + 'key': api_key, + 'domain': 'example.com', + 'type': 'subdomains' + } + response = requests.get(NEXTSCAN_API_URL, params=params, timeout=10) + data = response.json() + return data.get('success', False) or 'data' in data + except: + return False -def reverse_ip_lookup(ip_address): - # Placeholder for reverse IP lookup logic - pass +class NextScanAPI: + """Nextscan.cc API integration""" + def __init__(self, api_key): + self.api_key = api_key + self.base_url = NEXTSCAN_API_URL + + def get_subdomains(self, domain): + """Get subdomains from nextscan.cc API""" + try: + params = { + 'key': self.api_key, + 'domain': domain, + 'type': 'subdomains' + } + response = requests.get(self.base_url, params=params, timeout=30) + data = response.json() + + if data.get('success'): + subdomains = data.get('data', {}).get('subdomains', []) + return subdomains + return [] + except Exception as e: + color_print(f"[-] API Error: {e}", Colors.RED) + return [] + + def reverse_ip_lookup(self, ip): + """Get domains hosted on specific IP""" + try: + params = { + 'key': self.api_key, + 'target': ip, + 'type': 'reverse_ip' + } + response = requests.get(self.base_url, params=params, timeout=30) + data = response.json() + + if data.get('success'): + domains = data.get('data', {}).get('domains', []) + return domains + return [] + except Exception as e: + color_print(f"[-] API Error: {e}", Colors.RED) + return [] -def worker(queue): - while not queue.empty(): - domain = queue.get() - print(f"{Fore.GREEN}Scanning {domain}{Style.RESET_ALL}") - subdomain_scanner(domain) - queue.task_done() +class DNSScanner: + """DNS-based subdomain enumeration""" + # Common subdomains to check + COMMON_SUBDOMAINS = [ + 'www', 'mail', 'ftp', 'localhost', 'webmail', 'smtp', 'pop', 'ns1', + 'webdisk', 'ns2', 'cpanel', 'whm', 'autodiscover', 'autoconfig', + 'm', 'mobile', 'api', 'dev', 'staging', 'test', 'prod', + 'admin', 'console', 'dashboard', 'blog', 'shop', 'support', + 'cdn', 'static', 'assets', 'images', 'downloads', 'files' + ] + + def __init__(self): + self.resolver = dns.resolver.Resolver() + self.resolver.timeout = 5 + self.resolver.lifetime = 5 + + def check_subdomain(self, subdomain, domain): + """Check if subdomain exists via DNS""" + full_domain = f"{subdomain}.{domain}" + try: + answers = self.resolver.resolve(full_domain, 'A') + ips = [rdata.address for rdata in answers] + return True, ips + except: + return False, [] + + def enumerate_subdomains(self, domain, threads=10): + """Enumerate common subdomains""" + results = [] + + def worker(subdomain): + exists, ips = self.check_subdomain(subdomain, domain) + if exists: + color_print(f"[+] Found: {subdomain}.{domain} -> {', '.join(ips)}", Colors.GREEN) + results.append({ + 'subdomain': f"{subdomain}.{domain}", + 'ips': ips + }) + + with ThreadPoolExecutor(max_workers=threads) as executor: + executor.map(worker, self.COMMON_SUBDOMAINS) + + return results + + def get_dns_records(self, domain): + """Get various DNS records for domain""" + records = {} + record_types = ['A', 'AAAA', 'CNAME', 'MX', 'TXT', 'NS'] + + for record_type in record_types: + try: + answers = self.resolver.resolve(domain, record_type) + records[record_type] = [str(rdata) for rdata in answers] + except: + pass + + return records -def main(domains): - queue = Queue() - for domain in domains: - queue.put(domain) +class ReverseIPLookup: + """Reverse IP lookup functionality""" + @staticmethod + def get_hostname(ip): + """Get hostname from IP""" + try: + hostname = socket.gethostbyaddr(ip) + return hostname[0] + except: + return None + + @staticmethod + def get_ip(domain): + """Get IP from domain""" + try: + ip = socket.gethostbyname(domain) + return ip + except: + return None - threads = [] - for _ in range(10): # Using 10 threads - thread = threading.Thread(target=worker, args=(queue,)) - thread.start() - threads.append(thread) +class NextScan: + """Main scanner class""" + def __init__(self, api_key=''): + self.api_key = api_key + self.api_client = NextScanAPI(api_key) if api_key else None + self.dns_scanner = DNSScanner() + self.reverse_lookup = ReverseIPLookup() + self.results = [] + + def scan_domain(self, domain): + """Comprehensive domain scan""" + color_print(f"\n[*] Scanning domain: {domain}", Colors.CYAN) + color_print("=" * 60, Colors.GRAY) + + # Get basic DNS records + color_print("\n[*] Fetching DNS records...", Colors.BLUE) + dns_records = self.dns_scanner.get_dns_records(domain) + for record_type, values in dns_records.items(): + for value in values: + color_print(f" [{record_type}] {value}", Colors.YELLOW) + + # Enumerate subdomains via DNS + color_print("\n[*] Enumerating subdomains via DNS...", Colors.BLUE) + dns_subs = self.dns_scanner.enumerate_subdomains(domain) + + # Get subdomains from API if available + api_subs = [] + if self.api_client: + color_print("\n[*] Fetching subdomains from Nextscan.cc API...", Colors.BLUE) + api_subs = self.api_client.get_subdomains(domain) + for sub in api_subs: + subdomain_name = sub.get('subdomain', sub) if isinstance(sub, dict) else sub + ip = sub.get('ip', '') if isinstance(sub, dict) else '' + color_print(f" [API] {subdomain_name} -> {ip}", Colors.GREEN) + + # Combine results + all_subdomains = dns_subs + api_subs + + color_print(f"\n[+] Found {len(all_subdomains)} subdomains!", Colors.GREEN) + + # Save to file + output_file = f"scan_{domain}_{int(time.time())}.txt" + with open(output_file, 'w') as f: + for sub in all_subdomains: + if isinstance(sub, dict): + subdomain = sub.get('subdomain', sub.get('subdomain', '')) + ips = sub.get('ips', []) + f.write(f"{subdomain},{','.join(ips) if ips else ''}\n") + else: + f.write(f"{sub}\n") + + color_print(f"[+] Results saved to {output_file}", Colors.GREEN) + return all_subdomains + + def reverse_ip(self, ip): + """Reverse IP lookup""" + color_print(f"\n[*] Reverse IP lookup: {ip}", Colors.CYAN) + color_print("=" * 60, Colors.GRAY) + + if not self.api_client: + color_print("[-] API key required for reverse IP lookup", Colors.RED) + return + + domains = self.api_client.reverse_ip_lookup(ip) + color_print(f"[+] Found {len(domains)} domains on {ip}", Colors.GREEN) + + for domain in domains: + color_print(f" - {domain}", Colors.YELLOW) + + # Save to file + output_file = f"reverse_ip_{ip}_{int(time.time())}.txt" + with open(output_file, 'w') as f: + for domain in domains: + f.write(f"{domain}\n") + + color_print(f"[+] Results saved to {output_file}", Colors.GREEN) + return domains - queue.join() +def show_banner(): + """Display banner""" + banner = """ + ╔═══════════════════════════════════════╗ + ║ NEXTSCAN v2.0 ║ + ║ Subdomain & Reverse IP Scanner ║ + ╚═══════════════════════════════════════╝ + """ + color_print(banner, Colors.CYAN) - for thread in threads: - thread.join() +def main_menu(): + """Display main menu""" + show_banner() + + api_key = load_api_key() + + while True: + print("\n[OPTIONS]") + print("[1] Set API Key") + print("[2] Scan Domain") + print("[3] Reverse IP Lookup") + print("[4] Scan from File") + print("[0] Exit") + + choice = input("\n> ").strip() + + if choice == '1': + api_key = input("Enter your Nextscan.cc API key: ").strip() + if validate_api_key(api_key): + save_api_key(api_key) + else: + color_print("[-] Invalid API key", Colors.RED) + + elif choice == '2': + domain = input("Enter domain: ").strip() + if domain: + scanner = NextScan(api_key) + scanner.scan_domain(domain) + + elif choice == '3': + if not api_key: + color_print("[-] API key required!", Colors.RED) + continue + ip = input("Enter IP address: ").strip() + if ip: + scanner = NextScan(api_key) + scanner.reverse_ip(ip) + + elif choice == '4': + file_path = input("Enter file path: ").strip() + try: + with open(file_path, 'r') as f: + domains = [line.strip() for line in f if line.strip()] + + scanner = NextScan(api_key) + for domain in domains: + scanner.scan_domain(domain) + time.sleep(1) # Rate limiting + except Exception as e: + color_print(f"[-] Error: {e}", Colors.RED) + + elif choice == '0': + color_print("\n[*] Goodbye!", Colors.CYAN) + break -if __name__ == "__main__": - target_domains = ["example.com", "testsite.com"] # Replace with actual domains - main(target_domains) \ No newline at end of file +if __name__ == '__main__': + try: + main_menu() + except KeyboardInterrupt: + color_print("\n\n[!] Interrupted by user", Colors.YELLOW) + except Exception as e: + color_print(f"[-] Error: {e}", Colors.RED) \ No newline at end of file