├── 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 |
--------------------------------------------------------------------------------