Advertisement
xGHOSTSECx

GhostWebScan.py

Dec 30th, 2023
1,234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.22 KB | None | 0 0
  1. #!/data/data/com.termux/files/usr/bin/env python
  2.  
  3. import argparse
  4. import asyncio
  5. import aiohttp
  6. import json
  7. import logging
  8. from urllib.parse import urlparse
  9. from bs4 import BeautifulSoup
  10. from concurrent.futures import ThreadPoolExecutor
  11. from functools import partial
  12.  
  13. logging.basicConfig(level=logging.INFO)
  14.  
  15. async def fetch_subdomains_expert(session, domain, depth):
  16.     subdomains = set()
  17.  
  18.     if depth == 0:
  19.         return subdomains
  20.  
  21.     try:
  22.         response = await session.get(f'https://crt.sh/?q=%.{domain}&output=json', timeout=5)
  23.         data = await response.json()
  24.         new_subdomains = {entry['name_value'] for entry in data}
  25.         subdomains.update(new_subdomains)
  26.  
  27.         tasks = []
  28.  
  29.         for new_domain in new_subdomains:
  30.             tasks.append(asyncio.ensure_future(fetch_subdomains_expert(session, new_domain, depth - 1)))
  31.  
  32.         await asyncio.gather(*tasks)
  33.  
  34.     except (aiohttp.ClientError, asyncio.TimeoutError) as e:
  35.         logging.error(f"Error in fetch_subdomains_expert: {str(e)}")
  36.  
  37.     return subdomains
  38.  
  39. async def fetch_subdomains_async(url, depth):
  40.     subdomains = set()
  41.  
  42.     try:
  43.         base_domain = urlparse(url).netloc
  44.         async with aiohttp.ClientSession() as session:
  45.             subdomains = await fetch_subdomains_expert(session, base_domain, depth)
  46.  
  47.     except (aiohttp.ClientError, asyncio.TimeoutError) as e:
  48.         logging.error(f"Error in fetch_subdomains_async: {str(e)}")
  49.  
  50.     return list(subdomains)
  51.  
  52. async def gather_technology_info_expert(session, subdomain):
  53.     tech_info = {}
  54.     try:
  55.         response = await session.get(f'http://{subdomain}', timeout=5)
  56.         soup = BeautifulSoup(await response.text(), 'html.parser')
  57.  
  58.         tech_info['title'] = soup.title.text if soup.title else None
  59.         tech_info['meta_tags'] = [meta['name'] for meta in soup.find_all('meta', {'name': True})]
  60.         tech_info['scripts'] = [script['src'] for script in soup.find_all('script', {'src': True})]
  61.  
  62.     except (aiohttp.ClientError, asyncio.TimeoutError) as e:
  63.         logging.error(f"Error in gather_technology_info_expert: {str(e)}")
  64.  
  65.     return tech_info
  66.  
  67. async def scan_website_expert(url, depth, output_format, output_file, concurrency, rate_limit, custom_headers, interactive_mode, command):
  68.     try:
  69.         base_domain = urlparse(url).netloc
  70.         async with aiohttp.ClientSession(headers=custom_headers) as session:
  71.             subdomains = await fetch_subdomains_expert(session, base_domain, depth)
  72.  
  73.             tech_info_func = partial(gather_technology_info_expert, session)
  74.             with ThreadPoolExecutor(max_workers=concurrency) as executor:
  75.                 tech_info_list = list(executor.map(tech_info_func, subdomains))
  76.  
  77.             # Process command
  78.             if "links" in command:
  79.                 links = set()
  80.                 for subdomain in subdomains:
  81.                     try:
  82.                         response = await session.get(f'http://{subdomain}', timeout=5)
  83.                         soup = BeautifulSoup(await response.text(), 'html.parser')
  84.                         links.update({a['href'] for a in soup.find_all('a', href=True)})
  85.                     except (aiohttp.ClientError, asyncio.TimeoutError):
  86.                         continue
  87.                 print("\nLinks:")
  88.                 print("\n".join(links))
  89.  
  90.             if "status_codes" in command:
  91.                 status_codes = {}
  92.                 for subdomain in subdomains:
  93.                     try:
  94.                         response = await session.get(f'http://{subdomain}', timeout=5)
  95.                         status_codes[subdomain] = response.status
  96.                     except (aiohttp.ClientError, asyncio.TimeoutError):
  97.                         status_codes[subdomain] = "Error"
  98.                 print("\nHTTP Status Codes:")
  99.                 for subdomain, status in status_codes.items():
  100.                     print(f"{subdomain}: {status}")
  101.  
  102.             if "keywords" in command:
  103.                 keywords = set(["security", "vulnerability"])  # Customize keywords as needed
  104.                 print("\nKeywords Found:")
  105.                 for subdomain in subdomains:
  106.                     try:
  107.                         response = await session.get(f'http://{subdomain}', timeout=5)
  108.                         soup = BeautifulSoup(await response.text(), 'html.parser')
  109.                         text = soup.get_text().lower()
  110.                         if any(keyword in text for keyword in keywords):
  111.                             print(f"{subdomain}: Keywords Found")
  112.                     except (aiohttp.ClientError, asyncio.TimeoutError):
  113.                         continue
  114.  
  115.             if output_file:
  116.                 with open(output_file, 'w') as file:
  117.                     if output_format == 'json':
  118.                         json.dump({'subdomains': list(subdomains), 'technology_info': tech_info_list}, file, indent=2)
  119.                     # Add support for other output formats as needed
  120.  
  121.     except Exception as e:
  122.         logging.error(f"Error in scan_website_expert: {str(e)}")
  123.  
  124. def print_gui():
  125.     print("\033[93m==============================================================")
  126.     print("\033[1m                      GhostSec Web Scanner                      ")
  127.     print("\033[93m==============================================================\033[0m")
  128.     print("\033[92mUsage: ./your_script_name.py example.com [options]\n")
  129.     print("\033[1mOptions:\033[0m")
  130.     print("  -h, --help            Show this help message and exit")
  131.     print("  --depth DEPTH         Depth of subdomain enumeration (default: 1)")
  132.     print("  --output-format {json} Output format (default: json)")
  133.     print("  --output-file OUTPUT_FILE Output file path")
  134.     print("  --concurrency CONCURRENCY Number of concurrent tasks (default: 5)")
  135.     print("  --rate-limit RATE_LIMIT Rate limit in requests per minute (default: 0)")
  136.     print("  --custom-headers CUSTOM_HEADERS Custom HTTP headers as a JSON object")
  137.     print("  --interactive-mode   Enable interactive mode")
  138.     print("\n\033[1mCommand Options:\033[0m")
  139.     print("  --command {links,status_codes,keywords} Execute specific commands")
  140.     print("\n\033[1mExamples:\033[0m")
  141.     print("  ./your_script_name.py example.com --depth 2 --output-format json --output-file results.json --command links,status_codes")
  142.     print("  ./your_script_name.py example.com --interactive-mode --command keywords")
  143.     print("\n\033[93m==============================================================\033[0m")
  144.  
  145. if __name__ == "__main__":
  146.     parser = argparse.ArgumentParser(
  147.         description='GhostSec Web Scanner - Scan a website for subdomains and technology information.',
  148.         epilog="Example: ./your_script_name.py example.com --depth 2 --output-format json --output-file results.json --command links,status_codes"
  149.     )
  150.     parser.add_argument('url', help='Target website URL')
  151.     parser.add_argument('--depth', type=int, default=1, help='Depth of subdomain enumeration')
  152.     parser.add_argument('--output-format', choices=['json'], default='json', help='Output format')
  153.     parser.add_argument('--output-file', help='Output file path')
  154.     parser.add_argument('--concurrency', type=int, default=5, help='Number of concurrent tasks')
  155.     parser.add_argument('--rate-limit', type=int, default=0, help='Rate limit in requests per minute')
  156.     parser.add_argument('--custom-headers', type=json.loads, default={}, help='Custom HTTP headers as a JSON object')
  157.     parser.add_argument('--interactive-mode', action='store_true', help='Enable interactive mode')
  158.     parser.add_argument('--command', choices=['links', 'status_codes', 'keywords'], help='Execute specific commands')
  159.  
  160.     args = parser.parse_args()
  161.  
  162.     if args.url == "--help" or args.url == "-h":
  163.         print_gui()
  164.     else:
  165.         try:
  166.             loop = asyncio.get_event_loop()
  167.             loop.run_until_complete(scan_website_expert(
  168.                 args.url, args.depth, args.output_format, args.output_file, args.concurrency, args.rate_limit,
  169.                 args.custom_headers, args.interactive_mode, args.command
  170.             ))
  171.         except KeyboardInterrupt:
  172.             print("\nScan aborted by user.")
  173.         except Exception as e:
  174.             print(f"An error occurred: {str(e)}")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement