Decrypter_2025 / app.py
lewiswatson's picture
Update app.py
44a69a7 verified
raw
history blame
2.85 kB
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()