Created
April 27, 2025 22:09
-
-
Save x86-69/57349d7d1a1d20dca209d02fd7e6f7ac to your computer and use it in GitHub Desktop.
UDMCTF 2025 - cmsc351
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
| import itertools | |
| import subprocess | |
| import sys | |
| import os | |
| def generate_candidates(length, chars='st'): | |
| """Generates all possible strings of a given length using specified characters.""" | |
| # Use itertools.product to create all combinations | |
| for item in itertools.product(chars, repeat=length): | |
| yield "".join(item) | |
| def run_program(executable_path, input_string): | |
| """Runs the target program with the given input string.""" | |
| try: | |
| # Ensure the input string includes a newline, as fgets reads lines | |
| input_bytes = (input_string + '\n') | |
| # Run the program, capture stdout and stderr | |
| result = subprocess.run( | |
| [executable_path], | |
| input=input_bytes, | |
| capture_output=True, | |
| text=True, # Decode output as text | |
| check=False # Don't raise exception on non-zero exit code | |
| ) | |
| return result.stdout, result.stderr, result.returncode | |
| except FileNotFoundError: | |
| print(f"Error: Executable '{executable_path}' not found.", file=sys.stderr) | |
| print("Please compile cmsc351.c (e.g., gcc cmsc351.c -o cmsc351) and place it in the same directory.", file=sys.stderr) | |
| sys.exit(1) | |
| except Exception as e: | |
| print(f"An error occurred while running the program: {e}", file=sys.stderr) | |
| return None, str(e), 1 # Indicate error | |
| # --- Configuration --- | |
| EXECUTABLE = './cmsc351' # Path to the compiled C program | |
| PASSWORD_LENGTH = 25 | |
| FAILURE_MESSAGE = "sorry, looks like you shouldn't have fallen asleep in lecture." | |
| # --- End Configuration --- | |
| print(f"Starting brute-force attack on '{EXECUTABLE}'...") | |
| print(f"Generating and testing {2**PASSWORD_LENGTH:,} candidates of length {PASSWORD_LENGTH}...") | |
| # Check if the executable exists and is executable | |
| if not os.path.isfile(EXECUTABLE): | |
| print(f"Error: Executable '{EXECUTABLE}' not found.", file=sys.stderr) | |
| print("Please compile cmsc351.c (e.g., gcc cmsc351.c -o cmsc351) and place it in the same directory.", file=sys.stderr) | |
| sys.exit(1) | |
| if not os.access(EXECUTABLE, os.X_OK): | |
| print(f"Error: Executable '{EXECUTABLE}' is not executable.", file=sys.stderr) | |
| print("Please ensure it has execute permissions (e.g., chmod +x cmsc351).", file=sys.stderr) | |
| sys.exit(1) | |
| count = 0 | |
| for candidate in generate_candidates(PASSWORD_LENGTH): | |
| count += 1 | |
| # Provide some progress feedback occasionally | |
| if count % 100000 == 0: | |
| print(f"Tested {count:,} candidates...") | |
| stdout, stderr, returncode = run_program(EXECUTABLE, candidate) | |
| if stdout is None: # An error occurred during execution | |
| print(f"Stopping due to error running with input: {candidate}") | |
| break | |
| # Check if the failure message is NOT in the output | |
| if FAILURE_MESSAGE not in stdout: | |
| print("\n" + "="*30) | |
| print(f"Success! Found the correct input:") | |
| print(f"Input: {candidate}") | |
| print("-" * 30) | |
| print(f"Program Output (stdout):") | |
| print(stdout.strip()) | |
| if stderr: | |
| print("-" * 30) | |
| print(f"Program Output (stderr):") | |
| print(stderr.strip()) | |
| print("="*30) | |
| break # Stop after finding the correct input | |
| else: | |
| # This block executes if the loop completes without finding the password | |
| print("\nBrute-force finished. Correct input not found.") | |
| print(f"Total candidates tested: {count:,}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment