import argparse import sys import os from flask import Flask, render_template, request, redirect, url_for, abort from Modules.windows import get_windows_content from Modules.Persistence.persistence import get_persistence_menu from Modules.Persistence.autostart import * from Modules.linux import get_linux_content from Modules.tips import get_random_tip_or_joke from Modules.methodology import get_methodology_content from Modules.investigate import get_investigate_content from Modules.Investigate.threat import * from Modules.Investigate.ip import * from Modules.Investigate.domain import * from Modules.Investigate.filehash import * from Modules.Investigate.malware import * from static.ascii_text_prompts import full_ascii_art_stripped, infinitei_stripped from config.config import VERSION app = Flask(__name__) # In-memory data store for the notebook page notebook = { "notes": [], "ips": [], "domains": [], "services": [], "tasks": [] } @app.context_processor def inject_tip(): """ Add a random tip or joke to every page's context. """ return {"random_tip": get_random_tip_or_joke()} README_PATH = os.path.join(os.getcwd(), "README.md") def get_readme_description(): """ Extract the description starting with "HUNT-AI" and stopping at the next blank line from the README.md file. """ if not os.path.exists(README_PATH): return "No description available." description = [] capture = False try: with open(README_PATH, "r", encoding="utf-8") as readme_file: for line in readme_file: # Start capturing from the line containing "HUNT-AI" if "HUNT-AI" in line: capture = True description.append(line.strip()) # Continue capturing until a blank line is encountered elif capture: if line.strip() == "": break description.append(line.strip()) except Exception as e: return f"Error reading README.md: {e}" return " ".join(description) if description else "No description available." @app.route('/') def home(): # Read description from README.md readme_description = get_readme_description() # Links to display on the home page links = [ {"name": "Visit Start.me", "url": "https://start.me/p/qbzw4e/cyber-security"}, {"name": "Visit My Website", "url": "https://infinit3i.com/"} ] return render_template( 'index.html', full_ascii_art=full_ascii_art_stripped, infinitei=infinitei_stripped, links=links, readme_description=readme_description ) @app.route('/methodology') def methodology(): content = get_methodology_content() return render_template('methodology.html', content=content) @app.route('/linux') def linux(): sections = get_linux_content() return render_template('linux.html', sections=sections) @app.route('/linux/') def linux_section(title): sections = get_linux_content() section = next((s for s in sections if s["title"].replace(" ", "_").lower() == title.lower()), None) if not section: abort(404) return render_template('section.html', section=section) @app.route('/rule_creation') def rule_creation(): return render_template('rule_creation.html') @app.route('/windows') def windows(): # Load all sections sections = get_windows_content() return render_template('windows.html', sections=sections) @app.route('/windows/<title>') def windows_section(title): # Find the section matching the title sections = get_windows_content() section = next((s for s in sections if s["title"].replace(" ", "_").lower() == title.lower()), None) if not section: abort(404) # Return a 404 if the section is not found return render_template('section.html', section=section) @app.route('/persistence') def persistence_submenu(): """ Displays the submenu for all persistence methods. """ menu = get_persistence_menu() return render_template('persistence_submenu.html', menu=menu) @app.route('/persistence/<method>') def persistence_method(method): """ Dynamically load content for a specific persistence method. """ try: # Dynamically import the requested method module module = __import__(f"Modules.Persistence.{method}", fromlist=["get_content"]) content = module.get_content() return render_template('persistence_method.html', content=content) except ModuleNotFoundError: abort(404, description=f"Persistence method '{method}' not found.") @app.route('/investigate') def investigate(): content = get_investigate_content() return render_template('investigate.html', content=content) @app.route('/investigate/threat') def investigate_threat(): content = get_threat_content() return render_template('investigate.html', content=content) @app.route('/investigate/domain') def investigate_domain(): content = get_domain_content() return render_template('investigate.html', content=content) @app.route('/investigate/filehash') def investigate_filehash(): content = get_filehash_content() return render_template('investigate.html', content=content) @app.route('/investigate/ip') def investigate_ip(): content = get_ip_content() return render_template('investigate.html', content=content) @app.route('/investigate/malware') def investigate_malware(): content = get_malware_content() return render_template('investigate.html', content=content) def display_help(): """ Display help information for the command-line interface. """ help_text = f""" Usage: python3 app.py Start the Flask application python3 app.py -v Display the current version python3 app.py -h Show this help page python3 app.py -f <file> Load the last session file for collaboration """ print(help_text) def get_version(): """ Display the version of the application. """ print(f"App Version: {VERSION}") def load_session(file_path): """ Load a session file and display its contents. """ try: with open(file_path, "r") as file: session_data = file.read() print(f"Session loaded successfully from {file_path}:\n") print(session_data) except FileNotFoundError: print(f"Error: File '{file_path}' not found.") except Exception as e: print(f"Error: {e}") def handle_arguments(): """ Parse and handle command-line arguments. """ parser = argparse.ArgumentParser( description="App Runner - Threat AI Command Interface", usage="python3 app.py [-v | -h | -f <file>]" ) parser.add_argument("-v", "--version", action="store_true", help="Display the current version") parser.add_argument("-f", "--file", type=str, help="Load the last session file for collaboration") args = parser.parse_args() if args.version: get_version() sys.exit(0) elif args.file: load_session(args.file) sys.exit(0) @app.route('/notebook', methods=['GET', 'POST']) def notebook_page(): if request.method == 'POST': # Capture data from form submission category = request.form.get('category') entry = request.form.get('entry') if category in notebook and entry: notebook[category].append(entry) return render_template('notebook.html', notebook=notebook) @app.route('/delete/<category>/<int:index>') def delete_entry(category, index): if category in notebook and 0 <= index < len(notebook[category]): notebook[category].pop(index) return redirect(url_for('notebook_page')) if __name__ == '__main__': # If arguments are passed, handle them; otherwise, run the Flask app. if len(sys.argv) > 1: handle_arguments() else: app.run(debug=True)