CyberChef

repository·master·Indexed 12 days ago

https://github.com/gchq/cyberchef

A web-based 'Cyber Swiss Army Knife' for performing complex data operations including encryption, encoding, compression, and parsing entirely within the browser. Version 11.3.0 features a recipe-based pipeline for sequential data manipulation, automated encoding detection ('Magic'), and deep linking for sharing configurations. It includes a core library for low-level data handling such as Bech32 encoding/decoding, bitwise operations, and ID3v2 metadata parsing.

Tokens
9.3K
Snippets
35
Records
43
Agent score
99%

What's inside CyberChef

  1. CyberChef core features

    master

    CyberChef provides several advanced features for data analysis:

    • Auto Bake: Automatically re-runs the recipe whenever the input or recipe changes. This can be toggled off for large inputs to improve performance.
    • Automated encoding detection ('Magic'): Automatically detects common encodings. If detected, a 'magic' icon appears in the Output field to allow quick decoding.
    • Breakpoints: Allows you to pause execution at any operation in the recipe and step through the process one operation at a time to inspect intermediate data states.
    • Save/Load Recipes: Recipes can be saved to local storage or shared via the URL.
    • Client-side processing: All processing happens entirely within your browser. No input data or recipe configurations are sent to a server, making it safe for use in closed networks or via local downloads.
  2. How CyberChef works

    master

    CyberChef is a web-based tool for data manipulation consisting of four main functional areas:

    1. Input: Located in the top right. Paste, type, or drag text/files here to begin processing.
    2. Output: Located in the bottom right. Displays the result of your operations.
    3. Operations: Located on the far left. A searchable, categorized list of all available cyber operations (e.g., XOR, Base64, AES, hashing).
    4. Recipe: The central area. You build a processing pipeline by dragging operations from the list into this area and configuring their arguments.

    Operations are executed sequentially as a 'recipe'.

  3. Use deep linking to share recipes and inputs

    master

    You can manipulate the URL hash to pre-configure the CyberChef state. This is useful for sharing specific recipes or inputs with others.

    The URL format is: https://gchq.github.io/CyberChef/#recipe=Operation()&input=...

    Supported URL arguments:

    • recipe: The sequence of operations to perform.
    • input: The data to process (must be Base64 encoded).
    • theme: The visual theme to apply.
  4. Run CyberChef locally with Docker

    master

    You can run CyberChef locally using Docker. Ensure Docker Desktop is running on your machine before proceeding.

    Option 1: Build the Docker image yourself

    Use this method if you want to build the image from the local source code.

    1. Build the image with the required ulimit:
      docker build --tag cyberchef --ulimit nofile=10000 .
    2. Run the container, mapping port 8080:
      docker run -it -p 8080:8080 cyberchef
    3. Access the app at http://localhost:8080.

    Option 2: Use the pre-built Docker image

    Use this method to skip the build process and pull the official image from GitHub Container Registry.

    docker run -it -p 8080:8080 ghcr.io/gchq/cyberchef:latest

    After running either command, navigate to http://localhost:8080 in your browser.

  5. Implement a custom CyberChef operation by extending the Operation class

    master

    To create a new operation for CyberChef, you must extend the Operation class and implement the core lifecycle methods. The Operation class manages metadata (name, module, description), input/output types (using Dish enums), and the collection of Ingredient objects that represent the operation's parameters.

    Core Methods to Implement

    • run(input, args): The primary execution logic. It takes the input and an array of args (the values for the operation's ingredients) and returns the processed result.
    • present(data, args): (Optional) Overriding this allows you to transform the raw output of run() into a human-readable format for display in the CyberChef UI without changing the actual data returned by run().
    • highlight(pos, args) and highlightReverse(pos, args): (Optional) Used to provide visual highlighting of specific positions within the output.

    Managing Parameters (Ingredients)

    Operations use Ingredient objects to define their configuration interface. You can manage these via:

    • this.args: A getter/setter for the configuration of the ingredients.
    • this.ingValues: A getter/setter for the actual values assigned to the ingredients.
    • validateIngredients(args): Validates the current or provided ingredient values against their constraints, throwing an OperationError if invalid.
    import Operation from './src/core/Operation.mjs';
    
    class MyCustomOperation extends Operation {
        constructor() {
            super();
            this.name = 'My Custom Op';
            this.module = 'custom-module';
            // Add ingredients here using addIngredient()
        }
    
        run(input, args) {
            // Perform transformation logic
            return input.toString().split('').reverse().join('');
        }
    
        present(data, args) {
            // Return a human-readable version for the UI
            return `Result: ${data}`;
        }
    }
  6. How the SigabaMachine components work together

    master

    The SIGABA machine is composed of three distinct rotor banks that interact in a specific sequence during each step:

    1. Control Bank (ControlBank): Generates control outputs. The outputs are derived from signals passing through the control rotors (typically using inputs 'F', 'G', 'H', and 'I').
    2. Index Bank (IndexBank): Takes the outputs from the Control Bank and passes them through the index rotors to produce index outputs.
    3. Cipher Bank (CipherBank): Uses the index outputs to determine which cipher rotors to step. The signal then passes through the cipher rotors to produce the final encrypted/decrypted letter.

    This sequence is orchestrated by the SigabaMachine.step() method, which is called after every letter is processed.

  7. Manage operation sequences with the Recipe class

    master

    The Recipe class is the central controller for a sequence of Operation objects acting upon a Dish. It manages the lifecycle of a recipe, including parsing configurations, hydrating operation instances, executing the sequence, and presenting results.

    Key capabilities include:

    • Configuration: Create recipes from JSON configuration objects or strings.
    • Execution: Run operations sequentially on a Dish, supporting breakpoints and flow control (forking).
    • Flow Control: Detect and handle operations that alter the recipe execution path (e.g., loops or conditional jumps).
    • Presentation: Automatically present the output of the final operation in a user-friendly format.
    import Recipe from './src/core/Recipe.mjs';
    
    // Example: Creating a recipe from a config object
    const recipeConfig = [
      { op: 'To Base64', args: {} },
      { op: 'From Hex', args: { 'alphabet': '0123456789abcdef' } }
    ];
    const recipe = new Recipe(recipeConfig);
  8. Export an operation's configuration for recipes

    master

    The config getter returns a JSON-serializable object representing the operation and its current ingredient configurations. This is used to generate or persist CyberChef recipes.

    Format:

    {
      "op": "Operation Name",
      "args": [
        { "name": "arg_name", "type": "arg_type", "value": "arg_value" }
      ]
    }
  9. Decode Bech32 or Bech32m strings

    master

    The decode function parses a Bech32 or Bech32m encoded string back into its constituent parts.

    Parameters:

    • str (string): The encoded string to decode.
    • encoding (string, default: 'Auto-detect'): Specifies the expected encoding: 'Bech32', 'Bech32m', or 'Auto-detect' (which attempts Bech32 first, then Bech32m).

    Returns: An object containing:

    • hrp (string): The decoded Human-Readable Part.
    • data (number[]): The decoded data bytes.
    • encoding (string): The encoding type that was successfully verified.
    • witnessVersion (number | null): If the string was identified as a SegWit address, this contains the witness version; otherwise null.

    Constraints:

    • The input string cannot be mixed case (must be all uppercase or all lowercase).
    • The input string cannot exceed 90 characters.
    import { decode } from './Bech32.mjs';
    
    const result = decode('bc1qw508d6qejxtdg4yjrsqegz6lq5tx0w362l66p');
    console.log(result.hrp);            // 'bc'
    console.log(result.data);           // [decoded bytes]
    console.log(result.witnessVersion); // e.g., 0
  10. Convert between 8-bit bytes and 5-bit words

    master

    Bech32 uses a 5-bit character set. These utility functions handle the bit-shifting required to convert between standard 8-bit byte arrays and 5-bit word arrays.

    • toWords(data): Converts number[] or Uint8Array (8-bit) to number[] (5-bit words).
    • fromWords(words): Converts number[] (5-bit words) to number[] (8-bit bytes). Throws an OperationError if the padding is invalid (e.g., non-zero bits in padding or too many bits remaining).
    import { toWords, fromWords } from './Bech32.mjs';
    
    const bytes = [72, 101, 108, 108, 111]; // 'Hello'
    const words = toWords(bytes);
    const backToBytes = fromWords(words);
  11. Execute a Recipe on a Dish

    master

    The execute method runs the sequence of operations defined in the recipe against a provided Dish.

    Parameters:

    • dish: The Dish instance containing the data to be processed.
    • startFrom (number, default: 0): The index of the operation in opList to start execution from.
    • forkState (object, default: {}): State used for forked recipes (e.g., containing numRegisters, numJumps, or forkOffset).

    Returns:

    • Promise<number>: The index of the operation where execution finished or paused (e.g., at a breakpoint).

    Behavior:

    • It automatically hydrates operation modules before running.
    • If an operation is disabled, it is skipped.
    • If a breakpoint is encountered, execution pauses and returns the current index.
    • If a flowControl operation is encountered, it manages state jumps and registers.
    • Errors of type OperationError or DishError are caught, and their messages are set as the output in the Dish (as a string), stopping execution at that point.
    // Assuming 'dish' is an existing Dish instance
    const finalIndex = await recipe.execute(dish);
    console.log(`Recipe finished at operation index: ${finalIndex}`);
  12. Read null-terminated bytes with readNullTerminated()

    master

    Use readNullTerminated(bytes, start, encoding) to extract bytes until a null terminator is encountered.

    • If encoding is 1 or 2, it treats the data as UTF-16 and looks for a double null (0x00 0x00).
    • Otherwise, it looks for a single null (0x00).

    Returns an object: { valueBytes: Uint8Array, next: number }, where next is the index immediately following the terminator.

    // encoding 1 or 2 for UTF-16 awareness
    const { valueBytes, next } = readNullTerminated(bytes, 0, 1);