Know the Enemy by Its Shape#

Malware (malicious software) is any program built to harm, spy on or take control of a system. Modern malware is mostly a business: access brokers sell footholds, ransomware crews rent their tooling to affiliates, and info-stealers feed credential markets. Knowing the families matters for a practical reason: the label you put on an infection decides how you contain it. A worm means "isolate the network segment now"; an info-stealer means "rotate every credential that machine touched"; a rootkit means "do not trust anything the running OS tells you".

The Core Families#

Family Defining trait Spreads by itself? What to do first
Virus Attaches to a host file or boot sector Only when the host runs Identify and clean infected files
Worm Self-propagates over the network Yes Isolate segments, patch the exploited service
Trojan Looks useful, does something else No Find the install source, check what it dropped
Ransomware Encrypts data, often steals it first Usually via operator or worm component Isolate, protect backups, start IR
Spyware / info-stealer Harvests credentials, cookies, files No Rotate credentials and revoke sessions
Rootkit Hides itself from the OS No Examine from a trusted boot or image, usually rebuild
RAT / backdoor Interactive remote control No Find the C2 channel, look for lateral movement
Fileless / living off the land Runs in memory using built-in tools No Hunt in process and script logs, not files
Botnet agent Enrols the host in a remotely commanded network Sometimes Block C2, find how it arrived

A few distinctions trip people up:

  • Categories overlap. A single sample is often a trojan (how it arrived), a RAT (what it does) and a loader for ransomware (what comes next). Describe behaviour, not just a label.
  • Info-stealers are underrated. They grab saved browser passwords and, critically, session cookies, which let the attacker skip MFA entirely by replaying an already-authenticated session. Changing the password is not enough; sessions must be revoked.
  • Ransomware today usually means double extortion: data is exfiltrated before encryption, so restoring from backup fixes availability but not the data leak.
  • Fileless techniques abuse trusted binaries such as PowerShell, WMI, mshta, rundll32 and certutil. Nothing malicious sits on disk for a file scanner to find, which is why "the scan came back clean" says little on its own.

How It Gets In#

Delivery follows a short list of routes:

  • Phishing: attachments (macro documents, archives, disk images, shortcut files) and links to fake login or download pages. See social engineering.
  • Exposed services: brute-forced or credential-stuffed RDP, SSH and VPN logins, and unpatched internet-facing appliances.
  • Drive-by and malvertising: fake software download sites promoted through search ads, and compromised websites.
  • Supply chain: a poisoned package, a trojanised installer or a compromised update server. See supply-chain security.
  • Removable media: USB baiting and infected shared drives.

Almost every route either tricks a person or exploits a missing patch or weak credential. That tells you where prevention spend goes: patching, MFA on remote access, email filtering, and making the dangerous action harder (for example, blocking macros from internet-sourced documents).

Persistence: Where Malware Hides Between Reboots#

Once running, malware wants to survive a restart. Knowing the common persistence locations lets you check a suspicious machine yourself:

# Windows: run keys, scheduled tasks, services
reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Run
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run
Get-ScheduledTask | Where-Object {$_.State -ne "Disabled"} | Select-Object TaskPath, TaskName
Get-CimInstance Win32_Service | Where-Object {$_.StartMode -eq "Auto"} | Select-Object Name, PathName
# Linux: cron, systemd units, shell startup files, SSH keys
crontab -l; ls -la /etc/cron.* /var/spool/cron 2>/dev/null
systemctl list-unit-files --state=enabled
grep -n "curl\|wget\|base64" ~/.bashrc ~/.profile /etc/profile 2>/dev/null
cat ~/.ssh/authorized_keys

What to look for: entries pointing into user-writable folders (AppData, Temp, /tmp, /dev/shm), random-looking names, scripts with encoded arguments, and SSH keys nobody recognises. On Windows, Sysinternals Autoruns shows all of these locations in one view and can hide entries signed by Microsoft, which cuts the noise dramatically.

Behaviour Beats Signatures#

Signature scanning matches known-bad file hashes and byte patterns. It is fast and precise but blind to anything new or repacked. EDR (endpoint detection and response) watches behaviour instead: which process started which, what it wrote, where it connected. The classic example is a document viewer spawning a script interpreter. You can prototype that detection with psutil:

import psutil

OFFICE = {"winword.exe", "excel.exe", "powerpnt.exe", "outlook.exe"}
SHELLS = {"powershell.exe", "pwsh.exe", "cmd.exe", "wscript.exe",
          "cscript.exe", "mshta.exe", "rundll32.exe"}

for proc in psutil.process_iter(["pid", "name", "ppid", "cmdline"]):
    name = (proc.info["name"] or "").lower()
    if name not in SHELLS:
        continue
    try:
        parent = psutil.Process(proc.info["ppid"]).name().lower()
    except (psutil.NoSuchProcess, psutil.AccessDenied):
        continue
    if parent in OFFICE:
        cmd = " ".join(proc.info["cmdline"] or [])
        print(f"SUSPICIOUS {parent} -> {name} pid={proc.info['pid']}: {cmd[:120]}")

On a clean machine this prints nothing. A hit such as winword.exe -> powershell.exe ... -EncodedCommand JAB... is exactly what a macro dropper looks like. A real EDR records this history continuously (so a process that already exited is still visible), which a point-in-time script cannot do. Sysmon's process-creation events give you the same parent-child data in logs; detection and SIEM covers turning them into alerts.

For file-based hunting across many machines or samples, YARA rules describe patterns in text:

rule Suspicious_PowerShell_Cradle
{
    meta:
        description = "Script that downloads and executes code"
    strings:
        $a = "DownloadString" nocase
        $b = "Invoke-Expression" nocase
        $c = "IEX" nocase fullword
        $d = "FromBase64String" nocase
    condition:
        2 of them
}

Run it with yara -r rules.yar C:\Users\ or from Python with yara-python (yara.compile(filepath="rules.yar").match(path)). Expect false positives from legitimate admin scripts; YARA hits are leads to review, not verdicts.

The Defense Stack#

Layer controls so that no single failure is total:

  • Prevent delivery: email filtering, blocking macros in internet-sourced files, DNS filtering of known-bad domains.
  • Remove the exploit: patch operating systems, browsers and internet-facing appliances quickly; put MFA on every remote-access path.
  • Limit what runs: application allowlisting (AppLocker, WDAC) on high-value machines, and users without local admin rights. Code that runs as a standard user cannot install drivers or disable security tools.
  • Detect behaviour: EDR on every endpoint, with alerts going to someone who reads them.
  • Contain the blast radius: network segmentation and egress filtering so a compromised workstation cannot reach servers directly or talk to arbitrary internet hosts.
  • Survive ransomware: backups that attackers cannot delete. Follow the 3-2-1 idea (three copies, two media types, one offline or immutable), keep backup credentials separate from domain admin, and test restores. A backup that has never been restored is a hope, not a control.

Handling an Infection#

Treat a confirmed infection as an incident, not an antivirus ticket:

  1. Isolate the host from the network (EDR network isolation, or pull the cable), but do not power it off if you may need memory evidence.
  2. Scope: search for the same hash, domain or behaviour across the fleet. The first machine you found is rarely the only one.
  3. Assume credential theft: rotate passwords, revoke sessions and tokens used on that machine.
  4. Rebuild rather than clean when in doubt, especially for rootkits and RATs. Reimaging from a known-good image is faster and more trustworthy than proving a system is clean.
  5. Close the entry point so the same route cannot be reused.

The incident response lesson covers evidence handling in detail.

Practice#

Build an isolated lab: a Windows VM with no shared folders, snapshot taken, network set to host-only. Install Sysmon, open a harmless document you create with a macro that launches notepad.exe, and confirm the parent-child relationship appears in Sysmon event ID 1 and in the psutil script. Then write a YARA rule that matches your test document and nothing else in your Documents folder. Only analyse real malware samples in a properly isolated lab, and never on a work machine.