Operation Hallucination is a multi-stage CTF challenge that demonstrates the platform's ability to guide players through complex, progressive scenarios with narrative immersion, technical validation, and hands-on AWS experience. Understanding the challenge flow is essential to understanding how the architecture supports interactive, secure gameplay.
Operation Hallucination consists of 4 stages, each requiring different skills and AWS knowledge:
┌─────────────────────────────────────────────────────────────────┐
│ OPERATION HALLUCINATION COMPLETE FLOW │
│ │
│ STAGE 1: MISSION BRIEFING (/challenges/hallucination) │
│ ┌──────────────────────────────────────┐ │
│ │ • Display narrative context: │ │
│ │ "GenAI data poisoning attack" │ │
│ │ • Show encrypted message excerpt │ │
│ │ • Present riddle to solve: │ │
│ │ "Through neural webs I weave..." │ │
│ │ • Player clicks "Accept Mission" │ │
│ └──────────┬───────────────────────────┘ │
│ │ │
│ │ POST /challenges/progression │
│ │ { email, challengeId: "hallucination", │
│ │ stage: 1, completed: "false" } │
│ ▼ │
│ ┌──────────────────────────────────────┐ │
│ │ Lambda: awschallenges_stage_ │ │
│ │ progression │ │
│ │ • Updates DynamoDB: │ │
│ │ challengeProgress.hallucination. │ │
│ │ stage1 = { completed: 0, │ │
│ │ attempts: 0 } │ │
│ │ • Returns success response │ │
│ └──────────┬───────────────────────────┘ │
│ │ │
│ │ router.push('/challenges/hallucination_2') │
│ ▼ │
│ │
│ STAGE 2: RIDDLE VALIDATION (/challenges/hallucination_2) │
│ ┌──────────────────────────────────────┐ │
│ │ • Display full riddle text │ │
│ │ • Input field for answer │ │
│ │ • Player enters: "GenAI" (correct) │ │
│ │ or similar variations │ │
│ │ • Clicks "Begin Validation" │ │
│ └──────────┬───────────────────────────┘ │
│ │ │
│ │ POST /challenges/hallucination/salt │
│ │ { text: "GenAI", email: "user@example.com" } │
│ ▼ │
│ ┌──────────────────────────────────────┐ │
│ │ Lambda: awschallenge_hallucination_ │ │
│ │ salt │ │
│ │ • analyze_neural_input(text): │ │
│ │ - Exact match: GenAI, Gen AI, etc.│ │
│ │ - Close match: LLM, AI model, etc.│ │
│ │ • Track attempts in DynamoDB: │ │
│ │ - wrongAttempts (max 3) │ │
│ │ - closeAttempts (max 3) │ │
│ │ - lockedUntil (30-min lockout) │ │
│ │ • Return neural-themed response: │ │
│ │ - Success: "Access Granted!" │ │
│ │ - Close: "Partial Synchronization"│ │
│ │ - Wrong: "Prompt Injection Failed"│ │
│ │ - Locked: "Compromised Agent" │ │
│ └──────────┬───────────────────────────┘ │
│ │ │
│ │ IF SUCCESS: │
│ │ POST /challenges/progression │
│ │ { stage: 2, completed: "true" } │
│ │ router.push('/challenges/hallucination_3') │
│ ▼ │
│ │
│ STAGE 3: KMS DECRYPTION (/challenges/hallucination_3) │
│ ┌──────────────────────────────────────┐ │
│ │ • Display encrypted message blob │ │
│ │ • Explain KMS decryption task │ │
│ │ • Player clicks "Request Access" │ │
│ └──────────┬───────────────────────────┘ │
│ │ │
│ │ POST /challenges/hallucination/kmsdecrypt │
│ │ { email: "user@example.com" } │
│ ▼ │
│ ┌──────────────────────────────────────┐ │
│ │ Lambda: getKMSDecrypt │ │
│ │ • AWS STS AssumeRole: │ │
│ │ - Role: KMSDecryptRole │ │
│ │ - Session: 30 minutes │ │
│ │ - Policy: kms:Decrypt only │ │
│ │ • Returns temporary credentials: │ │
│ │ { │ │
│ │ AccessKeyId: "ASIAZ...", │ │
│ │ SecretAccessKey: "...", │ │
│ │ SessionToken: "...", │ │
│ │ Expiration: "ISO timestamp" │ │
│ │ } │ │
│ │ • Display credentials to player │ │
│ └──────────┬───────────────────────────┘ │
│ │ │
│ │ Player uses AWS CLI manually: │
│ │ $ export AWS_ACCESS_KEY_ID=... │
│ │ $ export AWS_SECRET_ACCESS_KEY=... │
│ │ $ export AWS_SESSION_TOKEN=... │
│ │ $ aws kms decrypt --ciphertext-blob ... │
│ │ │
│ │ Decrypted message reveals: │
│ │ "MENTAT VEIL PROTOCOL" │
│ │ │
│ │ Player manually navigates to: │
│ │ router.push('/challenges/hallucination_4') │
│ ▼ │
│ │
│ STAGE 4: FINAL VALIDATION (/challenges/hallucination_4) │
│ ┌──────────────────────────────────────┐ │
│ │ • Input field for protocol name │ │
│ │ • Player enters: │ │
│ │ "MENTAT VEIL PROTOCOL" │ │
│ │ • Clicks "Validate Protocol" │ │
│ └──────────┬───────────────────────────┘ │
│ │ │
│ │ POST /challenges/hallucination/finalcheck │
│ │ { email: "...", answer: "MENTAT VEIL PROTOCOL" } │
│ ▼ │
│ ┌──────────────────────────────────────┐ │
│ │ Lambda: awschallengehallucination_ │ │
│ │ final_check │ │
│ │ • Validate protocol name: │ │
│ │ - Exact: "MENTAT VEIL PROTOCOL" │ │
│ │ - Variants: case-insensitive, │ │
│ │ partial matches ("VEIL PROTOCOL")│ │
│ │ • Verify stage completion: │ │
│ │ - Must complete Stages 1-3 first │ │
│ │ • Track attempts (same as Stage 2) │ │
│ │ • IF SUCCESS: │ │
│ │ - POST /challenges/progression │ │
│ │ { stage: 4, completed: "true" } │ │
│ │ - Calculate score: │ │
│ │ * Direct success: 1000 points │ │
│ │ * After persistence: 800 points │ │
│ │ - Lambda: awschallenge_score_ │ │
│ │ update │ │
│ │ - Update user level if threshold │ │
│ │ reached │ │
│ │ - router.push('/challenges/ │ │
│ │ hallucination_success') │ │
│ └──────────────────────────────────────┘ │
│ │
│ SUCCESS PAGE (/challenges/hallucination_success) │
│ ┌──────────────────────────────────────┐ │
│ │ • Mission completion message │ │
│ │ • Display updated score/level │ │
│ │ • Narrative conclusion │ │
│ │ • Button: Return to Dashboard │ │
│ └──────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Multi-Stage Design
The multi-stage approach builds progressive difficulty where each stage teaches skills incrementally: puzzle solving leads to AWS knowledge, which leads to cryptography. This structure validates different skills at each checkpoint, maintaining player engagement through a sense of progress. The design mirrors real CTF scenarios with multi-step investigation workflows and provides a flexible pattern for creating new challenges.
Each challenge stage has specific validation requirements and error handling:
POST /challenges/progressionchallengeProgress.hallucination.stage1 = { completed: 0, attempts: 0 } in DynamoDBgenai, gen ai, gen-ai, generative ai, generative-aillm, large language model, ai model, generative, chatbot, chat gpt, mlawschallenge_hallucination_saltMAX_WRONG_ATTEMPTS = 3 MAX_CLOSE_ATTEMPTS = 3 LOCKOUT_MINUTES = 30 # DynamoDB attributes: wrongAttempts: number # Increments on wrong answer closeAttempts: number # Increments on close answer lockedUntil: string # ISO timestamp for lockout expiration
getKMSDecrypt (uses AWS STS AssumeRole){
"AccessKeyId": "ASIAZ...",
"SecretAccessKey": "...",
"SessionToken": "...",
"Expiration": "2024-01-15T12:30:00Z"
}
kms:Decrypt action only on specific keyaws kms decrypt \ --ciphertext-blob fileb://encrypted_message.bin \ --output text \ --query Plaintext | base64 --decode
mentat veil protocol, MENTAT VEIL PROTOCOL, Mentat Veil Protocolveil protocol, mentat protocol, mentat veilawschallengehallucination_final_checkcurrentScore >= threshold, increment currentLevel (1 → 2 → 3)challengeProgress.hallucination.stage4 = { completed: 1, attempts: X }awschallenge_score_update Lambda/challenges/hallucination_successDual Validation Strategy
The platform employs both client-side and server-side validation. Client-side validation provides immediate feedback through form validation, input sanitization, and loading states, enhancing user experience. Server-side validation in Lambda functions serves as the authoritative source of truth, preventing cheating and ensuring data integrity. This separation allows validation logic updates through Lambda redeployment without requiring frontend changes.