6

In the description of the -K (--keep-dirlinks) flag, the rsync man page gives this warning (my emphasis):

One note of caution: if you use --keep-dirlinks, you must trust all the symlinks in the copy! If it is possible for an untrusted user to create their own symlink to any directory, the user could then (on a subsequent copy) replace the symlink with a real directory and affect the content of whatever directory the symlink references. For backup copies, you are better off using something like a bind mount instead of a symlink to modify your receiving hierarchy.

I've read the highlighted sentence several times, and I still cannot picture the exploit it refers to.

Could someone give a fleshed out example of the exploit? (Please include an explaination of how a "bind mount" avoids the problem.)


FWIW, this is my understanding of what the -K option does.

For example, if the initial state is this:

sender:/path/to/sourcedir
└── foo/
    └── file

receiver:/path/to/targetdir
├── bar/
│   └── stuff
└── foo@ -> bar/

Then, after rsync sender:/path/to/sourcedir/ receiver:/path/to/targetdir, the receiver will look like this:

receiver:/path/to/targetdir
├── bar/
│   └── stuff
└── foo/
    └── file

(Note that foo is no longer a symlink.)

After rsync -K sender:/path/to/sourcedir/ receiver:/path/to/targetdir, on the other hand, it will look like this:

receiver:/path/to/targetdir
├── bar/
│   ├── file
│   └── stuff
└── foo@ -> bar/
kjo
  • 1,043
  • 2
  • 9
  • 15

2 Answers2

4

You are correct on the use of the -K option. But the exploit is about having different users performing the link creation and running rsync. Let's first see some rsync -K in action. Make some test dirs:

[me] $ mkdir a b c b/from b/from/mydir c/to
[me] $ touch a/bar
[me] $ touch b/from/mydir/foo

And run the plain rsync

[me] $ rsync -avK b/from/ c/to
sending incremental file list
./
mydir/
mydir/foo

sent 135 bytes  received 39 bytes  348.00 bytes/sec
total size is 0  speedup is 0.00
[me] $ find c/to/
c/to/
c/to/mydir
c/to/mydir/foo

And let's clean c before a new test:

[me] $ rm -rf c/to
[me] $ mkdir c/to

Now, imagine that I give some other user the rights to write into c/to and b/from. To make things simple let's say that the following chgrp will allow a bunch of people to write in there:

[me] $ chgrp -R students c/to b/from

And a clever student performs this:

[student] $ ln -s ../../a c/to/student_dir
[student] $ mkdir b/from/student_dir
[student] $ echo 1337 > b/from/student_dir/bar

The next morning I run rsync and:

[me] $ rsync -avK b/from/ c/to/
sending incremental file list
./
student_dir/
student_dir/bar

Ouch! My file inside a that I never gave permission to anyone to modify has changed:

[me] $ cat a/bar
1337

And, since rsync is commonly used for repetitive tasks such as cron jobs there is a good chance that this would even go unnoticed.

In simple words the exploit can be argued to be that: a user that has access to the sender (from) and receiver (to) sides of a recurrent rsync job acquires the privileges of the user running the rsync job.

Don't run rsync -K as root!

grochmal
  • 5,677
  • 2
  • 19
  • 30
4

Here's a possible attack. Start with this on sender:

sender:/path/to/sourcedir
└── foo@ -> /etc/

Run the rsync once and get this:

receiver:/path/to/targetdir
└── foo@ -> /etc/

Now change sender to have this:

sender:/path/to/sourcedir
└── foo/
    └── passwd

Now when the rsync runs again, /etc/passwd will get overwritten on receiver.

Bind mounts prevent this attack because rsync will always write through them but will never create them.

  • Wow that was a less than 10 seconds difference in answers :) . Yeah, that's pretty much it (+1). Can be very dangerous to run as a user that can overwrite /etc/passwd – grochmal Mar 15 '17 at 01:34