#framework #metadata #telemetry #helper #warnings #demo #pmsf

bin+lib pmsf

Polymorphic Malware Stage Framework (PMSF): a research-grade Rust framework for simulating and analyzing modular malware stages

1 unstable release

0.1.0 Apr 19, 2025

#609 in Debugging

Download history 145/week @ 2025-04-16

145 downloads per month

MIT license

35KB
478 lines

Polymorphic Malware Stage Framework (PMSF)

Crates.io docs.rs License

⚠️ DISCLAIMER: This framework is a proof‑of‑concept for educational and research use only. The author does not condone or support malicious or unauthorized activities.

PMSF is a robust, research-grade Rust framework engineered for the simulation and analysis of modular malware stages. Designed with a focus on safety, extensibility, and clarity, PMSF empowers security researchers, educators, and students to explore advanced malware staging, evasion, and polymorphism techniques in a controlled, observable environment. All real-world actions are stubbed by default, ensuring a safe and risk-free experience for experimentation and learning.


⚠️ Security Warning

This framework is designed solely for safe simulation of malware stages in research and educational contexts.

Because PMSF is open source, it is possible for someone to modify the code to perform real malicious actions. Always review the code before running it, especially if you received it from an untrusted source.

To verify the code is safe:

  • Open src/lib.rs.
  • Search for the following function names:
    • establish_persistence
    • execute_code
    • communicate_c2
    • perform_anti_analysis
  • Inside each function, look for comments like // Placeholder.
  • If you see only logging and Ok(()) or Ok(true) being returned, it's safe.
  • If you see real system calls, file operations, network connections, or anything that changes your system, that's a red flag.

Never run code you do not trust or understand.


Table of Contents


Why Choose PMSF?

  • Purpose-Built for Security Research & Education: PMSF is tailored for security professionals, educators, and students seeking a safe, hands-on environment to study and demonstrate malware staging and evasion techniques.
  • Risk-Free Simulation: All operational stages are fully stubbed, guaranteeing a non-destructive, controlled experience ideal for experimentation and curriculum development.
  • Modular & Extensible Architecture: Easily add, modify, or chain new techniques with a stage-based, pluggable design—enabling rapid prototyping and comparative analysis.
  • Comprehensive Observability: Integrated logging and telemetry provide deep visibility into stage-level events, supporting detailed analysis and reporting.
  • Configurable & Reproducible: Dynamic configuration and deterministic selection mechanisms allow for precise scenario customization and repeatable experiments.

Key Features

  • Compile-Time Polymorphism: Leverage the rustmorphism crate to generate multiple binaries at build time, enabling diverse technique selection.
  • Dynamic Configuration: Select and orchestrate stages explicitly via a TOML configuration file (config.toml).
  • Runtime Extensibility: Register custom techniques on the fly using a global registry and intuitive register_* functions.
  • Structured Error Handling: Diagnose issues efficiently with the comprehensive FrameworkError enum.
  • Context Propagation: Seamlessly transfer payloads and metadata between stages using the StageContext abstraction.
  • Integrated Logging: Monitor stage-level events in real time with the log crate and env_logger integration.
  • Telemetry Hooks: Instrument research and simulation workflows with the TelemetryEvent trait for custom callbacks.
  • Chaining Utilities: Execute multiple techniques in sequence with run_*_chain, aggregating results and errors.
  • Advanced Selection Helpers: Employ weighted random (weighted_random_choice) and conditional (environment/config) selection utilities for flexible technique orchestration.
  • Comprehensive Example: Explore a full-featured demonstration in examples/demo.rs showcasing all major capabilities.

Installation

Add this to your Cargo.toml:

[dependencies]
pmsf = "0.1.0"

Then import in Rust:

use pmsf::*;

Quick Start

use pmsf::{
    establish_persistence_poly,
    execute_code_poly,
    communicate_c2_poly,
    perform_anti_analysis_poly,
    StageContext,
};

fn main() {
    // Initialize a default stage context (no payload, empty metadata)
    let ctx = StageContext::default();

    // Select and execute the persistence stage
    let persistence = establish_persistence_poly();
    persistence.establish_persistence(&ctx).expect("Persistence stage failed");

    // Select and execute the anti-analysis stage
    let anti_analysis = perform_anti_analysis_poly();
    anti_analysis.perform_anti_analysis(&ctx).expect("Anti-analysis stage failed");

    // Select and execute the code execution stage
    let execution = execute_code_poly();
    execution.execute_code(&ctx).expect("Execution stage failed");

    // Select and execute the C2 communication stage
    let c2 = communicate_c2_poly();
    c2.communicate_c2(&ctx).expect("C2 stage failed");
}

Configuration

To customize stage selection, create a config.toml file in your project root. This allows you to explicitly specify which technique to use for each stage, or omit entries to enable random selection.

# config.toml
# Specify one technique per stage, or omit to use random selection.
persistence = "ScheduledTasks"
execution  = "MappingInjection"
c2         = "DNSTunneling"
anti_analysis = "VMDetection"

Load the configuration at runtime:

let config = FrameworkConfig::from_file("config.toml");
println!("Loaded config: {:?}", config);

Dynamic Registration

You can register your own custom technique at runtime, enabling rapid prototyping and extension:

// Define and implement your stage trait
struct MyTechnique;
impl PersistenceStage for MyTechnique { /* ... */ }

// Register it under a unique name
register_persistence("MyTechnique", || Box::new(MyTechnique));

// Retrieve and use the registered technique by name
if let Some(inst) = get_persistence_by_name("MyTechnique") {
    inst.establish_persistence(&ctx)?;
}

Logging & Telemetry

PMSF supports integrated logging and custom telemetry callbacks for enhanced observability:

use log::LevelFilter;
use env_logger;

env_logger::builder().filter_level(LevelFilter::Info).init();

struct ConsoleTelemetry;
impl TelemetryEvent for ConsoleTelemetry {
    fn on_event(&self, stage: &str, tech: &str, status: &str) {
        println!("Telemetry: {}::{}, {}", stage, tech, status);
    }
}

set_telemetry_callback(Box::new(ConsoleTelemetry));

All stages emit info! logs and trigger on_event(...) on success, or error! on failure.


Chaining Techniques

You can execute multiple techniques in sequence and collect any errors for robust, multi-step simulations:

let errs = run_persistence_chain(&["RegistryRunKeys", "ScheduledTasks"]);
match errs {
    Ok(_) => println!("All persistence steps succeeded."),
    Err(e) => println!("Errors: {:?}", e),
}

Helpers

PMSF provides utility functions for advanced technique selection:

  • Weighted random selection:
    weighted_random_choice(&[("A", 70), ("B", 30)])
    
  • Conditional selection based on environment/config:
    select_technique_by_condition(&choices, "ENV_VAR")
    

Examples

Build and run the comprehensive demo:

cargo run --example demo

This example demonstrates config loading, registration, logging, telemetry, and chaining.


Contributing

Issues, pull requests, and suggestions are welcome. Please follow standard Rust project conventions.


License

The MIT License — see LICENSE for details.

Dependencies

~3.5–6MB
~102K SLoC