Skip to content

Conversation

@malfav
Copy link

@malfav malfav commented Nov 10, 2025

avcheck.py – Antivirus and Endpoint Detection and Response (EDR) Artifact Scanner (Volatility 3 Plugin)

avcheck.py is a specialized Volatility 3 plugin designed to detect and enumerate artifacts related to Antivirus (AV) and Endpoint Detection and Response (EDR) solutions within a Windows memory dump.
It enables investigators and threat hunters to identify which security products were active or installed on a system at the time of capture—critical for understanding a compromised system’s defensive posture.


Key Capabilities

Security Software Identification

Performs broad detection of security tools across over 80 known AV and EDR products, including:

  • Windows Defender (MsMpEng.exe)
  • Kaspersky (avp.exe)
  • Symantec
  • AVG
  • CrowdStrike (CsAgent.exe)
  • SentinelOne
  • FireEye
  • And many others

This identification provides immediate situational awareness of protective technologies present on the analyzed host.


Multi-Artifact Detection

Leverages multiple Volatility 3 subsystems to identify security software artifacts across different system components:

  • Processes:
    Scans active process lists (pslist) for executables associated with AV/EDR agents and monitoring daemons.

  • Services:
    Enumerates running services (svcscan) to locate entries related to installed security software.

  • DLLs:
    Inspects loaded libraries (dlllist) to detect known AV/EDR DLLs used for userland hooks or kernel-level integrations.

  • Files:
    Uses file scanning (filescan) to locate security software directories, databases, log files, and quarantine folders.

Each layer of detection provides corroborating evidence of installed and active endpoint protection components.


Detection History Triage

Includes a specialized analysis routine that looks for:

  • Quarantine directories and detection logs
  • Temporary or deleted AV alert files
  • Residual detection history (e.g., Defender history, Kaspersky reports)

These findings offer valuable context on prior malware detections or automated remediation activity performed by security software.


Detailed Summary Reporting

Generates a structured TreeGrid report summarizing all detected artifacts, categorized by source type:

  • Processes Detected
  • Services Detected
  • DLLs Detected
  • Files Detected

At the end of the report, a summary count highlights the number of findings per category, providing a concise overview of the security landscape of the system.

Example output:

Category Name / Artifact Path / Details Source Plugin
Process MsMpEng.exe Windows Defender pslist
Service WinDefend Microsoft Defender Antivirus Service svcscan
DLL mpengine.dll AV core scanning module dlllist
File DetectionHistory.db Defender detection logs filescan

# live.py – Volatility 3 Live System Analysis Plugin

`live.py` is a custom plugin for **Volatility 3** designed to extend its capabilities for **real-time forensic data collection and threat hunting** directly on a **live Windows system**, eliminating the need for a full memory dump.

This tool provides an **interactive command-line shell** for dynamic investigation, leveraging system APIs through libraries like `psutil` and `pywin32` to quickly triage and analyze active endpoints.

---

## Key Capabilities

### **Live Analysis Mode**
Performs immediate, low-overhead forensic data collection from an active operating system, bypassing traditional memory dump requirements.

### **Interactive Shell**
Includes an integrated CLI environment offering a suite of commands for efficient, step-by-step investigation via the `LiveShellCommand` interface.

### **Advanced Threat Hunting**
Provides built-in commands for targeted analysis:
- **fileless** – Detects fileless malware and suspicious in-memory activity, focusing on processes such as `powershell.exe`.
- **detect_sandbox** – Identifies virtualized or sandboxed environments by inspecting artifacts, process behavior, and MAC address prefixes.

### **Comprehensive Forensic Data Collection**
Collects essential artifacts and system information for deep analysis:
- **Process and Module Data:** `pslist`, `psscan`, `dlllist`, `handles`, `sids`, `cmdline`
- **Network Activity:** `netscan` for active connections and sockets
- **Persistence & Services:** Analysis of `services`, `drivers`, `registry`, and autorun entries
- **Artifact Analysis:** Extraction of `shimcache`, `prefetch`, `userassist`, and `jumplists`
- **Timeline Generation:** Unified event correlation using `timeliner`

