Safeguard
Application Security•

RC Scripts Persistence (T1037.004): rc.local, init.d and ESXi

Editing rc.local or ESXi local.sh runs code as root at every boot. Learn how it works, what to monitor, and how to review these files on Linux, macOS and ESXi.

Safeguard Security Team
4 min read

RC Scripts is ATT&CK T1037.004. It maps to Persistence and Privilege Escalation and applies to macOS, Linux, Network Devices and ESXi.

RC scripts are the startup files of Unix-like systems. They let administrators start custom services at boot for different run levels. They need root to modify, and they run as root at startup, which is what makes them attractive.

How attackers use it

MITRE explains that an adversary can add a malicious binary path or shell commands to rc.local, rc.common or other RC scripts that are specific to the distribution. At the next reboot the system runs the script contents as root.

The technique is especially effective on lightweight Unix-like systems that use root as the default user, such as ESXi hypervisors, IoT and embedded devices. On ESXi, most system files are stored in memory and changes are discarded at shutdown, so modifying /etc/rc.local.d/local.sh is one of the few ways to keep persistence across reboots.

MITRE adds context on how relevant this is on other systems. Several Unix-like systems have moved to systemd and deprecated RC scripts. macOS deprecated them in favor of launchd, and the technique works only on Mac OS X Panther 10.3 and earlier there. To keep backward compatibility, some systems such as Ubuntu will still run RC scripts if they exist with the right file permissions.

Procedure examples include a router malware family that ran from a modified RC script, a backdoor that added itself to /etc/rc.local, a ransomware family that used RC scripts to persist in the ESXi service, and an IoT malware family that used an RC script under /etc/rc3.d.

How to detect it

The MITRE analytics by platform:

  • Linux: modified or newly created /etc/rc.local or /etc/init.d scripts followed by suspicious execution at startup.
  • macOS: edits or additions to /etc/rc.common, /Library/StartupItems or /System/Library/StartupItems and the script execution that follows at login or reboot.
  • ESXi: changes to /etc/rc.local.d/local.sh or rc.local, with abnormal commands in post-boot script execution.
  • Network devices: modified boot-time configuration scripts that persist malicious CLI commands across reboots.

File integrity monitoring on the RC paths is the first line. The second is a record of what runs at boot. On auditd systems, a watch rule on the file produces an event for every write:

sudo auditctl -w /etc/rc.local -p wa -k rc_local_change

That command adds a rule for the running system. Use your normal audit rules file to make it permanent, and search the events later with ausearch for the key you chose.

How to reduce the risk

MITRE lists one mitigation: restrict file and directory permissions. Limit the privileges of user accounts so only authorized users can edit the rc.common file, and apply the same idea to the other RC paths.

Additional steps that follow from the description: take a baseline of rc scripts across your Linux and ESXi hosts, compare each host against it on a schedule, and, if you do not use RC scripts at all, remove the file so that a new one is easy to notice.

Check your own environment

Linux, look for RC script files and read them. Any file you did not expect is a finding:

ls -l /etc/rc.local /etc/rc.d /etc/init.d 2>/dev/null
cat /etc/rc.local 2>/dev/null

ESXi, view the local startup script. On a clean host it holds little beyond its header and a final exit line:

ls -l /etc/rc.local.d/
cat /etc/rc.local.d/local.sh

macOS, check for StartupItems:

ls -l /Library/StartupItems 2>/dev/null

A short list to carry away:

  • Who can write to the RC paths on each host?
  • Do you have a baseline copy to diff against?
  • Is anything that runs from these files outside your normal software inventory?

Click through it at your own pace, or open it full screen.

Quick check

Why is /etc/rc.local.d/local.sh important on ESXi?

ESXi keeps most system files in memory and discards changes at shutdown, so this script is one of the few places where an attacker can plant something that survives a reboot.

With what privileges do RC scripts run?

Root. They run at startup, and modifying them also needs root.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.