OSEP study materials
OSEP study resources

Sudo Rsync and a Backup Job You Cannot Break

OSEP · Put your knowledge to work in context.

All case studies

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 rsync is 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/www may 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 /tmp with 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=exec to 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 rsync followed 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 --server plus 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.