Lucene search
+L

Transform Chain

🗓️ 19 Aug 2026 05:37:22Reported by KittySploitType 
kittysploit
 kittysploit
🔗 kittysploit.com👁 2 Views

Transform Chain allows stacking multiple stream transforms on one C2 channel.

Refs
Code
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""Composable transform chain — stack multiple stream transforms on one C2 channel."""

from __future__ import annotations

import importlib
import re
from typing import List, Optional

from kittysploit import *


def _split_chain(spec: str) -> List[str]:
    parts = []
    for chunk in re.split(r"[,;]+", spec or ""):
        chunk = chunk.strip()
        if chunk:
            parts.append(chunk)
    return parts


class Module(Transform):
    """Apply multiple transforms in order (encode) or reverse order (decode)."""

    SUPPORTED_CLIENT_LANGUAGES = ["python"]

    __info__ = {
        "name": "Transform Chain",
        "description": "Stack multiple stream transforms (comma-separated module paths).",
        "author": "KittySploit Team",
        "version": "1.0.0",
    }

    chain = OptString(
        "transforms/python/stream/xor",
        "Comma-separated transform module paths, applied left-to-right on encode",
        True,
    )

    def __init__(self, framework=None):
        super().__init__(framework)
        self._chain_instances: List[Transform] = []
        self._chain_paths: List[str] = []
        self._encode_offsets: List[int] = []
        self._decode_offsets: List[int] = []

    def _ensure_chain_loaded(self) -> None:
        spec = str(getattr(getattr(self, "chain", None), "value", self.chain) or "").strip()
        paths = _split_chain(spec)
        if paths == self._chain_paths and self._chain_instances:
            return
        self._chain_instances = []
        self._chain_paths = []
        self._encode_offsets = []
        self._decode_offsets = []
        for path in paths:
            mod_path = "modules." + path.replace("/", ".")
            mod = importlib.import_module(mod_path)
            cls = getattr(mod, "Module", None)
            if cls is None:
                continue
            inst = cls(framework=getattr(self, "framework", None))
            self._chain_instances.append(inst)
            self._chain_paths.append(path)
            self._encode_offsets.append(0)
            self._decode_offsets.append(0)

    def get_supported_client_languages(self) -> List[str]:
        self._ensure_chain_loaded()
        if not self._chain_instances:
            return list(self.SUPPORTED_CLIENT_LANGUAGES)
        langs = None
        for inst in self._chain_instances:
            supported = set(inst.get_supported_client_languages())
            langs = supported if langs is None else langs & supported
        return sorted(langs or [])

    def encode(self, data: bytes, offset: int = 0) -> bytes:
        self._ensure_chain_loaded()
        if not data or not self._chain_instances:
            return data
        current = data
        for idx, xf in enumerate(self._chain_instances):
            inp_len = len(current)
            try:
                current = xf.encode(current, self._encode_offsets[idx])
            except TypeError:
                current = xf.encode(current)
            self._encode_offsets[idx] += inp_len
        return current

    def decode(self, data: bytes, offset: int = 0) -> bytes:
        self._ensure_chain_loaded()
        if not data or not self._chain_instances:
            return data
        current = data
        for idx in reversed(range(len(self._chain_instances))):
            xf = self._chain_instances[idx]
            inp_len = len(current)
            try:
                current = xf.decode(current, self._decode_offsets[idx])
            except TypeError:
                current = xf.decode(current)
            self._decode_offsets[idx] += inp_len
        return current

    def connection_copy(self):
        copy_xf = self.__class__(framework=getattr(self, "framework", None))
        copy_xf.set_option("chain", str(getattr(getattr(self, "chain", None), "value", self.chain) or ""))
        for name in self.get_options():
            if name == "chain":
                continue
            try:
                val = getattr(self, name)
                copy_xf.set_option(name, val)
            except Exception:
                pass
        return copy_xf

    def generate_client_code(self, language: str) -> Optional[str]:
        self._ensure_chain_loaded()
        if language != "python" or not self._chain_instances:
            return None

        chunks: List[str] = []
        encode_calls: List[str] = []
        decode_calls: List[str] = []

        for idx, xf in enumerate(self._chain_instances):
            if not hasattr(xf, "generate_client_code"):
                return None
            code = xf.generate_client_code(language)
            if not code:
                return None
            renamed = code.replace("_xf_", f"_xfc{idx}_")
            chunks.append(renamed)
            encode_calls.append(f"_xfc{idx}_encode")
            decode_calls.insert(0, f"_xfc{idx}_decode")

        body_encode = "d"
        for fn in encode_calls:
            body_encode = f"{fn}({body_encode})"
        body_decode = "d"
        for fn in decode_calls:
            body_decode = f"{fn}({body_decode})"

        return (
            "\n".join(chunks)
            + "\n"
            + "def _xf_encode(d):\n"
            + f" return {body_encode}\n"
            + "def _xf_decode(d):\n"
            + f" return {body_decode}\n"
        )

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

19 Aug 2026 05:37Current
5.8Medium risk
Vulners AI Score5.8
2