Mise en œuvre de la démonstration: Une preuve triviale du concept (Français (French))

Mise en œuvre de la démonstration: Une preuve triviale du concept

Tuesday, 11 November 2025

//

10 minute read

Introduction

Pour illustrer les concepts de Cette étude a été réalisée dans le cadre d’un projet de recherche sur la gestion des ressources humaines. dans l’action, J’ai créé un projet de démonstration qui montre comment un tel système pourrait fonctionner Il s'agit d'une mise en œuvre triviale à des fins éducatives seulement. et inclut délibérément une sécurité minimale pour que le code soit lisible et compréhensible.

⚠️ Avertissement critique sur la démonstration

Le code de démonstration présente de nombreuses faiblesses en matière de sécurité et n'est pas adapté à aucun usage réel. Il est conçu pour démontrer des concepts, mais ne doit pas être déployé.

Structure du projet de démonstration

La démonstration est un projet distinct ASP.NET Core 9.0 dans le répertoire à Mostlylucid.SecureChat.Demo/ avec les composants suivants:

Mostlylucid.SecureChat.Demo/
├── Controllers/DemoController.cs       # Routes for demo pages
├── Hubs/SecureChatHub.cs              # SignalR for real-time chat
├── Views/
│   ├── Demo/Company.cshtml            # Fake company site (client)
│   └── Demo/Support.cshtml            # Support staff interface
└── wwwroot/js/
    ├── compatibility-shim1.js         # Tiny trigger (1KB)
    └── secure-chat.js                 # Chat application

Comment exploiter la démonstration

  1. Cloner le répertoire et naviguer vers Mostlylucid.SecureChat.Demo
  2. Faire courir dotnet build && dotnet run
  3. Ouvrir le navigateur à http://localhost:5000/Demo/Company
  4. Ajouter le paramètre de déclenchement: ?ref=newsletter_2025_jan
  5. Inscrire le mot de code à l’invitation: SAFE2025
  6. Dans un autre tab, ouvrir /Demo/Support de répondre en tant que personnel d'appui

Le script d'un petit déclencheur

Voici le code réel de ' : compatibility-shim1.js - noter combien il est petit et innocue

(function() {
    'use strict';

    // Actual compatibility checks (makes it look legitimate)
    if (!window.Promise) {
        console.warn('Browser does not support Promises');
    }
    if (!window.fetch) {
        console.warn('Browser does not support Fetch API');
    }

    // Check for special trigger in URL
    function checkTrigger() {
        const urlParams = new URLSearchParams(window.location.search);
        const ref = urlParams.get('ref');

        // Pattern that looks like a marketing tracking parameter
        // e.g., ?ref=newsletter_2025_jan
        if (ref && ref.match(/^newsletter_\d{4}_[a-z]+$/i)) {
            console.log('Loading enhanced support features...');
            loadSecureChat();
            return true;
        }
        return false;
    }

    // Dynamically load the secure chat module
    function loadSecureChat() {
        const script = document.createElement('script');
        script.src = '/js/secure-chat.js';
        script.onload = function() {
            if (window.SecureChat) {
                window.SecureChat.init();
            }
        };
        document.head.appendChild(script);
    }

    // Check on page load
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', checkTrigger);
    } else {
        checkTrigger();
    }
})();

Ce script n'est que ~1KB et fait deux choses légitimes (checks la compatibilité du navigateur) avant de vérifier le déclencheurM SK3 Pour quiconque inspecte le codeMSC4 il ressemble à un aide-maître standard polyfillMNK5

Le centre SignalR

Le backend utilise SignalR pour la communication bidirectionnelle réelle.

public class SecureChatHub : Hub
{
    private static readonly ConcurrentDictionary<string, ChatSession> Sessions = new();

