Sudo Rsync and a Backup Job You Cannot Break
You have a shell as svc-backup on a CentOS 7 host. sudo -l shows (root) NOPASSWD: /usr/bin/rsync and nothing else. A root cron job runs rsync -a /var/www/ /backup/www/ every 10 minutes. The host is monitored by auditd, and the blue team alerts on new root processes and on writes to /etc/sudoers and /etc/shadow. You need root to read a root-owned TLS private key in /etc/pki/tls/private/, and you must not disrupt the backup job. You cannot reboot. rsync is version 3.1.2.
1. Explain how to use the sudo rsync rule to run a command as root and why it works despite the command restriction.
Read the worked answer
The sudoers rule authorizes /usr/bin/rsync but does not restrict arguments. rsync supports --checkpoint and --checkpoint-action=exec=COMMAND, which executes an arbitrary command when a checkpoint is reached. Because rsync is running as root under sudo, the command runs as root.
A minimal invocation that does not touch the production backup:
sudo rsync -a --checkpoint=1 --checkpoint-action=exec='/bin/sh -c "cp /etc/pki/tls/private/server.key /var/www/.k; chmod 644 /var/www/.k"' /var/www/ /tmp/rsync-test/
Why this works: sudo matches the program path, not the option set. The checkpoint action is a legitimate rsync feature, so the process does not look like a shell launched directly from sudo. The -a copy is small if you use a test source/destination, and the actual command execution is the checkpoint action.
The judgement is to avoid writing to /etc/sudoers or /etc/shadow, which the blue team explicitly alerts on. Copying the key into the web root lets you retrieve it over HTTP and avoids a suspicious cat of the private key.
2. What detection does this produce, and how do you reduce it while still reading the key?
Read the worked answer
Detections:
- A new root process:
sudo rsyncis logged by auditd, and the blue team alerts on new root processes. You cannot avoid a sudo event, but you can make it look like part of the normal backup cadence by running it near the cron window and using the same source/destination structure. - File integrity monitoring on
/var/wwwmay catch the new hidden file. If FIM covers the web root, write the key to a directory the web server already writes to, or to a path that rsync itself creates during the backup. - The private key file is likely covered by FIM. Reading it via a copy changes its access time but not its contents; copying is still the least noisy way to get the material.
Reduction:
- Do not write to
/tmpwith a world-readable name; use a path that matches the application's normal file patterns. - Retrieve the key immediately and remove the copy in the same rsync invocation using
--checkpoint-action=execto run a second command, so the file exists only briefly. - Avoid invoking a shell interactively; a single rsync process with a checkpoint action is less visible than
sudo rsyncfollowed by an interactive root shell.
The tradeoff is that any sudo invocation is logged. The judgement is to accept one root-process event rather than trigger the specific high-severity alerts on sudoers and shadow writes.
3. If the sudoers rule were restricted to `/usr/bin/rsync --server`, how would your approach change?
Read the worked answer
With an argument-restricted rule, sudo matches the exact command line, so you cannot add --checkpoint-action or -e. The checkpoint-action path is closed.
You would then look for a way to abuse the allowed --server mode. rsync --server is the remote-side protocol handler and is normally driven by a peer over a socket; it does not by itself give arbitrary command execution. The realistic options are:
- Find another sudo entry or a writable file used by the root cron job and use the cron path instead of sudo.
- If the rule allows
--serverplus specific options, determine whether any of those options permit file writes into a root-executed path, such as a script or cron file under/etc/cron.d. - If neither is possible, do not force the rsync path; pivot to the application or another host and return with a different privilege-escalation vector.
The judgement is that an argument-restricted sudo rule is a different vulnerability class from an unrestricted one. Testing the exact allowed argument set with sudo -l and a benign invocation is the first step; assuming the checkpoint trick still works would waste the window and generate a failed sudo alert.