├── README.md ├── secora.PNG └── secora.py /README.md: -------------------------------------------------------------------------------- 1 | # INFO 2 | SECORA : A Bug Bounty Hunter's Terminal 3 | 4 | 5 | 6 | # USAGE 7 | HELP : 8 | Command : list sessions -----> List All Sessions 9 | 10 | Command : interact -----> Interact With The Session 11 | 12 | Command : Exit -----> Exit Secora 13 | 14 | # DONATE 15 | https://buymeacoffee.com/cyb3rf034r3ss 16 | -------------------------------------------------------------------------------- /secora.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/40sp3l/secora/c0e38e5eb872f1c9d51aca782c2cdc76d042fd57/secora.PNG -------------------------------------------------------------------------------- /secora.py: -------------------------------------------------------------------------------- 1 | # secora is a bug bounty automation framework 2 | import requests 3 | from colorama import Fore 4 | from art import text2art 5 | import readline 6 | from subprocess import check_output 7 | import os 8 | import time 9 | import queue 10 | import threading 11 | import subprocess 12 | from typing import Dict, Tuple 13 | 14 | # unix only 15 | if os.name == "posix": 16 | os.system('clear') 17 | else: 18 | exit() 19 | 20 | # banner 21 | print(text2art("secora")) 22 | print(Fore.YELLOW+"[SECORA]: A Bug Bounty Hunter's Terminal ------> [CREATOR]: @40sp3l\n"+Fore.WHITE) 23 | # help 24 | print(Fore.BLUE+"[+] Help: "+Fore.WHITE) 25 | print(Fore.BLUE+"Command: list sessions -------> List All Sessions"+Fore.WHITE) 26 | print(Fore.BLUE+"Command: interact -------> Interact With The Session"+Fore.WHITE) 27 | print(Fore.BLUE+"Command: Exit -------> Exit Secora\n"+Fore.WHITE) 28 | 29 | # Dictionary to store background processes and their details 30 | background_tasks: Dict[int, Tuple[subprocess.Popen, str, queue.Queue]] = {} 31 | task_counter = 0 32 | 33 | def run_subfinder_command(command: str, task_id: int) -> None: 34 | """Run a subfinder command in the background and capture output.""" 35 | process = subprocess.Popen( 36 | command, shell=True, 37 | stdout=subprocess.PIPE, 38 | stderr=subprocess.STDOUT, 39 | text=True 40 | ) 41 | output_queue = queue.Queue() 42 | background_tasks[task_id] = (process, command, output_queue) 43 | 44 | # Thread to capture output 45 | def capture_output(): 46 | while process.poll() is None: 47 | line = process.stdout.readline() 48 | if line: 49 | output_queue.put(line.strip()) 50 | # Capture any remaining output 51 | for line in process.stdout: 52 | if line: 53 | output_queue.put(line.strip()) 54 | 55 | threading.Thread(target=capture_output, daemon=True).start() 56 | 57 | def list_sessions() -> None: 58 | """List all running background tasks.""" 59 | if not background_tasks: 60 | print("\n[!] No background tasks running.\n") 61 | return 62 | 63 | print("\nBackground Tasks:") 64 | for task_id, (_, command, _) in background_tasks.items(): 65 | print(f"\nID: {task_id} | Command: {command}\n") 66 | 67 | def interact_task(task_id: int) -> None: 68 | """Display the output of a specific background task.""" 69 | if task_id not in background_tasks: 70 | print(f"\n[!] No task found with ID {task_id}\n") 71 | return 72 | 73 | process, command, output_queue = background_tasks[task_id] 74 | print(f"\nInteracting with task ID {task_id} | Command: {command}\n") 75 | 76 | # Print any queued output 77 | while not output_queue.empty(): 78 | print(output_queue.get()) 79 | 80 | # Check if process is still running and display new output 81 | while process.poll() is None: 82 | try: 83 | line = output_queue.get(timeout=1) 84 | print(line) 85 | except queue.Empty: 86 | continue 87 | 88 | # Print any remaining output after process completion 89 | while not output_queue.empty(): 90 | print(output_queue.get()) 91 | 92 | print(f"\nTask ID {task_id} has completed.\n") 93 | 94 | def main(): 95 | global task_counter 96 | while True: 97 | user_input = input(Fore.YELLOW+"[SECORA]-------> "+Fore.WHITE).strip() 98 | 99 | if user_input.lower() == "exit": 100 | print("Exiting...") 101 | break 102 | 103 | if user_input.startswith("subfinder") or user_input.startswith("assetfinder") or user_input.startswith("nmap") or user_input.startswith("httpx-toolkit") or user_input.startswith("curl") or user_input.startswith("amass") or user_input.startswith("waybackurls") or user_input.startswith("gau") or user_input.startswith("findomain") or user_input.startswith("gf") or user_input.startswith("meg") or user_input.startswith("nuclei") or user_input.startswith("dalfox") or user_input.startswith("sqlmap") or user_input.startswith("dirsearch") or user_input.startswith("ffuf") or user_input.startswith("gobuster") or user_input.startswith("arjun") or user_input.startswith("ksubdomain") or user_input.startswith("wafw00f") or user_input.startswith("whatweb") or user_input.startswith("naabu") or user_input.startswith("cat") or user_input.startswith("httprobe") or user_input.startswith("anew") or user_input.startswith("grep"): 104 | task_counter += 1 105 | print(f"\nStarting task ID {task_counter} in the background\n") 106 | threading.Thread( 107 | target=run_subfinder_command, 108 | args=(user_input, task_counter), 109 | daemon=True 110 | ).start() 111 | time.sleep(0.1) 112 | 113 | elif user_input == "list sessions": 114 | list_sessions() 115 | 116 | elif user_input.startswith("interact "): 117 | try: 118 | task_id = int(user_input.split(" ")[1]) 119 | interact_task(task_id) 120 | except (IndexError, ValueError): 121 | print("\n[!] Invalid command. Use: interact \n") 122 | 123 | else: 124 | print("\n[!] Unknown command. Supported commands: subfinder , list sessions, interact , exit\n") 125 | 126 | if __name__ == "__main__": 127 | main() 128 | --------------------------------------------------------------------------------