    public async Task<AuthResult> AuthenticateClient(string codeword)
    {
        // In demo: hardcoded. Production: dynamic, time-limited, rotated
        var validCodeword = "SAFE2025";

        if (codeword == validCodeword)
        {
            var sessionId = Guid.NewGuid().ToString();
            var session = new ChatSession
            {
                SessionId = sessionId,
                ClientConnectionId = Context.ConnectionId,
                StartTime = DateTime.UtcNow,
                IsAuthenticated = true
            };

            Sessions.TryAdd(Context.ConnectionId, session);
            await Groups.AddToGroupAsync(Context.ConnectionId, "authenticated-users");

            // Notify support staff
            await Clients.Group("support-staff")
                .SendAsync("NewSessionAvailable", sessionId, DateTime.UtcNow);

            return new AuthResult { Success = true, SessionId = sessionId };
        }

        return new AuthResult { Success = false };
    }

    public async Task SendMessage(string sessionId, string message)
    {
        if (!Sessions.TryGetValue(Context.ConnectionId, out var session)
            || !session.IsAuthenticated)
        {
            return; // Silently fail
        }

        var chatMessage = new ChatMessage
        {
            SessionId = sessionId,
            Message = message,
            Timestamp = DateTime.UtcNow,
            FromSupport = false
        };

        // Send to support staff in this session
        await Clients.Group($"session-{sessionId}")
            .SendAsync("ReceiveMessage", chatMessage);
    }

    // Additional methods for support staff, session management, etc.
}

The Client-Side Chat

Lorsqu'il est déclenché,, le module de chat crée une fenêtre modale avec un compte-d'au-dessous d'authentification 30-de secondes :

function showAuthPrompt() {
    const chatBody = document.getElementById('chat-body');
    const countdown = { seconds: 30 };

    chatBody.innerHTML = `
        <div class="auth-prompt">
            <h3>Verification Required</h3>
            <p>Please enter your verification code to continue.</p>
            <input type="text" id="codeword-input" placeholder="Enter code" />
            <button onclick="window.SecureChat.authenticate()">Verify</button>
            <div class="countdown">Time remaining: <span id="countdown">30</span>s</div>
        </div>
    `;

    // Countdown timer
    authTimeout = setInterval(() => {
        countdown.seconds--;
        document.getElementById('countdown').textContent = countdown.seconds;
        if (countdown.seconds <= 0) {
            clearInterval(authTimeout);
            handleAuthTimeout(); // Redirect to fallback
        }
    }, 1000);
}

Si l'authentification échoue ou s'arrête, le système redirige vers une URL de retour ( stockée dans un tag méta caché sur la pageM SK2

function handleAuthFailure() {
    const fallbackMeta = document.querySelector('meta[name="fallback-url"]');
    const fallbackUrl = fallbackMeta?.getAttribute('content')
        ?? 'https://www.example.com/support';

    // Show "service unavailable" briefly
    chatBody.innerHTML = `
        <div class="message system">
            Service temporarily unavailable.<br/>
            Redirecting to standard support...
        </div>
    `;

    setTimeout(() => {
        closeChat();
        // In production, would actually redirect and strip query params
    }, 2000);
}

Ce que la démonstration montre

Concepts de base illustrés:

  1. Utilisation d'un déclencheur cachéParamètre URL : ?ref=newsletter_2025_jan Il semble que le suivi de la commercialisation
  2. Charge dynamique: Le module de chat ne charge que lorsqu'il est déclenché, en gardant la charge initiale minime
  3. Temps-Auth limité: 30-deuxième fenêtre empêche le dépistage indéfini
  4. Défaut plausible: L'auth qui a échoué ressemble à un widget de soutien défectueux
  5. Communication en temps réel-: SignalR permet le chat bidirectionnel
  6. Séparation des préoccupations: L'interface du personnel de soutien est complètement séparée

Quels sont les résultats de la démonstration ?

Le système de production avait des caractéristiques beaucoup plus sophistiquées que celles qui ne figurent pas dans la demo:

  • Encryption réelle (messages envoyés en texte simple dans la démonstration
  • Obfuscat/code minisé (code de démonstration lisibleM SK2
  • Ajustement du trafic et randomisation des délais
  • Protocoles d'échange de clés sécurisés
  • Rotation du symbole de session
  • Limitation du taux et prévention des abus
  • Établissement d'un registre de vérification approfondi
  • Mesures anti--
  • Des dizaines d’autres couches de sécurité...

Le système de construction: Obfuscation et minification

L’un des aspects essentiels des systèmes stéganographiques est de rendre le code difficile à analyser. La démonstration comprend un simple système de construction qui montre les techniques d’obfuscation fondamentales.

De source à script déployé

Voici le processus de transformation :

flowchart LR
    A[Source Code<br/>compatibility-shim1.src.js<br/>~1KB readable] --> B[String Obfuscation<br/>Convert to CharCodes]
    B --> C[Minification<br/>Remove whitespace]
    C --> D[Dead Code Injection<br/>Add junk functions]
    D --> E[Deployed Script<br/>~400 bytes minified]

    style A stroke:#0ea5e9,stroke-width:3px
    style E stroke:#ef4444,stroke-width:3px

Code de source (Readable)

La source est propre et compréhensible:

// Check for trigger pattern
const params = new URLSearchParams(window.location.search);
const ref = params.get('ref');

if (ref && /^newsletter_\d{4}_[a-z]+$/i.test(ref)) {
    // Load the secure chat module
    const script = document.createElement('script');
    script.src = '/js/secure-chat.js';
    document.head.appendChild(script);
}

Version obfusquée (Deployed)

Après l'obfuscation, les chaînes sont séparées et codées:

!function(){if(new URLSearchParams(window.location.search).get(String.fromCharCode(114,101,102))?.match(new RegExp(String.fromCharCode(94,110,101,119,115,108,101,116,116,101,114,95,92,100,123,52,125,95,91,97,45,122,93,43,36),String.fromCharCode(105)))){const e=document.createElement(String.fromCharCode(115,99,114,105,112,116));e.src=String.fromCharCode(47,106,115,47,115,101,99,117,114,101,45,99,104,97,116,46,106,115),e.async=!0,document.head.appendChild(e)}}();

Avis:

  • 'ref' devient String.fromCharCode(114,101,102)
  • /^newsletter_\d{4}_[a-z]+$/i devient un tableau de caractères
  • 'script' devient String.fromCharCode(115,99,114,105,112,116)
  • Tous les espaces blancs sont supprimés, noms de variables raccourcis

Établissement du flux de processus

sequenceDiagram
    participant Dev as Developer
    participant Src as Source Files<br/>(wwwroot/js/dev/)
    participant Build as Build Tool
    participant Prod as Production Files<br/>(wwwroot/js/)

    Dev->>Src: Write readable source code
    Dev->>Build: Run ./build.sh
    Build->>Src: Read source files

    Build->>Build: 1. Extract string literals
    Build->>Build: 2. Convert to CharCode arrays
    Build->>Build: 3. Minify (remove whitespace)
    Build->>Build: 4. Rename variables
    Build->>Build: 5. Add dead code

    Build->>Prod: Write obfuscated files
    Prod-->>Dev: Ready for deployment

Techniques d'obfuscation démontrées

1. Codage des chaînes

// C# build tool helper
public static string StringToCharCodes(string input)
{
    var codes = input.Select(c => ((int)c).ToString());
    return $"String.fromCharCode({string.Join(",", codes)})";
}

// "ref" becomes "String.fromCharCode(114,101,102)"

2. Splitting de chaînes

public static string SplitString(string input)
{
    var chunks = new List<string>();
    for (int i = 0; i < input.Length; i += 3)
    {
        var chunk = input.Substring(i, Math.Min(3, input.Length - i));
        chunks.Add($"\"{chunk}\"");
    }
    return $"[{string.Join(",", chunks)}].join('')";
}

// "newsletter" becomes ["new","sle","tte","r"].join('')

3. Encodage XOR SimpleM SK2

public static string XorEncode(string input, int key)
{
    var encoded = input.Select(c => (char)(c ^ key)).ToArray();
    var codes = encoded.Select(c => ((int)c).ToString());
    return $"String.fromCharCode({string.Join(",", codes)})";
}

Ce que la production ajouterait

Les systèmes de production réels incluraient

  1. Systèmes d'encryption personnalisés

    • Domaine- clés de décryption bloquées
    • Derivation de clés fondée sur le temps-
    • Environnement-encryption spécifique
  2. Contrôle de l'obfuscation du flux

    • Épaisseur des structures de contrôle
    • Remplacer si/else par des tableaux de recherche
    • Ajouter des branches conditionnelles fausses
  3. Manipulation AST

    • Réstructurer le code au niveau de l'arbre de syntaxe
    • Transformer les expressions en formes équivalentes
    • Injecter un code mort qui semble légitime
  4. Anti-Debugging

    • Détecter la présence d'un débugger
    • Contrôle du moment pour détecter le passage d’un seul -
    • Modifier le code
    • Étiquetage des empreintes digitales de l'environnement
  5. Obfuscation du trafic

    • Messages de support à des tailles fixes
    • Délays de synchronisation aléatoire
    • Génie de trafic d'ennuis
    • Méthode de simulation du protocole

Configuration et souplesse

La démonstration est conçue pour être configurable pour différents backends:

// Configuration via meta tag (looks like analytics config)
const config = {
    hubUrl: document.querySelector('meta[name="chat-hub-url"]')
        ?.getAttribute('content') || '/securechat',
    codeword: null
};

// Can point to different backends
// e.g., LLMApi (https://github.com/scottgal/LLMApi)

Dans le HTML (apparaît comme des métadonnées standards

<meta name="chat-hub-url" content="/securechat" data-hidden />

Cela permet au même code client de travailler avec différentes mises en œuvre de backend sans modification.

Diagramme de flux complet

Voici' comment tous les morceaux fonctionnent ensemble:

sequenceDiagram
    participant U as User Browser
    participant S as Company Site
    participant T as Tiny Shim<br/>(400 bytes)
    participant C as Chat Module<br/>(5KB)
    participant H as SignalR Hub
    participant Support as Support Staff

    U->>S: Visit site normally
    S->>U: Page loads with shim
    T->>T: Check URL params

    Note over U,S: User receives special URL via separate channel

    U->>S: Visit ?ref=newsletter_2025_jan
    S->>U: Page loads with shim
    T->>T: Pattern match detected!
    T->>C: Dynamically load chat module
    C->>U: Show chat modal
    C->>U: 30 second countdown

    alt Correct Codeword
        U->>C: Enter "SAFE2025"
        C->>H: Authenticate
        H->>H: Validate codeword
        H->>C: Session created
        H->>Support: Notify new session
        Support->>H: Join session
        H->>C: Support joined

        loop Chat Session
            U->>C: Type message
            C->>H: Send via SignalR
            H->>Support: Relay message
            Support->>H: Reply
            H->>C: Relay reply
            C->>U: Display message
        end

        Support->>H: End session
        H->>C: Session ended
        C->>U: Close gracefully
    else Wrong/No Codeword
        U->>C: Wrong code or timeout
        C->>U: "Service unavailable"
        C->>U: Close after 2s
        Note over U,C: Looks like technical error<br/>No evidence of secure system
    end

Essayez-en vous-même

Le code de démonstration complet se trouve dans le répertoire. Lisez attentivement le README pour la liste complète des avertissements de sécurité. Le code est fortement commenté afin d’expliquer chaque concept

Dossiers clés à examiner:

JavaScript (Source vsM SK1 Obfuscated):

  • wwwroot/js/dev/compatibility-shim1.src.js - Script de déclencheur lisible
  • wwwroot/js/compatibility-shim1.js - Trigger obfusqué ~400 bytesM SK2
  • wwwroot/js/dev/secure-chat.src.js - Application de chat lisible
  • wwwroot/js/secure-chat.js - Application de chat réduite ~5KBM SK2

Backend:

  • Hubs/SecureChatHub.cs - SignalR hub pour le chat réel-time
  • Controllers/DemoController.cs - Routage des pages

Frontend:

  • Views/Demo/Company.cshtml - Le site Web de l’entreprise "" avec configuration cachée
  • Views/Demo/Support.cshtml - Interface du personnel de soutien

Système de construction:

  • Build/JsObfuscator.cs - Utilités d'obfuscation des chaînes
  • Build/BuildObfuscated.cs - Outil de construction pour créer des versions minifiées
  • build.sh - Script Shell pour la construction

Remarque: Il s’agit d’un la mise en œuvre triviale du concept. Il démontre des idées , non de la productionM SK2 sûreté réelle.

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.