Learn Ethical Hacking (#77) - Malware Analysis - Understanding the Threat
Learn Ethical Hacking (#77) - Malware Analysis - Understanding the Threat

What will I learn
- Malware analysis methodology -- the structured approach to understanding what malicious software actually does;
- Static analysis -- examining malware without executing it using strings, PE parsers, and disassemblers;
- Dynamic analysis -- running malware in a controlled sandbox and observing its behavior in real time;
- Malware types -- trojans, ransomware, rootkits, worms, wipers, infostealers, and how each operates;
- Sandbox environments -- building safe analysis labs with FlareVM, REMnux, and ANY.RUN;
- YARA rules -- writing detection signatures based on malware characteristics;
- IOC extraction -- pulling indicators of compromise (hashes, domains, IPs, mutexes) from malware samples;
- Defense: malware detection strategies, sandboxing, and building organizational malware analysis capability.
Requirements
- A working modern computer running macOS, Windows or Ubuntu;
- An isolated VM for malware analysis (NO network access to production systems);
- Understanding of reverse engineering from Episode 44;
- Ghidra and a PE analysis tool (PEStudio or CFF Explorer);
- The ambition to learn ethical hacking and security research.
Difficulty
- Advanced
Curriculum (of the Learn Ethical Hacking Series):
- Learn Ethical Hacking (#1) - Why Hackers Win
- Learn Ethical Hacking (#2) - Your Hacking Lab
- Learn Ethical Hacking (#3) - How the Internet Actually Works - For Attackers
- Learn Ethical Hacking (#4) - Reconnaissance - The Art of Not Being Noticed
- Learn Ethical Hacking (#5) - Active Scanning - Mapping the Attack Surface
- Learn Ethical Hacking (#6) - The AI Slop Epidemic - Why AI-Generated Code Is a Security Disaster
- Learn Ethical Hacking (#7) - Passwords - Why Humans Are the Weakest Cipher
- Learn Ethical Hacking (#8) - Social Engineering - Hacking the Human
- Learn Ethical Hacking (#9) - Cryptography for Hackers - What Protects Data (and What Doesn't)
- Learn Ethical Hacking (#10) - The Vulnerability Lifecycle - From Discovery to Patch to Exploit
- Learn Ethical Hacking (#11) - HTTP Deep Dive - Request Smuggling and Header Injection
- Learn Ethical Hacking (#12) - SQL Injection - The Bug That Won't Die
- Learn Ethical Hacking (#13) - SQL Injection Advanced - Extracting Entire Databases
- Learn Ethical Hacking (#14) - Cross-Site Scripting (XSS) - Injecting Code Into Browsers
- Learn Ethical Hacking (#15) - XSS Advanced - Bypassing Filters and CSP
- Learn Ethical Hacking (#16) - Cross-Site Request Forgery - Making Users Attack Themselves
- Learn Ethical Hacking (#17) - Authentication Bypass - Getting In Without a Password
- Learn Ethical Hacking (#18) - Server-Side Request Forgery - Making Servers Betray Themselves
- Learn Ethical Hacking (#19) - Insecure Deserialization - Code Execution via Data
- Learn Ethical Hacking (#20) - File Upload Vulnerabilities - When Users Upload Weapons
- Learn Ethical Hacking (#21) - API Security - The New Attack Surface
- Learn Ethical Hacking (#22) - Business Logic Flaws - When the Code Works But the Logic Doesn't
- Learn Ethical Hacking (#23) - Client-Side Attacks - Beyond XSS
- Learn Ethical Hacking (#24) - Content Management Systems - Hacking WordPress and Friends
- Learn Ethical Hacking (#25) - Web Application Firewalls - Bypassing the Guards
- Learn Ethical Hacking (#26) - The Full Web Pentest - Methodology and Reporting
- Learn Ethical Hacking (#27) - Bug Bounty Hunting - Getting Paid to Hack the Web
- Learn Ethical Hacking (#28) - The AI Web Attack Surface - AI Features as Vulnerabilities
- Learn Ethical Hacking (#29) - Network Sniffing - Seeing Everything on the Wire
- Learn Ethical Hacking (#30) - Wireless Network Attacks - Breaking Wi-Fi
- Learn Ethical Hacking (#31) - Privilege Escalation - Linux
- Learn Ethical Hacking (#32) - Privilege Escalation - Windows
- Learn Ethical Hacking (#33) - Active Directory Attacks - The Crown Jewels
- Learn Ethical Hacking (#34) - Pivoting and Lateral Movement - Spreading Through Networks
- Learn Ethical Hacking (#35) - Cloud Security - AWS Attack and Defense
- Learn Ethical Hacking (#36) - Cloud Security - Azure and GCP
- Learn Ethical Hacking (#37) - Container Security - Docker and Kubernetes Attacks
- Learn Ethical Hacking (#38) - Infrastructure as Code - Securing the Automation
- Learn Ethical Hacking (#39) - Email Security - Phishing Infrastructure and Defense
- Learn Ethical Hacking (#40) - DNS Attacks - Exploiting the Internet's Foundation
- Learn Ethical Hacking (#41) - Exploitation Frameworks - Metasploit and Cobalt Strike
- Learn Ethical Hacking (#42) - Custom Exploit Development - Writing Your Own
- Learn Ethical Hacking (#43) - Exploit Development Advanced - Modern Mitigations and Bypasses
- Learn Ethical Hacking (#44) - Reverse Engineering - Understanding Binaries
- Learn Ethical Hacking (#45) - Supply Chain Attacks - Poisoning the Source
- Learn Ethical Hacking (#46) - The Human Factor - Why Security Training Fails
- Learn Ethical Hacking (#47) - Physical Security and OSINT - The Forgotten Attack Vectors
- Learn Ethical Hacking (#48) - Insider Threats - When the Call Is Coming from Inside the House
- Learn Ethical Hacking (#49) - Deepfakes and AI Deception - The New Social Engineering
- Learn Ethical Hacking (#50) - Red Team Operations - Simulating Real Attacks
- Learn Ethical Hacking (#51) - Incident Response - When Things Go Wrong
- Learn Ethical Hacking (#52) - Threat Intelligence - Knowing Your Enemy
- Learn Ethical Hacking (#53) - Security Architecture - Designing Systems That Resist Attack
- Learn Ethical Hacking (#54) - Compliance and Governance - The Business of Security
- Learn Ethical Hacking (#55) - Privacy and Data Protection - GDPR, CCPA, and Beyond
- Learn Ethical Hacking (#56) - Cryptocurrency Security - Attacking and Defending Digital Assets
- Learn Ethical Hacking (#57) - IoT and Embedded Security - Hacking the Physical World
- Learn Ethical Hacking (#58) - The AI Security Landscape - Attacking and Defending AI Systems
- Learn Ethical Hacking (#59) - Python for Pentesters - Automating Everything
- Learn Ethical Hacking (#60) - Zig for Security Tools - When Speed and Memory Matter
- Learn Ethical Hacking (#61) - Writing Custom Scanners - Beyond Off-the-Shelf
- Learn Ethical Hacking (#62) - C2 Frameworks - Building Command and Control
- Learn Ethical Hacking (#63) - Payload Generation and Evasion - Defeating Antivirus
- Learn Ethical Hacking (#64) - Fuzzing - Finding Bugs at Machine Speed
- Learn Ethical Hacking (#65) - OSINT Automation - Large-Scale Intelligence Gathering
- Learn Ethical Hacking (#66) - Reporting and Documentation - The Professional Difference
- Learn Ethical Hacking (#67) - Continuous Security - DevSecOps and Pipeline Security
- Learn Ethical Hacking (#68) - Wireless and Bluetooth Exploitation Deep Dive
- Learn Ethical Hacking (#69) - Mobile Application Security - Android and iOS
- Learn Ethical Hacking (#70) - Building a Pentesting Practice - Going Professional
- Learn Ethical Hacking (#71) - Hardening Linux - From Default to Fortress
- Learn Ethical Hacking (#72) - Hardening Windows and Active Directory
- Learn Ethical Hacking (#73) - Network Security Architecture - Defending the Wire
- Learn Ethical Hacking (#74) - Security Monitoring and SIEM - Seeing Everything
- Learn Ethical Hacking (#75) - Threat Hunting - Proactive Detection
- Learn Ethical Hacking (#76) - Digital Forensics Deep Dive - Evidence That Holds Up
- Learn Ethical Hacking (#77) - Malware Analysis - Understanding the Threat (this post)
Learn Ethical Hacking (#77) - Malware Analysis - Understanding the Threat
Solutions to Episode 76 Exercises
Exercise 1: Forensic disk imaging (abbreviated).
Tool: dc3dd on Ubuntu
Command: dc3dd if=/dev/sdb of=/evidence/lab-vm.raw hash=sha256 log=acq.log
Duration: 14 minutes for 40GB disk
SHA-256: 7f3a2b1c9d8e... (verified match between source and image)
Autopsy analysis:
File system: NTFS, 2 partitions (System Reserved + C:)
Deleted files recovered: 7 (including a .docx and 2 .tmp files)
Browser history: 142 URLs, including download of test-malware.exe
Chain of custody documented per template from episode 76.
The 14-minute acquisition time for a 40GB disk is about right for USB 3.0 throughput to an external evidence drive (roughly 45 MB/s sustained, which is typical when dc3dd is simultaneously reading, writing, AND computing SHA-256 hashes on every block). If you are seeing significantly slower times, check whether your evidence drive is connected via USB 2.0 (which would cut throughput to ~25 MB/s) or whether you have a busy I/O scheduler interfering with the sequential read. The important detail is the hash verification -- dc3dd calculated the SHA-256 during acquisition and wrote it to the log, and you then recalculated it against the completed image file. Both hashes matching proves the image is a bit-perfect copy of the source drive, which is the mathematical foundation of forensic integrity we discussed in episode 76.
The 7 recovered deleted files are a good illustration of the gap between what "delete" means to the user and what actually happens on an NTFS disk. Those files were removed from the directory index (the $MFT entry was marked as free) but the actual data blocks remained on disk because nothing had overwritten them yet. The .docx file is particularly interesting for forensic analysis because Word documents are ZIP archives internally -- even a recovered fragment can contain embedded metadata (author name, save timestamps, template paths) that reveals information about the document's origin. And the browser history showing test-malware.exe being downloaded ties the disk evidence directly to user activity -- the kind of correlation that builds the forensic narrative we practiced in episode 76.
Exercise 2: Volatility memory analysis (abbreviated).
windows.pslist: 87 processes running
windows.psscan: 89 processes found (2 hidden/terminated)
Hidden: svchost.exe (PID 6832) -- not in pslist, terminated process
Hidden: beacon.exe (PID 7104) -- NOT in pslist -> suspicious!
windows.netscan: beacon.exe (PID 7104) had TCP connection to
10.10.14.5:443 (established) -- C2 connection
windows.cmdline: PID 7104 command line:
C:\Users\user\AppData\Local\Temp\beacon.exe
Verdict: hidden process with C2 connection = active compromise.
The pslist vs psscan discrepancy is exactly the rootkit detection technique we covered in episode 76. Two extra processes in psscan that pslist did not show: one terminated svchost.exe (PID 6832, which is normal -- terminated processes linger in memory until their pages are reclaimed) and one VERY suspicious beacon.exe (PID 7104) that is NOT terminated but IS hidden from the process list. A running process that does not appear in pslist means something has manipulated the kernel's active process linked list -- the DKOM (Direct Kernel Object Manipulation) technique that rootkits use to hide from Task Manager, Process Explorer, and any other tool that walks the official process list. Only a raw memory scanner like psscan, which looks for _EPROCESS structure headers regardless of list linkage, can find it.
The netscan result connecting beacon.exe to 10.10.14.5:443 confirms what we already suspected from the process name: this is a C2 implant (the 10.10.14.x range is the default HackTheBox VPN subnet, so this was clearly a lab exercise, but in a real investigation the destination IP would be a public C2 server). The command line path (\AppData\Local\Temp\) is a classic malware drop location because the user has write access to Temp without needing admin privileges. And the name "beacon.exe" is a dead giveaway that this is a Cobalt Strike Beacon or similar implant -- real attackers would rename it to something innocuous like svchost.exe or explorer.exe, but in a lab environment the obvious name makes learning easier.
Exercise 3: Timeline reconstruction (abbreviated).
14:22:05 - Chrome downloaded test-payload.exe from http://lab-server/
14:22:08 - test-payload.exe created in Downloads folder (NTFS $MFT)
14:22:15 - test-payload.exe executed (Prefetch file created)
14:22:16 - PowerShell spawned by test-payload.exe (Sysmon Event 1)
14:22:18 - Scheduled task "Updater" created (Event 4698)
14:22:20 - TCP connection to 10.10.14.5:443 (Sysmon Event 3)
Timeline matches the actions performed. All events correlated
across 4 evidence sources (NTFS, Prefetch, Sysmon, Event Log).
The six-event timeline spanning 15 seconds from download to C2 connection is a textbook attack chain compressed into a single forensic narrative. Each event comes from a different evidence source: the download from browser history (or NTFS $MFT creation timestamp), the file creation from the NTFS Master File Table, the execution from Prefetch (Windows creates a .pf file the first time a program runs), the PowerShell spawn from Sysmon Event 1 (process creation), the scheduled task from Windows Event 4698 (scheduled task created), and the network connection from Sysmon Event 3 (network connection detected). Four independent evidence sources, six correlated events, one coherent story. That is what Plaso and Autopsy's timeline view were designed to produce, and it is the gold standard of forensic reconstruction.
The scheduled task "Updater" at 14:22:18 is the persistence mechanism -- the malware is not just establishing a C2 connection for this session, it is ensuring it survives reboot. This connects directly to the persistence hunting techniques from episode 75: the query schtasks /query /fo CSV /v | findstr /i /v "Microsoft" would have found this task, and the Sysmon + SIEM correlation rule targeting Event 4698 would have alerted on it in real time if your monitoring stack was configured correctly (as per episode 74). Every layer of the defense arc -- monitoring (74), hunting (75), and forensics (76) -- produces evidence of the same attack, just from different perspectives and at different timescales.
Episode 76 covered digital forensics -- the disciplined process of collecting, preserving, and analyzing digital evidence so that findings hold up under legal scrutiny. Disk imaging with write blockers and dc3dd, memory forensics with Volatility, timeline reconstruction with Plaso, and the chain of custody documentation that makes the difference between evidence that convicts and evidence that gets thrown out. That episode answered the question "what happened on this system?" by methodically reconstructing the attacker's actions from the artifacts they left behind.
But forensics reconstructs the STORY. Today we answer the more specific question: what does this piece of software actually do?
Understanding the Enemy's Weapons
When your threat hunter (episode 75) flags a suspicious process, when your forensic analyst (episode 76) recovers a deleted executable from unallocated disk space, when your SOC gets an alert about an unknown binary phoning home to an external IP -- the next question is always the same. What does it do? Does it steal credentials? Does it encrypt files for ransom? Does it beacon to a C2 server? Does it exfiltrate data? How does it persist across reboots? What other machines might it have spread to? These answers drive the entire incident response. Without them, you are responding blind.
Malware analysis is the discipline that answers these questions. It is the process of systematically examining malicious software to understand its capabilities, its communication channels, its persistence mechanisms, and its overall purpose. A forensic analyst finds the malware. A malware analyst tells you what it does. And THAT determines whether you need to rebuild 3 machines or 300.
There are two fundamental approaches: static analysis (examine the code without running it) and dynamic analysis (run it in a controlled environment and observe its behavior). Most professional analysts use both -- static analysis first to understand what the malware COULD do, dynamic analysis second to confirm what it ACTUALLY does when executed. The combination is more powerful than either approach alone because each compensates for the other's blind spots (obfuscated code defeats static analysis, sandbox-aware malware defeats dynamic analysis, but defeating both simultaneously is significantly harder).
The Analysis Lab
Here we go. Before you touch a single malware sample, you need an isolated analysis environment. This is NOT optional. Malware is designed to spread, to persist, to phone home, and to cause damage. Running it on your daily workstation -- or worse, on a machine connected to your production network -- is asking for trouble.
CRITICAL: never analyze malware on a production system or a
system connected to your real network. Malware WILL try to spread.
Isolated analysis environment:
Option 1: FlareVM (Windows analysis)
- Windows 10/11 VM with pre-installed analysis tools
- Ghidra, x64dbg, PEStudio, Process Monitor, Wireshark
- Network: host-only or no network adapter
- Snapshot BEFORE analysis, revert AFTER every sample
- Download: https://github.com/mandiant/flare-vm
Option 2: REMnux (Linux analysis)
- Ubuntu-based distro purpose-built for malware analysis
- Pre-installed: Volatility, YARA, radare2, oletools, CyberChef
- Use for: document analysis, network simulation, Linux malware
- Download: https://remnux.org/
Option 3: ANY.RUN (cloud sandbox)
- Upload and observe malware in the browser -- no local risk
- Shows: process tree, network activity, file operations, registry
- Free tier available (public submissions -- your sample is shared)
- Paid tier for private submissions
- Useful for quick triage before deep manual analysis
Network simulation (for dynamic analysis):
INetSim or FakeDNS on a separate VM on the same host-only network.
Simulates DNS, HTTP, HTTPS, SMTP so the malware "thinks" it has
internet access. Captures all C2 communication attempts without
any real network connectivity to the outside world.
The FlareVM setup is what most Windows malware analysts use daily. It is a script that transforms a standard Windows 10 VM into a fully equipped analysis workstation -- Ghidra for reverse engineering (which we covered extensively in episode 44), x64dbg for dynamic debugging, PEStudio for quick PE file triage, Process Monitor and Process Explorer from Sysinternals for runtime behavior monitoring, plus dozens of other tools. The key discipline is snapshots: take a clean snapshot before loading any sample, and revert to that snapshot after every analysis session. Malware modifies the system state (that is literally what it does), and you need a clean baseline for every new sample.
REMnux is the Linux counterpart, and it fills a different niche. Windows malware is the majority of what you will analyze (because Windows is the majority of what gets attacked), but REMnux is invaluable for analyzing malicious documents (Office files with VBA macros, PDFs with embedded JavaScript), running network simulations alongside a Windows analysis VM, and obviously analyzing Linux-specific malware (which is increasingly common as cloud infrastructure and IoT devices become primary targets). The oletools suite on REMnux is particularly useful -- olevba extracts VBA macro code from Office documents, oleid identifies suspicious indicators, and rtfobj parses RTF files that embed OLE objects (a favorite delivery mechanism for exploitation).
The INetSim network simulation deserves special attention because it solves a critical problem in dynamic analysis: many malware samples check for network connectivity before executing their payload. If the malware sends a DNS query and gets no response, it might conclude it is running in a sandbox and refuse to do anything interesting (a technique called sandbox evasion that we touched on in episode 63). INetSim responds to DNS queries, serves fake HTTP pages, accepts SMTP connections, and generally makes the malware believe it has full internet access -- while actually capturing every request for your analysis. The malware tries to contact its C2 server, INetSim intercepts the DNS resolution and the subsequent HTTP/HTTPS connection, and you get a complete record of where the malware was trying to communicate without any packets ever leaving your lab network ;-)
Static Analysis
Static analysis means examining the malware without executing it. You look at the file's properties, extract strings, analyze the imports and exports, check the section entropy, and potentially disassemble or decompile the code. The advantage is safety -- the malware never runs, so it cannot do anything to your system. The disadvantage is that heavily obfuscated or packed malware reveals very little under static analysis because the real code is encrytped and only unpacked at runtime.
# Step 1: File identification
file suspicious.exe
# PE32+ executable (GUI) x86-64, for MS Windows
sha256sum suspicious.exe
# a4f3e2d1c0b9... -- check against VirusTotal
# Step 2: Strings extraction
strings suspicious.exe | head -100
# Look for: URLs, IP addresses, registry keys, file paths,
# error messages, API function names, encoded data
strings suspicious.exe | grep -iE "http|https|ftp|\.com|\.net|\.ru"
# Extract potential C2 URLs
strings suspicious.exe | grep -iE "password|crypt|key|token|mutex"
# Extract credential-related and synchronization strings
# Step 3: Entropy check per section
python3 -c "
import pefile
pe = pefile.PE('suspicious.exe')
print(f'Compiled: {pe.FILE_HEADER.TimeDateStamp}')
print(f'Sections: {len(pe.sections)}')
for section in pe.sections:
name = section.Name.decode().rstrip('\x00')
entropy = section.get_entropy()
print(f' {name:10s} size={section.SizeOfRawData:8d} entropy={entropy:.2f}')
# entropy > 7.0 = likely packed or encrypted
# entropy < 1.0 = mostly empty (padding)
# entropy 4.5-6.5 = normal code/data
print(f'\nImports:')
for entry in pe.DIRECTORY_ENTRY_IMPORT:
print(f' {entry.dll.decode()}')
for imp in entry.imports:
if imp.name:
print(f' {imp.name.decode()}')
"
The entropy check on PE sections is one of the fastest and most reliable triage indicators in static analysis. Entropy measures the randomness of data in a section on a scale from 0 (completely uniform, like a section full of zeros) to 8 (completely random, like encrypted or compressed data). Normal compiled code has an entropy between 4.5 and 6.5 -- it has structure and patterns (repeating instruction opcodes, aligned data structures) but is not uniform. A section with entropy above 7.0 is almost certainly packed, compressed, or encrypted -- which is a red flag because legitimate software rarely packs its own code sections. Malware authors use packers like UPX, Themida, and VMProtect to compress and encrypt their code, making static analysis much harder because the strings, imports, and actual logic are hidden inside the encrypted blob and only revealed at runtime when the unpacking stub decompresses them into memory.
The imports analysis tells you what Windows API functions the binary plans to call, and certain imports are immediate red flags:
Suspicious Windows API imports and what they indicate:
VirtualAlloc / VirtualProtect
Memory manipulation. Commonly used to allocate executable
memory for shellcode injection. Legitimate programs rarely
need to change memory page permissions at runtime.
CreateRemoteThread
Creates a thread in ANOTHER process's address space.
This is process injection -- running your code inside
someone else's process to hide from process listings.
NtUnmapViewOfSection + WriteProcessMemory
Process hollowing: create a legitimate process (e.g. svchost),
unmap its code, replace it with malware code. The process
looks normal in Task Manager but is running attacker code.
We covered this in episode 63.
CryptEncrypt / CryptGenKey / CryptAcquireContext
Cryptographic operations. Could be ransomware encrypting
files, or C2 traffic encryption. Context matters.
InternetOpenUrl / HttpSendRequest / WinHttpOpen
Network communication. The malware is going to phone home.
Combined with the strings extraction for URLs, this tells
you roughly where it wants to connect.
RegSetValueEx / RegCreateKeyEx
Registry modification. Almost certainly persistence --
setting a Run key or a service registration (the same
techniques we hunted for in episode 75).
Having said that, imports can be misleading. Sophisticated malware uses dynamic API resolution -- instead of importing CreateRemoteThread directly (which would show up in the import table), it calls GetProcAddress("kernel32.dll", "CreateRemoteThread") at runtime to get the function pointer. The import table shows only GetProcAddress and LoadLibrary, which are completely innocuous. The actual malicious API calls are invisible to static import analysis. This is why static analysis alone is often insufficient and dynamic analysis (running the sample and watching what it actually does) is needed to see the full picture.
# Step 4: Disassemble key functions with Ghidra
# (using episode 44 reverse engineering techniques)
# Open the binary in Ghidra
# Navigate to the entry point or main()
# Focus on:
# - Decryption routines (XOR loops, AES calls)
# - C2 communication setup (socket creation, HTTP requests)
# - File operations (CreateFile, ReadFile, WriteFile)
# - Process manipulation (OpenProcess, CreateRemoteThread)
# Ghidra's decompiler turns assembly into pseudo-C
# which is dramatically easier to read than raw x86:
#
# void main() {
# char *key = decrypt_config(encrypted_blob, 0x100);
# SOCKET s = connect_c2(key + 0x20, 443);
# while (recv_command(s, &cmd)) {
# execute_command(cmd);
# send_result(s, result);
# }
# }
#
# Even this simplified view tells you: config decryption,
# C2 connection, command loop. That is a RAT.
Dynamic Analysis
Static analysis tells you what the malware COULD do. Dynamic analysis tells you what it ACTUALLY does when executed. You run the sample in your isolated lab VM with monitoring tools capturing every action -- every file created, every registry key modified, every network connection attempted, every process spawned.
Dynamic analysis monitoring tools:
Process Monitor (ProcMon) -- Sysinternals
Captures: file system activity, registry activity, network,
process/thread activity in real time.
Filter by the malware process PID to reduce noise.
Export to CSV for post-analysis correlation.
Process Explorer -- Sysinternals
Shows: full process tree, loaded DLLs, handles, TCP/IP.
Highlight the malware process and watch what it spawns.
The process tree reveals parent-child relationships that
expose injection and process hollowing (episode 63).
Wireshark or TCPdump
Captures all network traffic from the analysis VM.
Combined with INetSim, reveals every C2 communication
attempt, DNS query, and data exfiltration payload.
Regshot
Take a registry snapshot BEFORE and AFTER execution.
The diff shows every registry key created or modified.
Persistence mechanisms become immediately visible.
API Monitor
Hooks Windows API calls in real time with full parameters.
See every argument passed to VirtualAlloc, CreateFile,
RegSetValueEx -- the level of detail that import analysis
cannot provide because the calls are resolved dynamically.
Dynamic analysis workflow:
1. Revert the analysis VM to a clean snapshot
2. Start all monitoring tools:
- ProcMon (filter for Process Name = sample.exe)
- Process Explorer (tree view, TCP/IP tab open)
- Wireshark (capture on host-only adapter)
- INetSim on the REMnux VM (fake internet services)
- Regshot first snapshot
3. Copy the malware to the VM and execute it
4. Wait 5-10 minutes
(some malware has sleep timers to evade short-duration sandboxes)
5. Observe and document:
- What child processes were created? (Process Explorer)
- What files were created, modified, or deleted? (ProcMon)
- What registry keys were set? (ProcMon + Regshot)
- What network connections were attempted? (Wireshark)
- What DNS queries were sent? (INetSim logs)
6. Take Regshot second snapshot and generate diff
7. Stop all captures, kill the malware if still running
8. Analyze the collected data
9. Revert VM to clean snapshot -- mandatory!
The 5-10 minute wait in step 4 is critical and the part that impatient analysts skip to their detriment. Many modern malware samples include sleep timers specifically designed to evade automated sandbox analysis. The logic is simple: automated sandboxes typically run samples for 60-120 seconds before declaring them clean. If the malware sleeps for 3 minutes before doing anything malicious, the sandbox times out and reports "no malicious behavior observed" -- and the file passes through to the victim's inbox or desktop. By waiting longer in manual analysis, you outlast these evasion timers. Some particularly sophisticated samples even check the system uptime (a freshly booted VM with 2 minutes of uptime looks like a sandbox, while a system that has been running for 3 days looks like a real workstation) or the mouse movement history (no mouse movement = no human user = probably a sandbox).
The ProcMon filter deserves emphasis. Without filtering, ProcMon captures every file system and registry operation on the entire machine -- which on Windows can be thousands of events per SECOND from normal OS activity. Your malware's 50 events are buried in 50,000 events from Explorer, Windows Update, WMI providers, and antivirus scans. Filtering for the malware's process name (and its child processes) reduces the output to only what the malware is responsible for. Export the filtered results to CSV, and you have a complete audit trail of every file the malware touched, every registry key it read or wrote, and every network connection it initiated.
Malware Types in Detail
Different malware categories have different behaviors, different indicators, and different levels of damage. Understanding the classification helps you prioritize your analysis and predict what to look for:
Trojan / Remote Access Trojan (RAT):
Purpose: establish persistent remote access for the attacker.
Behavior: C2 beaconing, keylogging, screenshot capture,
file upload/download, remote shell, process injection.
Indicators: outbound connections to unusual IPs on standard
ports (443, 80, 8080), process injection artifacts,
clipboard monitoring.
Examples: Emotet, Agent Tesla, NjRAT, AsyncRAT
Connects to: episode 62 (C2 frameworks)
Ransomware:
Purpose: encrypt files and extort payment.
Behavior: enumerate files, encrypt with AES/RSA hybrid,
drop ransom note, delete shadow copies (vssadmin),
may exfiltrate data first ("double extortion").
Indicators: mass file rename with new extensions (.locked,
.encrypted), crypto API calls (CryptEncrypt, CryptGenKey),
ransom note files (README.txt, DECRYPT_FILES.html),
vssadmin delete shadows command execution.
Examples: LockBit, BlackCat/ALPHV, Conti, REvil
Rootkit:
Purpose: hide attacker presence from the operating system.
Behavior: hook system calls, modify kernel structures (DKOM),
hide processes, files, registry keys, network connections.
Indicators: discrepancies between user-mode and kernel-mode
views (pslist vs psscan in Volatility from ep76), hooked
syscall table entries, hidden kernel drivers.
Examples: Necurs, ZeroAccess, Azazel (Linux)
Worm:
Purpose: self-replicate across networks without user action.
Behavior: scan for vulnerable services, exploit, copy self,
repeat. No user interaction needed after initial infection.
Indicators: scanning activity (rapid connections to port 445,
139, 22, etc.), copies of the binary on network shares,
lateral movement without credential theft.
Examples: WannaCry (EternalBlue), NotPetya, Conficker
Wiper:
Purpose: destroy data -- not for ransom, purely destructive.
Behavior: overwrite files with zeros or random data, corrupt
the MBR/VBR, destroy partition tables.
Indicators: mass file deletion or zeroing, MBR modification,
direct disk writes bypassing the file system.
Examples: Shamoon, WhisperGate, HermeticWiper, CaddyWiper
Note: wipers are often used in state-sponsored attacks
where the goal is destruction, not profit.
Infostealer:
Purpose: harvest credentials, browser data, crypto wallets.
Behavior: read browser credential stores (Chrome Login Data,
Firefox logins.json), clipboard monitoring for crypto
addresses, keylogging, cookie theft.
Indicators: reads from browser profile directories, accesses
credential manager APIs, exfiltrates via Telegram bot API
or Discord webhooks or SMTP.
Examples: RedLine, Raccoon, Vidar, Lumma
The distinction between ransomware and wipers is particularly important because they look almost identical during the encryption/destruction phase but have fundamentally different purposes and therefore different response strategies. Ransomware wants you to pay -- so the encryption must be reversible (the attacker has the key), the ransom note must be readable (they need you to find it), and the system must remain bootable enough for the victim to read the instructions. A wiper does not care about any of that. It overwrites data, corrupts the MBR, and tries to make the system as unrecoverable as possible. If you see shadow copy deletion (vssadmin delete shadows /all /quiet) combined with a ransom note drop, that is ransomware. If you see shadow copy deletion combined with direct MBR writes and no ransom note, that is a wiper -- and your response changes from "negotiate and consider paying" to "restore from offline backups because nothing on that disk is coming back."
YARA Rules
YARA is the pattern matching language for malware detection. Think of it as grep on steroids, specifically designed for binary files. You write rules that describe textual and binary patterns characteristic of a malware family, and then scan files (or entire directories, or memory dumps) for matches.
# YARA rule structure and examples
rule Emotet_Document_Loader {
meta:
description = "Detects Emotet initial access via Office macro"
author = "scipio"
date = "2026-06-10"
strings:
$macro1 = "AutoOpen" ascii
$macro2 = "Document_Open" ascii
$cmd1 = "powershell" nocase ascii
$cmd2 = "-encodedcommand" nocase ascii
$url = /https?:\/\/[a-zA-Z0-9\.\-]+\.(com|net|ru|xyz)/ ascii
condition:
uint16(0) == 0xCFD0 and // OLE document magic bytes
($macro1 or $macro2) and
($cmd1 and $cmd2) and
$url
}
rule Generic_Ransomware_Indicators {
meta:
description = "Generic ransomware behavioral indicators"
author = "scipio"
strings:
$ransom1 = "Your files have been encrypted" ascii wide
$ransom2 = "bitcoin" nocase ascii wide
$ransom3 = ".onion" ascii
$api1 = "CryptEncrypt" ascii
$api2 = "CryptGenKey" ascii
$shadow = "vssadmin" ascii
condition:
uint16(0) == 0x5A4D and // PE file (MZ header)
2 of ($ransom*) and
1 of ($api*) and
$shadow
}
rule Packed_PE_High_Entropy {
meta:
description = "PE file with suspiciously high section entropy"
author = "scipio"
condition:
uint16(0) == 0x5A4D and
for any section in pe.sections : (
math.entropy(section.offset, section.size) > 7.2
)
}
The magic bytes check (uint16(0) == 0xCFD0 for OLE documents, uint16(0) == 0x5A4D for PE files) is the first condition in most YARA rules and it serves as an efficient filter. Before YARA even checks the string patterns, it reads the first two bytes of the file to determine its type. If the file is not the expected type, the entire rule is skipped without reading the rest of the file. This makes scanning large file collections dramatically faster because most files are immediately eliminated before any expensive string matching occurs.
The Emotet rule above checks for the combination of OLE document format (Office file), macro auto-execution strings (AutoOpen or Document_Open -- the function names that VBA macros use to run automatically when the document is opened), PowerShell invocation with encoded commands (the classic LOLBin abuse chain from episode 32), and a URL pattern that matches common C2 domains. Each individual indicator is benign on its own -- legitimate documents have macros, legitimate scripts call PowerShell, legitimate software embeds URLs. But the COMBINATION of all four in a single OLE document is a strong indicator of a malicious dropper.
# Scanning with YARA
# Scan a single file
yara rules.yar suspicious.exe
# Scan an entire directory recursively
yara -r rules.yar /path/to/scan/
# Scan a memory dump (from Volatility acquisition)
yara rules.yar memory.raw
# Scan with multiple rule files
yara -r rules/*.yar /path/to/scan/
# Scan running processes on Linux
yara -p 32 rules.yar /proc/
# Output matching strings (useful for debugging rules)
yara -s rules.yar suspicious.exe
YARA is the bridge between malware analysis and detection engineering. When you analyze a new malware sample and understand its characteristics (what strings it contains, what patterns appear in its binary structure, what behavioral markers are unique to its family), you encode that knowledge into a YARA rule. That rule can then be deployed to your endpoint security tools, your email gateway, your sandbox infrastructure, and your SIEM to detect future samples from the same family automatically. The analysis informs the detection, the detection catches new samples, the new samples feed back into analysis -- this is the virtuous cycle that keeps defenders in the game.
IOC Extraction
Every malware sample contains indicators of compromise (IOCs) -- observable artifacts that can be used to detect the malware or its infrastructure on other systems. Extracting these IOCs is a core deliverable of malware analysis because they feed directly into your threat intelligence platform (episode 52), your SIEM detection rules (episode 74), and your incident response scoping (episode 51).
#!/usr/bin/env python3
"""ioc_extractor.py -- extract IOCs from a malware sample."""
import re
import hashlib
import pefile
import sys
def extract_iocs(filepath):
with open(filepath, 'rb') as f:
data = f.read()
text = data.decode('utf-8', errors='replace')
iocs = {
'hashes': {},
'urls': [],
'ips': [],
'domains': [],
'registry': [],
'mutexes': [],
}
# File hashes (the universal malware identifier)
iocs['hashes']['md5'] = hashlib.md5(data).hexdigest()
iocs['hashes']['sha256'] = hashlib.sha256(data).hexdigest()
# URLs embedded in the binary
iocs['urls'] = list(set(
re.findall(r'https?://[^\s<>"\']+', text)
))
# IP addresses (filter out loopback and broadcast)
raw_ips = re.findall(
r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b', text
)
iocs['ips'] = list(set(
ip for ip in raw_ips
if not ip.startswith(('0.', '127.', '255.'))
))
# Domain names
iocs['domains'] = list(set(
re.findall(r'\b[a-zA-Z0-9\-]+\.'
r'(com|net|org|ru|xyz|top|pw|cc)\b', text)
))
# Registry keys (persistence indicators)
iocs['registry'] = list(set(
re.findall(r'(?:HKLM|HKCU)\\[^\s"]+', text)
))
# Mutexes (unique instance identifiers)
iocs['mutexes'] = list(set(
re.findall(r'(?:Global\\|Local\\)[^\s"]+', text)
))
return iocs
if __name__ == '__main__':
if len(sys.argv) != 2:
print(f'Usage: {sys.argv[0]} <malware_sample>')
sys.exit(1)
iocs = extract_iocs(sys.argv[1])
for category, values in iocs.items():
if values:
print(f'\n[{category.upper()}]')
if isinstance(values, dict):
for k, v in values.items():
print(f' {k}: {v}')
else:
for v in values:
print(f' {v}')
The SHA-256 hash is the single most important IOC because it uniquely identifies the exact binary. You can share a SHA-256 hash on a mailing list, in a threat intelligence report, or in a VirusTotal query, and anyone else who encounters the same file can immediately identify it. Hashes are also the primary lookup key for malware databases -- VirusTotal alone has billions of file hashes indexed with detection results from 70+ antivirus engines. Before spending hours on manual analysis, always check the hash against VirusTotal first. If 50 engines already flag it as "Trojan.GenericKD.48719432," you can skip the basic classification and focus your analysis on the specific behavioral details that matter for YOUR incident.
The mutex extraction is less commonly discussed but extremely valuable. A mutex (mutual exclusion object) is a Windows synchronization primitive that malware uses to ensure only one copy of itself runs at a time. If the mutex already exists when the malware starts, it knows another instance is running and exits. The mutex name is typically hardcoded (something like Global\MSCTF.Asm.{b} or a random-looking GUID) and is unique to the malware family. Finding the mutex name lets you: (a) create a network-wide detection rule (scan every endpoint for that mutex), (b) create a "vaccination" for the malware by pre-creating the mutex on clean systems (the malware starts, finds the mutex, thinks another instance is running, and exits without doing anything), and (c) link different samples to the same campaign or author based on shared mutex names.
Defense: Building Organizational Capability
Not every organization needs a dedicated malware analysis team. But every organization that handles security incidents needs some level of malware analysis capability. The question is what level:
Tier 1: Automated analysis (any organization)
Tools: ANY.RUN, Joe Sandbox, Hybrid Analysis, VirusTotal
Process: upload suspicious files, get a report back
Skills needed: ability to interpret an automated report
Cost: free tier or $500-2,000/month for private submissions
Covers: 80% of commodity malware (known families, standard
behavior, existing signatures)
Tier 2: Basic manual analysis (mid-size security teams)
Tools: strings, PEStudio, YARA, pefile, CyberChef
Skills: static analysis, IOC extraction, YARA rule writing
Process: triage unknown samples, classify, extract IOCs
Cost: one trained analyst + tooling (mostly free/open source)
Covers: 95% of malware you will encounter
Tier 3: Full reverse engineering (large orgs, gov, MSSPs)
Tools: Ghidra/IDA Pro, x64dbg, API Monitor, full lab
Skills: assembly, RE, unpacking, anti-analysis bypass
Process: reverse engineer novel malware, write detailed reports
Cost: specialized analyst ($120K+/year) + lab infrastructure
Covers: 100% including novel/custom APT malware
Most organizations should aim for Tier 2 and outsource Tier 3
to a specialized firm (Mandiant, CrowdStrike, etc.) when needed.
The jump from "upload to VirusTotal and hope" to "basic manual
triage with IOC extraction" is the most impactful improvement
a security team can make.
The economics here are worth thinking about. A Tier 1 capability costs almost nothing and handles the bulk of incidents -- known malware families, commodity ransomware, script kiddie tools that are already in every AV database. You upload the file to a sandbox, get a report, cross-reference the IOCs with your SIEM, scope the incident, and move on. This works until you encounter something the automated tools have never seen before -- a custom implant built for your organization specifically, a new variant that no signature covers, or a sample that actively evades sandbox analysis. At that point, you need human eyes on the binary, and that is where Tier 2 makes the difference. One analyst who can run strings, check imports, write a YARA rule, and extract IOCs manually can handle samples that completely defeat automated analysis.
The AI Slop Connection
AI is transforming malware on both sides of the equation. On offense, AI-generated malware is polymorphic by default -- every time the AI produces a variant, the code structure is different, the string patterns change, and signature-based detection fails. An attacker can tell an AI "write me a Python infostealer that harvests browser credentials" and get a unique, functional sample that no existing YARA rule covers. The AI does not need to know about evasion techniques -- it produces unique code naturally because it generates from scratch rather than modifying a template. This is fundamentally different from traditional polymorphism (which transforms existing code through encryption or code substitution) and significantly harder to detect with traditional signature-based approaches.
On defense, AI is equally transformative. AI-powered sandboxes can detect evasive malware by analyzing behavioral patterns rather than relying on signatures -- if a binary allocates executable memory, writes shellcode to it, and calls the allocated memory as a function, the behavioral pattern screams "shellcode injection" regardless of what the specific bytes are. AI can classify unknown malware into known families based on behavioral similarity (graph-based analysis of API call sequences, network communication patterns, file system activity patterns) even when the code itself is completely different from any known sample. And AI-assisted YARA rule generation can produce detection signatures from natural language behavioral descriptions -- describe what the malware does, and the AI proposes string patterns and conditions that would match it.
The arms race is real. AI makes malware easier to generate AND makes detection tools smarter. The net effect so far: defenders are keeping pace, but barely. The advantage still goes to whoever uses the tools more skillfully, and understanding the fundamentals of malware analysis -- how to examine a binary, how to observe its behavior, how to extract the indicators that feed into your detection pipeline -- remains essential regardless of how much AI assists the process. Understanding how to write code that does not BECOME the target of these techniques is the natural next step from understanding how to analyze threats.
Exercises
Exercise 1: Set up a malware analysis lab using FlareVM (Windows) or REMnux (Linux) in an isolated VM with NO real network access. Download a known, well-documented malware sample from MalwareBazaar (https://bazaar.abuse.ch/) -- choose something with extensive public analysis (Emotet or Agent Tesla are good candidates). Perform static analysis only: extract strings, identify suspicous imports using pefile, calculate MD5 and SHA-256 hashes, check the hashes against VirusTotal, and examine section entropy for packing indicators. Document your findings in a structured report and save to ~/lab-notes/static-malware-analysis.md.
Exercise 2: Perform dynamic analysis on the same sample in your isolated VM (with INetSim providing fake network services). Use Process Monitor (filtered for the malware PID), Wireshark (capturing on the host-only adapter), and Regshot (before/after registry snapshots). Document: (a) what child processes it creates, (b) what files it writes or modifies, (c) what registry keys it sets (persistence?), (d) what network connections it attempts (C2 addresses?). Compare your dynamic findings against the static analysis -- did the dynamic run reveal capabilities that were hidden from static analysis? Save to ~/lab-notes/dynamic-malware-analysis.md.
Exercise 3: Write 3 YARA rules for malware detection: (a) a rule that detects PE files with at least one section having entropy above 7.2 (likely packed), (b) a rule that detects Office documents containing macro auto-execution strings combined with PowerShell invocation, (c) a rule specific to the malware sample you analyzed in exercises 1-2, targeting unique strings or byte patterns you identified. Test each rule against your sample AND against 5 clean files (a Word document, a PDF, a legitimate .exe, a text file, a JPEG) to verify zero false positives. Save your rules and test results to ~/lab-notes/yara-rules/.
Thanks for your contribution to the STEMsocial community. Feel free to join us on discord to get to know the rest of us!
Please consider delegating to the @stemsocial account (85% of the curation rewards are returned).
Consider setting @stemsocial as a beneficiary of this post's rewards if you would like to support the community and contribute to its mission of promoting science and education on Hive.