---
# sandbox_detect.py – Virtualization and Sandbox Environment Detection (Volatility 3 Plugin)

`sandbox_detect.py` is a specialized **Volatility 3 plugin** designed for **post-mortem forensic analysis** of **Windows memory dumps**.  
Its primary goal is to detect and score artifacts indicating that the analyzed system was operating within a **Virtual Machine (VM)**, **Sandbox**, or **Malware Analysis Environment**.

This plugin is particularly valuable for investigators who need to determine whether a captured memory sample originated from a **controlled analysis setup** or a **real-world victim system**.

---

## Key Capabilities

### **Multi-Layered Artifact Scanning**
Performs deep inspection across multiple memory and system layers to ensure comprehensive detection:

- **Process Analysis:** Identifies running processes related to virtualization or analysis environments, such as  
  `vmtoolsd.exe`, `vboxservice.exe`, `prl_cc.exe`, `wireshark.exe`, and `ollydbg.exe`.  
- **Driver and Module Checks:** Detects kernel modules and drivers named after virtualization platforms, including  
  `vmmouse.sys`, `vboxguest.sys`, and `vmhgfs.sys`.  
- **Registry and System Keys:** Examines critical registry entries and system identifiers for virtualization traces,  
  such as hardware IDs, BIOS strings, and known VM installation paths.

---

### **Heuristic Scoring System**
Implements a scoring engine that assigns severity levels to each identified artifact.  
Instead of a binary result, the plugin produces a **confidence-based verdict**, such as:

- **HIGH CONFIDENCE – Virtual Machine Detected**  
- **MODERATE CONFIDENCE – Sandbox Environment**  
- **LOW CONFIDENCE – Physical Host**

This scoring model provides analysts with clearer, evidence-weighted conclusions.

---
# sandbox_detect.py – Virtualization and Sandbox Environment Detection (Volatility 3 Plugin)

`sandbox_detect.py` is a specialized **Volatility 3 plugin** designed for **post-mortem forensic analysis** of **Windows memory dumps**.  
Its primary goal is to detect and score artifacts indicating that the analyzed system was operating within a **Virtual Machine (VM)**, **Sandbox**, or **Malware Analysis Environment**.

This plugin is particularly valuable for investigators who need to determine whether a captured memory sample originated from a **controlled analysis setup** or a **real-world victim system**.

---

## Key Capabilities

### **Multi-Layered Artifact Scanning**
Performs deep inspection across multiple memory and system layers to ensure comprehensive detection:

- **Process Analysis:** Identifies running processes related to virtualization or analysis environments, such as  
  `vmtoolsd.exe`, `vboxservice.exe`, `prl_cc.exe`, `wireshark.exe`, and `ollydbg.exe`.  
- **Driver and Module Checks:** Detects kernel modules and drivers named after virtualization platforms, including  
  `vmmouse.sys`, `vboxguest.sys`, and `vmhgfs.sys`.  
- **Registry and System Keys:** Examines critical registry entries and system identifiers for virtualization traces,  
  such as hardware IDs, BIOS strings, and known VM installation paths.

---

### **Heuristic Scoring System**
Implements a scoring engine that assigns severity levels to each identified artifact.  
Instead of a binary result, the plugin produces a **confidence-based verdict**, such as:

- **HIGH CONFIDENCE – Virtual Machine Detected**  
- **MODERATE CONFIDENCE – Sandbox Environment**  
- **LOW CONFIDENCE – Physical Host**

This scoring model provides analysts with clearer, evidence-weighted conclusions.

---
# proccon.py – Process Connectivity & Visualization (Volatility 3 Plugin)

`proccon.py` is a **Volatility 3 plugin** designed to provide **process visualization and relationship mapping** from a **Windows memory dump**.  
While it does not perform direct forensic analysis, it serves as a **critical utility** for post-processing and visualizing process hierarchy data.

