Spaces:
Sleeping
Sleeping
| import os | |
| import base64 | |
| import hashlib | |
| import gradio as gr | |
| from pathlib import Path | |
| from Crypto.Cipher import AES | |
| from Crypto.Util import Counter | |
| ROOT = Path(__file__).parent | |
| ASSET_IMG = ROOT / "mascot.png" | |
| REQUIREMENTS = ROOT / "requirements.txt" | |
| def _key_and_nonce(): | |
| # Key = SHA256 of mascot.png bytes | |
| img_bytes = (ASSET_IMG.read_bytes() if ASSET_IMG.exists() else b"") | |
| key = hashlib.sha256(img_bytes).digest() # 32 bytes (AES-256) | |
| # Nonce (8 bytes) derived from first line of requirements.txt | |
| rl = "" | |
| if REQUIREMENTS.exists(): | |
| with REQUIREMENTS.open("r", encoding="utf-8", errors="ignore") as f: | |
| rl = (f.readline() or "").strip() | |
| nonce_src = hashlib.sha1(rl.encode("utf-8")).digest() | |
| nonce = nonce_src[:8] if nonce_src else b"\x00" * 8 | |
| return key, nonce | |
| def _encrypt_flag(flag: str) -> str: | |
| key, nonce = _key_and_nonce() | |
| ctr = Counter.new(64, prefix=nonce, initial_value=0) | |
| cipher = AES.new(key, AES.MODE_CTR, counter=ctr) | |
| ct = cipher.encrypt(flag.encode("utf-8")) | |
| return base64.b64encode(ct).decode("ascii") | |
| def get_ciphertext(): | |
| flag = (os.environ.get("FLAG") or "").strip() | |
| if not flag: | |
| return "⚠️ FLAG not set." | |
| return _encrypt_flag(flag) | |
| def verify(candidate: str): | |
| flag = (os.environ.get("FLAG") or "").strip() | |
| if not flag: | |
| return ("⚠️ FLAG not set.", "") | |
| candidate = (candidate or "").strip() | |
| if not candidate: | |
| return ("No input provided.", "") | |
| if candidate == flag: | |
| # Always return the official flag from env (not user input) | |
| return ("✅ Correct.", flag) | |
| return ("❌ Incorrect.", "") | |
| custom_css = """ | |
| #hero { display: flex; gap: 16px; align-items: center; } | |
| #hero .title h1 { margin: 0; } | |
| """ | |
| with gr.Blocks(title="ENUSEC Freshers – Decrypter 2025", css=custom_css) as demo: | |
| # Hero row with mascot + title | |
| with gr.Row(elem_id="hero"): | |
| gr.Image( | |
| value=str(ASSET_IMG) if ASSET_IMG.exists() else None, | |
| show_label=False, | |
| interactive=False, | |
| height=160, | |
| visible=ASSET_IMG.exists() | |
| ) | |
| gr.Markdown( | |
| """ | |
| # Decrypter 2025 | |
| Click **Get Encrypted Blob** to receive a Base64 string. | |
| Submit the flag when you have it. | |
| """, | |
| elem_classes=["title"] | |
| ) | |
| # Ciphertext section | |
| b = gr.Button("Get Encrypted Blob") | |
| blob = gr.Textbox(label="Ciphertext (Base64)", interactive=False) | |
| b.click(get_ciphertext, None, blob) | |
| # Submission section | |
| gr.Markdown("## Submit Flag") | |
| guess = gr.Textbox(label="freshers{...}") | |
| submit = gr.Button("Submit") | |
| msg = gr.Markdown() | |
| out = gr.Textbox(label="Official Flag", interactive=False) | |
| submit.click(verify, guess, [msg, out]) | |
| if __name__ == "__main__": | |
| demo.launch() | |