Skip to content

Artifact Analysis: Linux Legacy Persistence (init.d, rc.local)

1. The “Quick & Dirty” Persistence: /etc/rc.local

Section titled “1. The “Quick & Dirty” Persistence: /etc/rc.local”

Historically, /etc/rc.local was the traditional script executed at the very end of the boot process, right before the login prompt appeared. It was designed for administrators to easily add custom startup commands without writing complex service files.

In modern systemd environments, this file is executed via a compatibility unit (rc-local.service). If the file exists and has the executable bit set, systemd will run it.

An attacker simply appends a malicious command (e.g., a reverse shell or a dropper payload) to the end of the file, ensuring it executes with root privileges upon every reboot.

To investigate a mounted forensic image (e.g., /mnt/analysis/), analysts must scrutinize the file contents:

Terminal window
cat /mnt/analysis/etc/rc.local

Hunting Focus: Look for any commands executing before the exit 0 statement, especially invocations of /bin/bash -i, curl, wget, or the execution of hidden binaries residing in /tmp/ or /dev/shm/.

Before systemd, Linux managed services using SysVinit scripts and execution runlevels (0 through 6). Runlevel 3 (multi-user text mode) and Runlevel 5 (graphical interface) are the standard operational states.

For a script located in /etc/init.d/ to execute at boot, a symbolic link must be created in the corresponding runlevel directory (e.g., /etc/rc3.d/). This symlink must begin with the letter S (for Start), followed by a priority number (01-99).

  1. The attacker drops a malicious bash script (e.g., network-daemon) into /etc/init.d/.
  2. They create the activation symlink: ln -s /etc/init.d/network-daemon /etc/rc3.d/S99network-daemon.
  3. The S99 prefix ensures the malicious script executes last, after all legitimate network services are initialized.

Analysts must list the activation links and trace them back to their origin scripts:

Terminal window
ls -l /mnt/analysis/etc/rc*.d/S*

Hunting Focus: Identify symbolic links pointing to unrecognized scripts. Pay special attention to scripts with a high priority number (e.g., S99).

While not strictly “boot” scripts, global profile scripts are executed every time an interactive shell is spawned. Unlike ~/.bashrc, which only affects a specific user, these files affect all users, including root.

  • Artifact Locations:
    • /etc/profile
    • /etc/profile.d/*.sh
    • /etc/bash.bashrc

If an attacker drops a backdoor.sh into /etc/profile.d/, the payload will detonate with administrative privileges the moment a legitimate system administrator logs in via SSH or a local TTY.

Advanced threat actors utilize “Timestomping” (altering file modification dates) to blend their malicious scripts in /etc/init.d/ with legitimate system files dating back to the OS installation. Relying solely on mtime (modification time) is insufficient.

DFIR analysts must leverage the native package managers (DPKG or RPM) to perform integrity checks on suspicious scripts.

verify_dpkg_integrity.sh
# Query the package manager to determine if the script belongs to a legitimate package
# Run this on a live system or via a chroot environment
dpkg -S /etc/init.d/suspicious_script
# If the output is "dpkg-query: no path found matching pattern", the file is UNVERIFIED and highly suspicious.