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

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

leh-banner.jpg

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 (#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 time!

@scipio



0
0
0.000
1 comments
avatar

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. 
 

0
0
0.000