Modify Program (T0889) is the point where an intruder stops looking at a controller and starts changing what it does to the physical process. MITRE ATT&CK for ICS files it under Persistence, because altered or added logic stays on the controller across restarts and keeps running long after the engineering session that loaded it has closed. Its procedure examples range from Stuxnet to the 2026 attacks on internet-exposed PLCs at US water utilities. This guide is for OT security engineers, control engineers and OT SOC analysts: what the technique covers, how it differs from its neighbours, how to detect logic changes with program hashes and protocol monitoring, and how to keep a trusted copy of every program so recovery is quick. For the wider matrix see the MITRE ATT&CK for ICS Guide.
Key takeaways
- Logic is the persistence layer. ATT&CK describes T0889 as modifying or adding a program on a controller, including new functions, changed logic in existing functions and new calls between functions in Program Organization Units (POUs).
- Program Download is only one route. Online edit and program append change logic while the controller keeps running, so there may be no stop, no restart and no obvious alarm.
- A trusted baseline makes detection possible. ATT&CK's detection strategy compares the running program hash with the last authorised baseline and flags any difference without a change ticket.
- Prevention sits on the controller and the workstation. ATT&CK lists four mitigations: Authorization Enforcement, Human User Authentication, Code Signing and Audit with cryptographic integrity checks.
- Recovery depends on offline, verified program copies. Without a known-good project file and program for each controller, an altered controller cannot be restored with confidence.
What T0889 covers and how it differs from nearby techniques
In ATT&CK for ICS v20, Modify Program applies to the Embedded platform and sits in the Persistence tactic. The technique description says modification can be done with a Program Download as well as other forms such as online edit and program append, and it points to IEC 61131-3 Program Organization Units as the programming elements involved. It also notes that some programs may let an adversary interact directly with the controller's native API.
Several ATT&CK for ICS techniques touch the same controller, and the boundaries matter for detection and reporting.
| Technique | Tactic | What happens | Typical evidence |
|---|---|---|---|
| T0889 Modify Program | Persistence | Logic on the controller is added to or changed | Program hash differs from baseline, new or changed blocks |
| T0843 Program Download | Lateral Movement | A user program is transferred to the controller (the transport for many T0889 changes) | Download session from an engineering tool, possible mode change |
| T0845 Program Upload | Collection | The running program is read from the controller to study the process | Upload request from an unexpected host, often before a change |
| T0821 Modify Controller Tasking | Execution | Task associations are changed so the controller runs the adversary's program | Task configuration differs from baseline |
| T0873 Project File Infection | Persistence | Project files on the engineering side carry malicious content | Project file on a workstation or share differs from the approved copy |
| T0858 Change Operating Mode | Execution, Evasion | The controller is switched to a mode that permits engineering functions | Key switch or software mode change outside a change window |
In practice these appear together: an upload to understand the process, a mode change, a download or online edit, then the modified program persisting. Each ID has its own page in the ATT&CK matrix, and a detection programme should record them separately.
Procedure examples and what they teach
ATT&CK v20 lists two software examples, one group and one campaign for T0889.
- Stuxnet (S0603): ATT&CK records that it infected PLCs with different code depending on the characteristics of the target, using an infection sequence of code blocks and data blocks downloaded to alter the PLC's behaviour. The lesson is that a modification can be tailored to one plant and stay silent elsewhere. See the ICS Malware History Guide.
- PLC-Blaster (S1006): a 2016 research worm by Spenneberg, Brüggemann and Schwartke that copies itself into POUs (Data Block, Function and Function Block) on Siemens S7-1200 PLCs. The authors' paper shows the worm stored alongside the unmodified user program, surviving restarts, and notes that engineering software can list the added blocks but not analyse them. Their main defence was the controller's access protection level that blocks code changes over the network when the password is unknown to the attacker.
- CyberAv3ngers (G1027): ATT&CK records that during the 2026 Iranian Water Campaign (C0065) the group used manufacturers' commercial programming software from Rockwell Automation, Schneider Electric (EcoStruxure Control Expert) and Siemens (TIA Portal) to modify running PLC program logic, citing CISA advisory AA26-097A. Legitimate engineering tools are the attack tool here, so allowlisting the software alone does not help: who runs it, from where and against which controller is what matters.
- 2026 U.S. Water Utilities Attacks (C0066): ATT&CK records that the adversary altered the control logic of internet-exposed PLCs after gaining access through default credentials, producing ladder logic discrepancies. Forescout's analysis states that at least one victim had its PLC logic modified, while most reported cases involved password and IP address changes. ATT&CK notes the campaign has not been formally attributed.
The water cases are a reminder that T0889 needs reachability, not sophistication. Tenable's summary of the federal guidance lists removing PLCs from direct internet exposure and setting physical mode switches to Run to block remote logic changes among the first actions. See the Water and Wastewater Cybersecurity Guide.
Prevention: the ATT&CK mitigations in practice
| Mitigation | What ATT&CK says for T0889 | How to apply it in OT |
|---|---|---|
| M0800 Authorization Enforcement | Restrict program modification to certain users such as engineers and field technicians, preferably with role-based access | Turn on the controller's protection level or write protection and record who holds the password; restrict the engineering role in the programming software to named engineers |
| M0804 Human User Authentication | Require authentication for all remote or local management sessions, supporting account use, password and user account management policies | Named accounts on engineering workstations and in controller security features where the product supports them; no shared "engineer" login |
| M0945 Code Signing | Use code signatures to verify the integrity and authenticity of programs on safety or control assets | Turn on signed project or program features where the controller and firmware support them; test in a lab first |
| M0947 Audit | Verify the integrity of control logic loaded on a controller; prefer cryptographic hashes such as SHA-2 or SHA-3 over CRCs and checksums, which are not cryptographically strong | Scheduled program comparison against the approved copy, with SHA-256 hashes of exported programs and project files |
Physical controls matter as much as software ones. Many controllers have a key switch or mode selector, and Mandiant's TRITON analysis recommends keeping keys out of PROGRAM mode except during scheduled programming events, auditing key state and putting key position changes under change management. That advice transfers to any controller with a hardware mode switch. See the PLC Security Guide for controller hardening in general.
- Engineering workstations: the tools that legitimately modify programs live here, so they are the main control point. Dedicated hosts, no internet browsing, application allowlisting and named logons. See the Engineering Workstation Security Guide.
- Network paths: only the engineering workstation subnet should reach controller programming ports. Use zones and conduits to enforce it; see the OT Network Segmentation, Purdue Model and IEC 62443 Zones and Conduits Guide.
- Remote and vendor access: integrators often hold programming rights. Broker their sessions and make them time-bound; see the OT Remote Access Guide.
Detection: program hashes, protocol writes and process effects
ATT&CK v20 detection strategy DET0783 (Detection of Modify Program) has one embedded-platform analytic, AN1915. It flags an ICS protocol write to an existing program block from a source not on the approved engineering workstation list, outside a scheduled change window, and correlates it with a post-change program hash comparison and a measurable change in I/O behaviour. Like all ATT&CK for ICS analytics in v20, it carries an operational fidelity gate: alert only when the action cannot be attributed to an authorised engineering source and falls outside an approved maintenance window or lacks change-control context.
| Data source (ATT&CK v20) | What to look for | Where it comes from |
|---|---|---|
| assetinventory:ProgramHash | Program hash differs from the last authorised baseline with no change ticket reference | OT asset inventory or change detection tooling that polls controllers, or scheduled manual comparison |
| NSM:Content | Write to an existing program block from a source not on the engineering workstation list, outside the change window | Passive OT network monitoring with protocol decoding for the controller family |
| device:VendorLog | Change in scan cycle timing or I/O update pattern after a flagged write | Controller diagnostics and event buffers, historian trends |
Add two engineering-side sources. Engineering software and workstation logs show who opened which project and when a download or online edit was performed. Project file hashes on the engineering share catch T0873 activity before it reaches a controller. PLC-Blaster's authors also point to unexpected PLC stops and unusual scanning on port 102/tcp in the industrial network as visible signals for that family of controller. For the monitoring platform itself see the OT Network Security Monitoring Guide.
Useful measures that show this is working:
- Baseline coverage: percentage of controllers with a current, hashed, approved program copy.
- Comparison frequency: time between automated or manual program comparisons per critical controller.
- Unexplained changes: number of program hash mismatches without a matching change record, and time to resolve each.
- Write source compliance: percentage of program writes that came from approved engineering hosts.
- Restore time: time to restore a controller to its approved program in an exercise.
Controller program backups and recovery
Detection is only useful if you can return to a known-good state. Keep, for every controller, the approved project file, an exported copy of the running program and its SHA-256 hash, stored offline and away from the engineering workstations that an intruder would use. Forescout's analysis of the 2026 water attacks recommends keeping approved offline copies of controller programs, and Tenable's summary recommends offline, tested backups of PLC logic and configurations. For the full method see the OT Backup, Recovery and Golden Image Guide.
- Inventory: list every programmable controller, its firmware version, programming tool and project file owner. Start from the OT Asset Visibility Guide.
- Capture the baseline: during a planned window, upload each running program, compare it with the project file, resolve differences with the control engineer and record the approved hash.
- Protect the copies: store them offline or on a repository the engineering workstations cannot write to, with access logged.
- Automate comparison: where tooling supports it, poll program hashes on a schedule; start with alert-only, and agree with operations which controllers can be polled and how often.
- Tie to change control: every approved change produces a new baseline and hash in the same ticket.
- Exercise the restore: restore a test controller from the stored copy at least once a year, and time it.
Responding to a suspected program modification
Process safety comes first. A modified program may already be steering the process, and a hasty stop or download can cause its own hazard. Use the OT Incident Response Guide and agree each step with operations.
- Confirm with operations: is the process behaving as expected, and is manual or local control available if needed?
- Preserve evidence: upload the running program from a trusted workstation, hash it and keep it; collect controller event buffers, network captures and engineering workstation logs.
- Contain the path: block the source host at the conduit, suspend remote access and rotate controller and engineering passwords.
- Compare and decide: diff the uploaded program against the approved copy with the control engineer and decide when to restore.
- Restore and verify: download the approved program in a planned window, confirm the hash, then watch I/O behaviour.
Common failure patterns
- No approved copy exists: the latest project file lives on one engineer's laptop and does not match the running program, so a change cannot be proven or reversed.
- Controllers reachable from the internet: the 2026 water attacks reached PLCs exposed through cellular links, where default or weak credentials were the only barrier.
- Protection features left off: controller access protection, write protection and code signing exist on many platforms but are not turned on, so any host that can reach the controller can change it.
- Key switches left in a programming mode: remote changes are possible all year because the physical control was set once at commissioning.
- CRCs treated as integrity checks: ATT&CK's M0947 notes CRCs and checksums are not cryptographically strong; use a cryptographic hash for the baseline.
- Alerts without change context: monitoring flags every legitimate download, operators learn to ignore it, and the one unauthorised write is missed.
Framework mapping
| Framework | Reference | Relevance to T0889 |
|---|---|---|
| ATT&CK for ICS mitigations | M0800, M0804, M0945, M0947 | Restrict who can modify, authenticate sessions, sign programs, verify integrity |
| NIST SP 800-53 Rev 5 | CM-3 Configuration Change Control, CM-5 Access Restrictions for Change, SI-7 Software, Firmware, and Information Integrity, CP-9 System Backup | Authorised change, restricted change rights, integrity verification, program backups |
| NIST CSF 2.0 | PR.PS-01, DE.CM-09, PR.DS-11 | Configuration management, monitoring of software and runtime environments, tested backups |
| NIST SP 800-82 Rev 3 | Guide to Operational Technology (OT) Security | OT-specific tailoring of the controls above |
For IEC 62443 component and system requirements see the IEC 62443 Guide.
Practitioner checklist
- Hold an approved project file, exported program and SHA-256 hash for every controller, stored offline.
- Turn on controller access protection or write protection and record who holds the passwords.
- Set key switches to Run and audit key state under change management.
- Remove every controller from direct internet exposure and broker remote engineering access.
- Allow programming traffic only from named engineering workstations.
- Monitor program writes, uploads and mode changes with passive OT network monitoring.
- Compare running program hashes with the baseline on a schedule and tie every change to a ticket.
- Exercise a controller restore from the stored copy at least once a year.
Standards and references
- MITRE ATT&CK for ICS: T0889 Modify Program
- MITRE ATT&CK: C0066 2026 U.S. Water Utilities Attacks
- NIST: SP 800-82 Rev. 3, Guide to Operational Technology (OT) Security
- Black Hat Asia 2016: PLC-Blaster, A Worm Living Solely in the PLC
- Mandiant: Attackers Deploy New ICS Attack Framework TRITON
- Forescout: Exposed Devices Attacked in US Water Systems
- Tenable: Coordinated Cyberattack on Minnesota Water Utilities
Related NHI Mgmt Group resources: PLC Security Guide · OT Backup, Recovery and Golden Image Guide · Engineering Workstation Security Guide · MITRE ATT&CK for ICS Guide