4. Challenge Flow & Operation Hallucination

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.

4.1 Challenge Stage Flow

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.

4.2 Challenge Validation Logic

Each challenge stage has specific validation requirements and error handling:

Stage 1: Mission Acceptance

  • Validation: None (automatic progression)
  • Purpose: Track that player has started the challenge, establish narrative context
  • API Call: POST /challenges/progression
  • Storage: challengeProgress.hallucination.stage1 = { completed: 0, attempts: 0 } in DynamoDB
  • Next Step: Redirect to Stage 2 immediately

Stage 2: Riddle Answer Validation

  • Validation: Answer must match exact or close patterns
  • Exact Patterns (Success):
    • genai, gen ai, gen-ai, generative ai, generative-ai
    • Case-insensitive, whitespace-tolerant
  • Close Patterns (Partial Credit):
    • llm, large language model, ai model, generative, chatbot, chat gpt, ml
    • Encourages persistence and learning
  • Lambda: awschallenge_hallucination_salt
  • Attempt Tracking:
    MAX_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
  • Response Messages:
    • Success: "Validation Successful - Access Granted! Encryption salt: GenAI"
    • Close: "Neural Analysis: Partial Synchronization Detected. Try a variation. {X} attempts remaining..."
    • Wrong: "Prompt Injection Failed - Access Denied. {X} attempts remaining..."
    • Locked: "ALERT: Compromised Agent Detected. Systems locked for 30 minutes. Unlock at {timestamp}"
  • Persistence Bonus: After 3 close attempts, player unlocks Stage 3 with reduced score (800 vs 1000 points)

Stage 3: KMS Decryption

  • Validation: None (credentials provided automatically)
  • Purpose: Teach AWS CLI usage and KMS decryption
  • Lambda: getKMSDecrypt (uses AWS STS AssumeRole)
  • Credentials:
    {
      "AccessKeyId": "ASIAZ...",
      "SecretAccessKey": "...",
      "SessionToken": "...",
      "Expiration": "2024-01-15T12:30:00Z"
    }
  • Validity: 30 minutes (enforced by AWS STS)
  • Permissions: Scoped to kms:Decrypt action only on specific key
  • Decryption Command:
    aws kms decrypt \
      --ciphertext-blob fileb://encrypted_message.bin \
      --output text \
      --query Plaintext | base64 --decode
  • Decrypted Message: "MENTAT VEIL PROTOCOL" (answer for Stage 4)
  • Manual Progression: Player navigates to Stage 4 manually after decryption

Stage 4: Final Protocol Name Validation

  • Validation: Answer must match exact or close variants
  • Exact Patterns (Success):
    • mentat veil protocol, MENTAT VEIL PROTOCOL, Mentat Veil Protocol
    • Case-insensitive, whitespace-tolerant
  • Close Patterns (Partial Credit):
    • veil protocol, mentat protocol, mentat veil
    • Accepts partial matches for flexibility
  • Lambda: awschallengehallucination_final_check
  • Prerequisite Check: Verifies Stages 1-3 completed before allowing Stage 4 submission
  • Attempt Tracking: Same mechanism as Stage 2 (3 wrong, 3 close, 30-min lockout)
  • Score Calculation:
    • Direct Success (≤3 total attempts): 1000 points
    • Success with Persistence (4-6 attempts): 800 points
    • Success after Lockout: 600 points
  • Level Update: If currentScore >= threshold, increment currentLevel (1 → 2 → 3)
  • On Success:
    • Update challengeProgress.hallucination.stage4 = { completed: 1, attempts: X }
    • Trigger awschallenge_score_update Lambda
    • Redirect to /challenges/hallucination_success

Dual 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.