The plugin extracts **Parent-Child process relationships** and outputs them as a **Graphviz DOT file**, enabling investigators to generate graphical representations of the system’s process tree at the time of capture.

---

## Key Capabilities

### **Process Tree Extraction**
Efficiently iterates through the complete process list obtained via Volatility’s `windows.pslist` plugin to map:
- **PID** (Process ID) → **PPID** (Parent Process ID)

This provides a foundational dataset for visual process relationship mapping.

---

### **Graphviz DOT Output**
Automatically generates a **structured `.dot` file** compatible with Graphviz visualization tools such as:
- `dot`
- `neato`
- Online renderers and graphing tools

This output can be rendered into **network-style process trees**, allowing investigators to:
- Visualize process spawning chains  
- Detect irregular or unexpected parent-child relationships  
- Identify suspicious execution flows in malware investigations

---

### **Visualization Focus**
The plugin emphasizes **connectivity and hierarchy**, providing a clear visual representation of process structures that supports:
- **Anomaly Detection:** Spot abnormal or hidden parent-child relationships  
- **Malware Analysis:** Map execution chains to trace malicious process origins  
- **System Understanding:** Reveal the operational process tree at the time of memory capture  

---
# avcheck.py – Antivirus and Endpoint Detection and Response (EDR) Artifact Scanner (Volatility 3 Plugin)

`avcheck.py` is a specialized **Volatility 3 plugin** designed to detect and enumerate artifacts related to **Antivirus (AV)** and **Endpoint Detection and Response (EDR)** solutions within a **Windows memory dump**.  
It enables investigators and threat hunters to identify which security products were active or installed on a system at the time of capture—critical for understanding a compromised system’s defensive posture.

---

## Key Capabilities

### **Security Software Identification**
Performs broad detection of security tools across **over 80 known AV and EDR products**, including:
- Windows Defender (`MsMpEng.exe`)
- Kaspersky (`avp.exe`)
- Symantec
- AVG
- CrowdStrike (`CsAgent.exe`)
- SentinelOne
- FireEye
- And many others

This identification provides immediate situational awareness of protective technologies present on the analyzed host.

---

### **Multi-Artifact Detection**
Leverages multiple Volatility 3 subsystems to identify security software artifacts across different system components:

- **Processes:**  
  Scans active process lists (`pslist`) for executables associated with AV/EDR agents and monitoring daemons.

- **Services:**  
  Enumerates running services (`svcscan`) to locate entries related to installed security software.

- **DLLs:**  
  Inspects loaded libraries (`dlllist`) to detect known AV/EDR DLLs used for userland hooks or kernel-level integrations.

- **Files:**  
  Uses file scanning (`filescan`) to locate security software directories, databases, log files, and quarantine folders.

Each layer of detection provides corroborating evidence of installed and active endpoint protection components.

---

### **Detection History Triage**
Includes a specialized analysis routine that looks for:
- Quarantine directories and detection logs
- Temporary or deleted AV alert files
- Residual detection history (e.g., Defender history, Kaspersky reports)

These findings offer valuable context on **prior malware detections** or **automated remediation activity** performed by security software.

---

### **Detailed Summary Reporting**
Generates a structured **TreeGrid report** summarizing all detected artifacts, categorized by source type:
- **Processes Detected**
- **Services Detected**
- **DLLs Detected**
- **Files Detected**

At the end of the report, a **summary count** highlights the number of findings per category, providing a concise overview of the security landscape of the system.

Example output:

| Category | Name / Artifact | Path / Details | Source Plugin |
|-----------|----------------|----------------|----------------|
| Process   | MsMpEng.exe    | Windows Defender | pslist |
| Service   | WinDefend      | Microsoft Defender Antivirus Service | svcscan |
| DLL       | mpengine.dll   | AV core scanning module | dlllist |
| File      | DetectionHistory.db | Defender detection logs | filescan |

