The situation
An estate with GuardDuty enabled across 40 accounts. Malware Protection is not currently enabled. Two recent incidents motivated the question of whether to turn it on:
- Cryptominer on a developer instance. A dev installed an unofficial Docker image that happened to bundle XMRig. GuardDuty’s base detector caught the outbound CPU miner traffic via
CryptoCurrency:EC2/BitcoinTool.B!DNSbut couldn’t tell us where on the instance the miner binary lived. The responding engineer spent two hours SSH’ing around the instance’s filesystem manually. - Webshell on a partner-facing API instance. A known supply-chain compromise in an npm package dropped a webshell into
node_modules/. No outbound connection to flag yet; the webshell was waiting for a trigger. GuardDuty’s base detector had nothing.
The security team wants:
- On-demand scanning of suspicious instances (linked to GuardDuty findings).
- Scheduled scanning of production instances regardless of findings.
- Scanning of new S3 uploads for malware.
- A finding format that integrates with the existing Security Hub triage pipeline.
- Clarity on what the scanner can’t see (running-process memory, encrypted volumes without keys, etc.).
GuardDuty’s Malware Protection tiers address most of these, with known blind spots.
What actually matters
A malware scanner on AWS is solving a different problem than a CVE scanner or a network detector. Inspector asks “is any installed package known-vulnerable?” GuardDuty’s base detector asks “is the network behaviour consistent with a known attack?” A malware scanner asks “is there a file on disk that matches a known-malicious signature, or looks like a known-malicious pattern?”
That’s a filesystem-walking problem. Doing it on a running instance means either installing an agent (classical endpoint AV), which creates operational burden and possibly impacts workload performance, or doing it out-of-band by taking a snapshot of the instance’s disks and scanning the snapshot from somewhere else.
The snapshot approach has real advantages. It’s agentless (no install, no performance impact on the scanned instance). It’s safe against an attacker trying to evade detection, because the scanner runs in an isolated environment, so rootkit-style tampering can’t affect the scan. It’s consistent: the scan sees the filesystem at a single point in time.
It also has real limitations. It can’t see process memory (encrypted in-memory malware is invisible). It needs the volume to be decryptable; if it’s encrypted with a key the scanner can’t access, the scan fails. It runs on a schedule or trigger, not continuously, so malware that lands between scans isn’t seen until the next one. It doesn’t catch fileless attacks that never touch disk.
The three workload shapes the team cares about are also different problems. Scanning attached EBS volumes on suspicious activity or on-demand is one. Scanning objects newly uploaded to buckets is another. Catching in-memory and fileless attacks in real time is a third, and it requires an agent watching syscalls, not a periodic snapshot. A complete answer probably combines more than one of these.
What we’ll filter on
- Workload coverage. EC2, EKS, ECS, S3, Fargate?
- Trigger. GuardDuty finding, schedule, on-demand, or event-driven?
- In-memory / fileless detection. Does it see processes or just disk?
- EBS-encrypted volume handling. What happens with KMS-encrypted disks?
- Cost shape. Per-GB scanned, per-instance, or per-object?
The malware-scanning landscape
1. GuardDuty Malware Protection for EC2. Agentless snapshot-based scan. On a triggering GuardDuty finding (types like Trojan:EC2/*, CryptoCurrency:EC2/*, Backdoor:EC2/*), GuardDuty takes an EBS snapshot, scans it in an AWS-managed account, and emits a follow-up finding if malware is detected. Also supports aws guardduty start-malware-scan for on-demand scans. Does not cover in-memory or fileless attacks. Requires EBS volumes to be unencrypted or encrypted with KMS keys that grant the AWS-managed role access.
2. GuardDuty Malware Protection for S3. Managed scanner on S3 PutObject. Configured per-bucket; scans objects on upload, tags them with a scan result (NO_THREATS_FOUND, THREATS_FOUND, UNSUPPORTED), and emits findings. Useful for buckets accepting uploads from customers or partners. Priced per GB scanned.
3. GuardDuty Runtime Monitoring. eBPF agent on EKS nodes (deployed as an add-on), on ECS tasks on Fargate (sidecar model), and on EC2 (SSM-installed agent). Watches syscalls, process trees, file operations, network connections in real time. Detects fileless malware, in-memory injection, privilege escalation. Priced per-vCPU-hour for the monitored resource.
4. Third-party EDR (CrowdStrike, SentinelOne, Microsoft Defender, Trend Micro). Agent-based endpoint detection and response. Deep signal, strong UX, cross-cloud. Agent install, licence cost, operational overhead.
5. Custom signature scanners (ClamAV, YARA). Open-source antivirus tools. Can be deployed as a sidecar, scheduled Lambda, or EC2 scanner. Cheaper per-scan; require signature management and integration work.
6. Amazon Inspector. CVE scanner, not a malware scanner. Complementary rather than competitive; Inspector tells you “this package has a known vulnerability”, and Malware Protection tells you “there’s a known-malicious file on disk.”
Side by side
| Option | Coverage | Trigger | In-memory | Encryption handling | Cost shape |
|---|---|---|---|---|---|
| GD Malware Protection (EC2) | EC2 EBS volumes | GD finding + on-demand + scheduled | ✗ | KMS key must grant AWS role | Per-GB scanned |
| GD Malware Protection (S3) | S3 uploads | PutObject | ✗ (objects at rest) | SSE-S3 / KMS supported | Per-GB scanned |
| GD Runtime Monitoring | EKS, ECS-Fargate, EC2 | Continuous | ✓ (eBPF) | N/A | Per-vCPU-hour |
| Third-party EDR | Anywhere agent runs | Continuous | ✓ | Agent-based | Per-endpoint |
| ClamAV / YARA DIY | Anywhere you deploy | Custom | ✗ | Custom | Operational |
| Inspector | EC2, ECR, Lambda | Continuous | ✗ (CVE only) | N/A | Per-resource |
Reading the table: Malware Protection for EC2 is the agentless-disk answer; Runtime Monitoring is the in-memory answer; S3 Malware Protection is the upload-scanning answer. They coexist rather than substitute.
The snapshot scan path
The picks in depth
Malware Protection for EC2 with automatic triggers. Enable from the GuardDuty console or CLI. Once enabled, GuardDuty automatically triggers a malware scan when base detector findings indicate potential malware (types like Trojan:EC2/*, CryptoCurrency:EC2/*, Backdoor:EC2/*). The scan completes within ~15-45 minutes for typical volume sizes and emits follow-up findings of type Execution:EC2/MaliciousFile or similar, linked to the original finding by resource ID. On-demand scans via aws guardduty start-malware-scan for investigation of specific instances.
KMS key policy for encrypted volumes. For EBS volumes encrypted with customer-managed KMS keys, the scanner’s AWS-managed role needs kms:CreateGrant, kms:Decrypt, kms:DescribeKey, kms:GenerateDataKey* on the key. Add this to every CMK that might be attached to a scan-eligible instance; without it, the scan fails with a “cannot access volume” error. AWS provides a documented key policy snippet for this.
Malware Protection for S3 on upload-accepting buckets. Enable per-bucket for any bucket that accepts uploads from external sources (customer uploads, partner-dropzone buckets, form attachments). The scanner tags objects on PutObject with the scan result; a bucket policy can require GuardDutyMalwareProtection:NoThreatsFound on read actions, effectively quarantining unscanned or threat-found objects until a human reviews. Priced per GB scanned; exempt internal-only buckets to control cost.
Runtime Monitoring for in-memory coverage. Enable on the production EKS clusters and on EC2 hosts running long-lived stateful workloads where fileless attacks are a concern. The eBPF agent is deployed automatically on EKS via an add-on and on EC2 via SSM-installed agent. Runtime Monitoring catches process-injection, unexpected network activity, unusual syscall sequences: signals the snapshot scan can’t see.
A worked incident
01:42 UTC. GuardDuty fires Trojan:EC2/BlackholeTraffic.DNS on i-0beef in a payments account. Malware Protection’s automatic trigger fires. Snapshot of the instance’s EBS volume taken in the customer account, shared to the AWS scanner account, scanner walks the filesystem.
02:04. Scanner emits Execution:EC2/MaliciousFile with:
- File path:
/tmp/.X11-unix/xmrig - Threat name:
MinerX.XMRig.Generic - SHA256:
7d4b... - Linked to the earlier
Trojan:EC2/BlackholeTraffic.DNSfinding.
02:05. Security Hub receives the finding; EventBridge rule routes HIGH-severity Execution findings to PagerDuty. On-call already paged from the base detector finding.
02:08. With the specific file path in hand, the on-call SSHs to the instance (via Session Manager), confirms the file exists, notes its parent process in /proc, identifies the calling user (a deployment service account), and traces back to the Docker image pulled 40 minutes earlier.
02:15. Contain: quarantine the instance, pull the image from the deployment target, revoke the service account’s ECR pull permission, open a supply-chain incident for the image source. Base detector finding alone told the on-call something was wrong; Malware Protection finding told them what and where. That’s what cuts response time.
What’s worth remembering
- Malware Protection for EC2 is agentless snapshot-based. Triggered by specific GuardDuty base finding types or on-demand; emits follow-up findings with file paths and hashes.
- Encrypted volumes need KMS permission for the scanner. Grant the AWS-managed scanner role access on every CMK that might be attached to a scannable instance.
- Malware Protection for S3 scans uploads on PutObject. Per-bucket enable; tags objects with scan results; bucket policies can enforce scan-before-read.
- Runtime Monitoring is the in-memory complement. eBPF agent on EKS, ECS-Fargate, EC2 for fileless and memory-injection detection.
- The snapshot scan is not real-time. Malware that lands between scans is invisible until the next scan; Runtime Monitoring closes this gap.
- Base GuardDuty findings trigger the scan automatically. The feedback loop “network signal → trigger disk scan → correlate filesystem evidence” is the value.
- Findings flow to Security Hub via ASFF. Routing, severity, and workflow are consistent with the rest of the GuardDuty finding stream.
- Pricing is per-GB scanned. Large multi-TB volumes are expensive to scan on every finding; plan policy so that only severity-relevant findings trigger the scan.
GuardDuty sees packets; Inspector sees packages; Malware Protection reads the disk; Runtime Monitoring watches the processes. The real defence-in-depth is all four, each answering what the others can’t.