Last active
October 26, 2025 07:54
-
-
Save ThanniKudam/8c1137a9b2b8be6be261d6ad081a8c6f to your computer and use it in GitHub Desktop.
dreadnode interact cli
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """If you are doing dreadnode challenges, this code will help you to interact with the server easily via cli.""" | |
| #!/usr/bin/env python3 | |
| """ | |
| Enhanced dreadnode_cli.py | |
| Beautiful terminal interface for Dreadnode CTF challenge interaction and flag submission. | |
| """ | |
| import os | |
| import sys | |
| import json | |
| import requests | |
| import textwrap | |
| from pprint import pprint | |
| try: | |
| from colorama import init, Fore, Style | |
| except ImportError: | |
| os.system("pip install colorama --quiet") | |
| from colorama import init, Fore, Style | |
| init(autoreset=True) | |
| # --- Configuration --- | |
| CHALLENGE = "whatistheflag" | |
| CRUCIBLE_URL = "https://platform.dreadnode.io" | |
| CHALLENGE_URL = "https://whatistheflag.platform.dreadnode.io" | |
| # ---------------------- | |
| def get_api_key(): | |
| key = os.environ.get("DREADNODE_API_KEY") | |
| if key: | |
| print(f"{Fore.GREEN}Using DREADNODE_API_KEY from environment.") | |
| return key.strip() | |
| k = input(f"{Fore.YELLOW}Enter your DREADNODE_API_KEY: {Style.RESET_ALL}").strip() | |
| if not k: | |
| print(f"{Fore.RED}No API key provided. Exiting.") | |
| sys.exit(1) | |
| return k | |
| def query(api_key, input_data): | |
| url = f"{CHALLENGE_URL}/score" | |
| headers = {"X-API-Key": api_key} | |
| payload = {"data": input_data} | |
| try: | |
| resp = requests.post(url, headers=headers, json=payload, timeout=15) | |
| except requests.RequestException as e: | |
| return {"error": f"request failed: {e}"} | |
| try: | |
| return resp.json() | |
| except ValueError: | |
| return {"status_code": resp.status_code, "text": resp.text} | |
| def submit_flag(api_key, flag): | |
| url = f"{CRUCIBLE_URL}/api/challenges/{CHALLENGE}/submit-flag" | |
| headers = {"X-API-Key": api_key} | |
| payload = {"challenge": CHALLENGE, "flag": flag} | |
| try: | |
| resp = requests.post(url, headers=headers, json=payload, timeout=15) | |
| except requests.RequestException as e: | |
| return {"error": f"request failed: {e}"} | |
| try: | |
| return {"status_code": resp.status_code, "body": resp.json()} | |
| except ValueError: | |
| return {"status_code": resp.status_code, "text": resp.text} | |
| def pretty_print_response(res): | |
| """Nicely format the response output with colors and spacing.""" | |
| print(f"\n{Fore.CYAN}{'-'*60}{Style.RESET_ALL}") | |
| print(f"{Fore.MAGENTA}Response:{Style.RESET_ALL}\n") | |
| if isinstance(res, dict) and "output" in res: | |
| output = res["output"] | |
| wrapped = textwrap.fill(output, width=80) | |
| print(f"{Fore.GREEN}{wrapped}{Style.RESET_ALL}") | |
| else: | |
| pprint(res) | |
| print(f"{Fore.CYAN}{'-'*60}{Style.RESET_ALL}\n") | |
| def interactive_mode(api_key): | |
| print(f"""{Fore.CYAN} | |
| ╔══════════════════════════════════════════════════════════╗ | |
| ║ INTERACTIVE MODE - DREADNODE ║ | |
| ╚══════════════════════════════════════════════════════════╝ | |
| Type any message to send to the challenge. | |
| Commands: | |
| {Fore.YELLOW}:exit{Style.RESET_ALL} → quit interactive mode | |
| {Fore.YELLOW}:submit <flag>{Style.RESET_ALL} → submit a flag directly | |
| {Fore.YELLOW}:help{Style.RESET_ALL} → show this help again | |
| ─────────────────────────────────────────────────────────── | |
| """) | |
| last_response = None | |
| while True: | |
| try: | |
| prompt = input(f"{Fore.BLUE}you> {Style.RESET_ALL}").rstrip() | |
| except (KeyboardInterrupt, EOFError): | |
| print(f"\n{Fore.YELLOW}Exiting interactive mode.{Style.RESET_ALL}") | |
| break | |
| if not prompt: | |
| continue | |
| if prompt == ":exit": | |
| print(f"{Fore.YELLOW}Bye.{Style.RESET_ALL}") | |
| break | |
| elif prompt == ":help": | |
| print("Commands: :exit | :submit <flag> | :help") | |
| continue | |
| elif prompt.startswith(":submit "): | |
| flag = prompt.partition(" ")[2].strip() | |
| if not flag: | |
| print(f"{Fore.RED}No flag provided after :submit.{Style.RESET_ALL}") | |
| continue | |
| print(f"{Fore.YELLOW}Submitting flag...{Style.RESET_ALL}") | |
| res = submit_flag(api_key, flag) | |
| pretty_print_response(res) | |
| continue | |
| print(f"{Fore.YELLOW}Sending to challenge...{Style.RESET_ALL}") | |
| res = query(api_key, prompt) | |
| last_response = res | |
| pretty_print_response(res) | |
| # Heuristic flag detection | |
| def find_flag(obj): | |
| if isinstance(obj, str) and obj.startswith("gAAAAA"): | |
| return obj | |
| if isinstance(obj, dict): | |
| for v in obj.values(): | |
| f = find_flag(v) | |
| if f: | |
| return f | |
| if isinstance(obj, list): | |
| for v in obj: | |
| f = find_flag(v) | |
| if f: | |
| return f | |
| return None | |
| found = find_flag(res) | |
| if found: | |
| print(f"{Fore.GREEN}⚑ Potential Flag Found: {Fore.YELLOW}{found}{Style.RESET_ALL}\n") | |
| def submit_mode(api_key): | |
| print(f"{Fore.CYAN}\n--- SUBMIT MODE ---{Style.RESET_ALL}") | |
| flag = input(f"{Fore.YELLOW}Enter the flag to submit: {Style.RESET_ALL}").strip() | |
| if not flag: | |
| print(f"{Fore.RED}No flag provided. Abort.{Style.RESET_ALL}") | |
| return | |
| print(f"{Fore.YELLOW}Submitting flag...{Style.RESET_ALL}") | |
| res = submit_flag(api_key, flag) | |
| pretty_print_response(res) | |
| if res.get("body", {}).get("correct") is True: | |
| print(f"{Fore.GREEN}✅ The flag was correct. Congrats!{Style.RESET_ALL}") | |
| else: | |
| print(f"{Fore.RED}❌ Incorrect flag. Keep trying!{Style.RESET_ALL}") | |
| def main(): | |
| print(f"{Fore.CYAN}Dreadnode CLI — interact with the challenge or submit a flag.{Style.RESET_ALL}") | |
| api_key = get_api_key() | |
| while True: | |
| print(f""" | |
| {Fore.CYAN}Choose an action:{Style.RESET_ALL} | |
| {Fore.YELLOW}1){Style.RESET_ALL} Interact with the challenge | |
| {Fore.YELLOW}2){Style.RESET_ALL} Submit a flag | |
| {Fore.YELLOW}3){Style.RESET_ALL} Exit | |
| """) | |
| choice = input(f"{Fore.BLUE}select> {Style.RESET_ALL}").strip() | |
| if choice == "1": | |
| interactive_mode(api_key) | |
| elif choice == "2": | |
| submit_mode(api_key) | |
| elif choice == "3": | |
| print(f"{Fore.YELLOW}Goodbye!{Style.RESET_ALL}") | |
| break | |
| else: | |
| print(f"{Fore.RED}Invalid choice. Please choose 1, 2, or 3.{Style.RESET_ALL}") | |
| if __name__ == "__main__": | |
| main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment