A controller that suddenly takes longer, or less time, to run its program is often running a different program, and the cycle time counter it already keeps is the cheapest way to notice. MITRE D3FEND names this countermeasure Application Performance Monitoring (D3-APM) and defines it as "Monitoring the count and duration of the application or program cycle." It sits under the Detect tactic as a child of Platform Monitoring (D3-PM), and it monitors two digital artefacts: Application Scan Time and System Application Cycle Count. Its one child is Application Exception Monitoring (D3-AEM). D3FEND's description and its single reference, the Top 20 Secure PLC Coding Practices, place it in industrial control: scan time on programmable logic controllers (PLCs), trended on the HMI and correlated with other events. This card covers what D3-APM detects, why D3FEND shows no direct ATT&CK mapping for it, how to build and verify it on controllers, and where it falls short. It is written for OT security engineers, controls engineers and the SOC analysts who receive OT alerts.
Key takeaways
- Scan time is a fingerprint of the logic. On a stable process the time a controller takes to complete its main loop stays within a narrow band, so a step change suggests injected or deleted logic, a changed network load or a failing device.
- Two counters, both cheap. D3-APM watches the measured scan time and the count of completed program cycles since startup; both are native to most controllers or can be added in a few rungs of logic.
- No direct ATT&CK mapping. D3FEND relates no ATT&CK technique to scan time or cycle count; the techniques its page displays come from the child D3-AEM's Log artefact. The PLC-relevant link is the Top 20 practice's own mapping to Project File Infection (T0873).
- Trend, do not just limit. Many controllers also have a scan time watchdog that stops the CPU when a maximum is exceeded (general PLC practice, not part of the Top 20 guidance); D3-APM is about logging average, peak and minimum values and alerting on drift well before that point.
- It is a tripwire, not proof. A small, careful logic change can stay inside normal jitter, so pair cycle time trends with program checksums, change detection and memory trending.
D3-APM at a glance
| Attribute | Value |
|---|---|
| D3FEND ID | D3-APM (d3f:ApplicationPerformanceMonitoring) |
| Tactic | Detect |
| Parent technique | Platform Monitoring (D3-PM): "Monitoring platform components such as operating systems software, hardware devices, or firmware." |
| Child technique | Application Exception Monitoring (D3-AEM), synonym Application Failure Monitoring |
| Digital artefact 1 | Application Scan Time (monitors): "A variable that tracks the measured time it takes to begin, run, and complete a select portion of an application's logic." |
| Digital artefact 2 | System Application Cycle Count (monitors), synonym Controller Cycle Count: the number of times the controller has completed its main program loop since startup or last reset. D3FEND notes that in most controllers this is not a default tag but something that should be programmed. |
| D3FEND reference | Top 20 Secure PLC Coding Practices, V1.0 (PLC Security, 2021) |
| Typical data path | PLC system variable or summary logic, HMI trend, historian, then alarm forwarding to the SOC |
| Effort | Low per controller; the work is baselining and alarm design across a fleet |
How it works
D3FEND's knowledge base article describes the method in one line: keep track of the controller cycle time by logging it, setting alarms and correlating it with other events, because changes to cycle time can indicate injected logic, deleted logic or system failures.
A PLC runs its program in a loop: read inputs, execute logic, write outputs, handle communications, repeat. The duration of one loop is the scan time (or cycle time). It depends mainly on how much logic executes, which branches are taken and how much communication the CPU services. On a process in steady state, those factors change little, so the scan time trend is flat with small jitter. Adding a block of logic lengthens it; removing or bypassing logic shortens it; a flood of network requests or a failing module can push it up or make it erratic.
Practice 16 of the Top 20 Secure PLC Coding Practices, "Summarize PLC cycle times and trend them on the HMI", gives the concrete design:
- Summarise in the controller: calculate average, peak and minimum cycle times every 2 to 3 seconds from the system variable, rather than sending every raw value.
- Trend on the HMI: plot the summaries so operators and engineers can see heavy CPU load and step changes at a glance.
- Alarm on deviation: compare against a reference cycle time with a defined threshold for normal fluctuation, and log any deviation.
- Know the hardware limit (general PLC practice, not from the Top 20 document): many PLCs already enforce a maximum cycle time and force the CPU to STOP when it is exceeded. That watchdog is a safety backstop; the software monitor is what catches the smaller changes an attacker would make.
The document maps practice 16 to the Execution tactic and to Project File Infection (T0873), and lists its target group as integration and maintenance service providers, which reflects who usually writes the summary logic.
The System Application Cycle Count adds a second, simpler signal. A counter that increments once per scan and resets only at startup lets you check that the program is actually executing at the expected rate, and a counter that goes back to zero without a planned restart reveals a reset that may not have been logged anywhere else.
Signals to collect
| Signal | Source | Example change and what it may indicate |
|---|---|---|
| Average scan time | PLC system variable, summarised in logic | A lasting step up or down after no planned change: logic added, removed or altered (T0873, Modify Program T0889) |
| Peak scan time | Same summary block | New spikes at regular intervals: a new routine or task that runs periodically |
| Minimum scan time | Same summary block | A lower floor: logic bypassed or a routine no longer called |
| Cycle count | Programmed counter (not a default tag on most controllers) | Unexpected reset: restart outside a maintenance window (Device Restart/Shutdown T0816); slower rate: CPU overload |
| Scan time versus communications load | HMI or historian correlation with network monitoring | Scan time rising with polling volume: heavy or unauthorised remote reads and writes |
| Watchdog or maximum cycle time faults | Controller fault log | CPU forced to STOP; covered in depth by the child D3-AEM |
ATT&CK and D3-APM: what D3FEND does and does not map
Relationship type: none direct. D3FEND relates no ATT&CK technique to Application Scan Time or System Application Cycle Count (D3FEND 1.6.0, checked November 2026).
The D3FEND page for D3-APM still displays a list of enterprise techniques, such as DCSync (T1003.006), Password Spraying (T1110.003), Clear Command History (T1070.003) and Windows Management Instrumentation Event Subscription (T1546.003). Those are inherited from the child technique: D3-AEM monitors the Log artefact, and D3FEND infers relations to every technique that modifies or may modify a log. They are inferred and experimental, they do not describe what a cycle time monitor detects, and they are covered on the D3-AEM Application Exception Monitoring page. The list also includes Clear Windows Event Logs under an ID that ATT&CK v20 has revoked; its successor is T1685.005.
The useful mapping for practitioners comes from the D3FEND reference itself and from ATT&CK for ICS. The table below is labelled accordingly; each ID was checked against ATT&CK v20.
| ATT&CK for ICS ID | Technique | Source of the link | Why scan time helps |
|---|---|---|---|
| T0873 | Project File Infection | Top 20 practice 16 mapping | Infected project logic, once downloaded, usually changes scan time |
| T0889 | Modify Program | NHI Mgmt Group view | Added or removed routines change execution time |
| T0843 | Program Download | NHI Mgmt Group view | A full download often brings a restart (cycle count reset) and a new scan time baseline |
| T0816 | Device Restart/Shutdown | NHI Mgmt Group view, via cycle count reset | A counter reset without a planned restart shows the event |
Deeper attacker-side detail is on the T0873 Project File Infection, T0889 Modify Program and MITRE ATT&CK for ICS T0843 Program Download pages.
Where it is implemented
| Implementation class | What it provides | Fits when |
|---|---|---|
| Controller logic plus HMI trend | Summary block in the PLC (average, peak, minimum), HMI trend screen and HMI alarm, as practice 16 describes | You control the PLC code and want a no-cost start using native functions |
| Historian with analytics | Long-term storage of the summaries, baselines per controller and deviation alarms | A plant historian already collects process tags |
| OT network monitoring platforms | Passive or active collection of controller diagnostics and program change events, correlated with network activity | You need fleet-wide visibility without changing every controller's logic |
| Change management and backup tools for automation | Program comparison and checksums that confirm or rule out a logic change after a scan time alarm | Several engineering teams or integrators touch the same controllers |
Platform choices and rollout are covered in the OT Security Platform Buyer's Guide; controller-level hardening is in the PLC Security Guide.
Implementation steps
- Pick the controllers. Start with controllers that run safety-relevant or high-consequence logic and whose program changes rarely. Record the program version and checksum at the time you start.
- Expose the signals. Read the scan time from the controller's system variable and write a summary block that produces average, peak and minimum every 2 to 3 seconds. Program a cycle counter if the controller has none. Test the change on a simulator or a spare controller first and measure its own effect on scan time.
- Baseline per operating state. Collect at least several weeks of data across normal production, start-up, shutdown and maintenance modes, because scan time legitimately differs between states. Store one reference value and tolerance band per state.
- Set alarms. Alarm on sustained deviation outside the band (for example, average outside the band for more than a few minutes; an NHI Mgmt Group example, not a standard), on new peak patterns and on any cycle counter reset. Route security-relevant alarms to the SOC as well as to operators.
- Link to change control. Every approved program download should update the baseline through the change record. An alarm with no matching change ticket triggers a program comparison against the last known good version.
- Write the response. The runbook should compare the running program with the backup, check engineering workstation activity and controller mode changes, and escalate to OT incident response if the change is unexplained.
- Roll back safely. If the summary logic causes problems, remove it in a planned window under normal change control; the HMI trend and alarms can be disabled without touching process logic.
How to verify it works
- Planned change test: during an approved maintenance window on a test or low-consequence controller, download a version with a small extra routine and confirm the trend shifts and the alarm fires. Revert and confirm the trend returns.
- Restart test: perform a planned restart and confirm the cycle counter reset raises the expected event.
- Load test: in a test environment, increase communication polling to the controller and record how far scan time moves. This tells you how much non-security noise to expect.
- Data path check: confirm the summaries arrive in the historian and alarms reach the SOC queue, with time synchronisation in place so they can be correlated with network and workstation logs.
| Metric | Example target (NHI Mgmt Group suggestion, not a standard) | Why it matters |
|---|---|---|
| Critical controllers with scan time trending | 100% of high-consequence controllers | Coverage of the logic that matters most |
| Scan time alarms matched to a change record | All alarms explained within one shift | Unexplained alarms are the security signal |
| Baselines updated after approved downloads | Within 24 hours of the change | Stale baselines cause alarm fatigue |
| Planned change tests that triggered the alarm | 100% | Proves the tripwire works end to end |
| False alarms per controller per month | Falling after tuning | Shows tolerance bands match real operation |
Limits, bypasses and failure patterns
- Changes inside the jitter: a modified setpoint or a single altered comparison barely changes execution time. Parameter tampering is better caught by validating timers, counters and inputs in logic; see MITRE ATT&CK for ICS T0836 Modify Parameter.
- Logic that compensates: an adversary with time to study the controller could keep total execution time similar, for example by replacing rather than adding logic. Program checksums and change detection close that gap.
- Trusting the controller to report on itself: the summary block runs on the same CPU an attacker may control, so it can be altered or fed false values. Comparing the controller's reported values with an external poll, and protecting the summary routine with the same integrity checks as process logic, reduces this risk.
- One baseline for all states: start-up, batch changes and maintenance mode all change scan time. A single threshold either misses changes or alarms constantly.
- Alarms that stay with operators: a trend that only appears on the HMI is a process diagnostic, not a security control, until someone outside the control room sees the alarm and has a runbook for it.
- No time synchronisation: without accurate timestamps a scan time change cannot be correlated with a workstation login or a download event.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| NIST SP 800-53 Rev 5 | SI-4 System Monitoring | Monitoring controller behaviour for indicators of attack |
| NIST SP 800-53 Rev 5 | SI-7 Software, Firmware, and Information Integrity | Scan time drift as an indirect integrity signal for controller logic |
| NIST SP 800-53 Rev 5 | CM-3 Configuration Change Control | Matching alarms to approved program changes |
| NIST CSF 2.0 | DE.CM-09, DE.AE-02 | Monitoring computing hardware, software and runtime environments; analysing potentially adverse events |
| Top 20 Secure PLC Coding Practices | Practice 16 (cycle times); related practices 5 (checksums), 17 (uptime) and 19 (memory) | The D3FEND reference and its companion monitoring practices |
| MITRE D3FEND | D3-PM, D3-APM, D3-AEM | Parent, technique and child |
Related countermeasures
- Application Exception Monitoring (D3-AEM): the child technique, watching fault counters, timer failures and logs. See D3-AEM Application Exception Monitoring.
- Platform Uptime Monitoring (D3-PUM): trends uptime to detect restarts, the companion to cycle count resets. See D3-PUM Platform Uptime Monitoring.
- Operating Mode Monitoring (D3-OMM): detects operating modes such as Program, Run, Remote or Stop, which usually change before a download. See D3-OMM Operating Mode Monitoring.
- Operating Mode Restriction (D3-OPR) and OT Variable Access Restriction (D3-OVAR): hardening that makes the changes D3-APM detects harder to make. See D3-OPR Operating Mode Restriction and D3-OVAR OT Variable Access Restriction.
Practitioner checklist
- List high-consequence controllers and record program version and checksum before starting.
- Expose average, peak and minimum scan time every 2 to 3 seconds, and program a cycle counter where none exists.
- Test the summary logic on a simulator or spare controller and measure its own scan time cost.
- Baseline scan time per operating state, not as one figure.
- Alarm on sustained deviation, new peak patterns and any cycle counter reset.
- Route security-relevant alarms to the SOC as well as the HMI, with time synchronisation in place.
- Tie every approved download to a baseline update through change control.
- Run a planned change test at least once a year per controller class and record the result.
- Pair scan time monitoring with program checksums and memory trending.
Standards and references
- MITRE D3FEND: Application Performance Monitoring (D3-APM)
- MITRE D3FEND: Application Exception Monitoring (D3-AEM)
- PLC Security: Top 20 Secure PLC Coding Practices V1.0
- PLC Security: Secure PLC Coding Practices project
- MITRE ATT&CK for ICS: T0873 Project File Infection
- NIST: SP 800-53 Rev. 5 Security and Privacy Controls
- NIST: Cybersecurity Framework 2.0
Related NHI Mgmt Group resources: PLC Security Guide · OT Security Guide · MITRE ATT&CK for ICS Guide · MITRE D3FEND Guide