---
Copy link
Member

@ikelos ikelos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much for your submission. Currently this plugin isn't suitable for inclusion to the framework primarily because the output format is abused to produce data that will be easy for humans to use, but which will badly break consumption of the data by another program (at a minimum, specific parsing will be required).

There's also a large number of data items that are included directly in the code, which would be much better if they were loaded from a JSON file, so that the data can be changed without the plugin needing to be updated.

_version = (1, 0, 0)

# Comprehensive AV process names (80+ processes)
AV_PROCESSES = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a lot of fields that I'd class as data, and think it would be better to read these from a JSON file, so that the plugin can be updated without having to change the code. Please could you include these in a JSON file, and load it from the plugin (similar to, for the example, the getsids or getservicesids plugins)...

"""Detect running antivirus processes."""
av_procs = []

for proc in pslist.PsList.list_processes(self.context, kernel_module_name):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We generally prefer methods to take a context parameter as the first parameter, and use that. It helps make methods more consistent and is particularly useful if the method if found to be useful and other plugins want to use it (and so it would be turned into a classmethod). It's not a requirement, but it would make future maintenance easier.

I think that, and the AV_PROCESSES attribute, are the only places you make use of self. It should be fairly easy to transplant AC_PROCESSES whern the time comes, but at the moment there's no need because this isn't a classmethod (yet).

process_params = peb.ProcessParameters
if process_params:
image_path = process_params.ImagePathName.get_string()
proc_path = image_path if image_path else "N/A"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use the string N/A or any other string value. Other systems (besides the CLI) may need to know that the value isn't available, so please use something derived from BaseAbsentValue (such as NotAvailableValue). This means that a Web UI or similar could process the entry knowing that it's distinct from the actual string "N/A".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If necessary please return None and then when yielding as part of the TreeGrid, use field or NotAvailableValue(), just something to differentiate between a string value and something actively not being present.

try:
if peb and process_params:
cmdline = process_params.CommandLine.get_string()
cmdline_str = cmdline if cmdline else "N/A"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This applies to all fields.


return av_procs

def _detect_av_services(self) -> List[Dict]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, please take in context, layer_name and symbol_table parameters, rather than using self (see above for the reasoning).

vendor = self._identify_av_vendor(proc['name'], proc['path'])
detected_vendors.add(vendor)

# EVERY yield must have exactly 4 values
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't include bogus lines for formatting. If another tool is trying to ask the plugin to produce results, and can determine the types and column names there is no way for them to determine that these lines are unnecessary and do not contain valid data. This is entirely about trying to format the data for a human and completely ignores the use of this plugin by another computer program.

yield (0, ("", "", "", ""))

# Detected Products
if detected_vendors:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're trying to categorize the results, please include an additional column explaining the type, rather than including "header" values). This is wrong and will block this plugin from being added to the framework.

yield (0, ("", "", "", ""))

# Detection Files (categorized) - ALWAYS SHOW IF THERE ARE FILES
if av_files:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost everything in the following section is the wrong way of yielding data in volatility. Please provide data and allow the UI (and therefore ultimately the user) the ability to sort and group the results.

if quarantine:
yield (0, ("Quarantine Files:", "", "", ""))
for f in quarantine:
threat_display = f" [Threats: {f['threats']}]" if f['threats'] != 'N/A' else ""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks to be grouping individual data items as a single line. This is not the point of volatility and completely breaks the use of the plugin by anything other than a human reading the CLI output. Formatting the data before output is also unnecessary and will become problematic when the return from the data may be None or a BaseAbsentValue derivative.


class AVCheck(interfaces.plugins.PluginInterface):
"""Detects installed antivirus products and their detection history from memory."""
_required_framework_version = (2, 0, 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless you're certain this plugin can operate on version 2.0.0 of the framework, please use the current version of the framework (currently (2, 27, 0)).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants