hi
I am moving old files by using the following script :
find /home/-type f -atime +10 | \
while read file
do
mv $file /tmp/old
done
The script must also track the size of the directory it is creating and stop and create a
new directory when the size is some value (e.g. the size of a CD-ROM - 50MB (to allow for the
directories)) and size limit can be easily changed.
How can I do that?
What if I would tell you that if you run that script with root and you allow other users on your machine they could move ANY file on your machine to /tmp/old ?
# find . -type f | while read file; do echo mv $file /tmp/old; done
mv ./unix/ ../etc/passwd /tmp/old
#
As you can see, I was able to mv ../etc/passwd to /tmp/old. Now an attacker could use ".." or "." or even nothing depending on which directory the script was executed.
As to your question, use du to see the size of the directory and please be careful with your scripts.
What redoutable is saying -
Running as root you could have your /etc/passwd file or the shadow file
wind up in a publically readable directory. Then a simple dictionary attack, which might take some time, would give the bad guys access to everything on your machine.
FWIW - an attacker would have to be able to see what you are doing to exploit it. But.
Your best bet is not to move files around willy-nilly when you are a privileged user, unless you are sure about what file you are moving where.
And I don't know a simple workaround. Other than creating a non-priv user with multiple group membership - then newgrp to the correct group to play with the files. Someone else does know a good one, I'm sure.
Mcnamara a simple workaround is just to use ' " ' in the $file variable.
The actual problem here is that an attacker could trick the script into parsing three (old file and injected path and /tmp/old) or more parameters to "mv" instead of the disered two (old file and /tmp/old). That could be done simply by adding a space to a file name thus braking the $file variable into two arguments to "mv" instead of one.
Wrong vulnerable script with three arguments:
mv file ../etc/shadow /tmp/old
Ok script with two arguments:
mv "file ../etc/shadow" /tmp/old
This is actually more serious than it looks because the error is generally done with "rm -rf" instead of "mv" (in cron entries) and enables attackers to wreck beyond all repair any system by removing/moving critical files. Furthermore the system administrator would never be able to detect why the system is losing those critical files because the error is very subtle and lots of money would be spent restoring those machines.
Actually, to be perfectly precise, it's xargs -0 which is the key there. File names cannot contain a null byte because it's the terminator character of the underlying string encoding convention. find -print0 uses that to unambiguously output filenames with (otherwise) arbitrary character data in them, and xargs -0 conveniently knows how to handle that. Even more conveniently, the stream of null-terminated file names from find can be passed as is to exec by xargs without any additional translation or fiddling.
Yeah in other words instead of using a whitespace as a terminating char in the output it does it right by using the proper '\0' (null byte).
So if no -print0 is used the output could be "output1/ output2/output2\n\0" and then a second program that uses that output would break it into two arguments (using whitespace as a separating reference). In the other hand, if -print0 is used then the output would be "output1/ output2/output2\0" and then xargs -0 (the second program) instead of using whitespace as a separating reference uses '\0' thus considering that output has a single argument.
Unfortunately I think the every-day bash programmer wouldn't understand this very easily. More manual information is needed.
Actually, xargs without -0 breaks up input on newlines, but that's still a vulnerability because you can create a file called /tmp/(newline)/etc/passwd
If by "everyday" you mean people who fail to double-quote variables which might contain whitespace then yes, this is probably way beyond their grasp. But surely, nobody who reads this forum on a regular basis would still be doing that? (Ha ha only serious.)
What I meant was that the "everyday" bash programmer wouldn't understand the importance of using '\0' as a reference instead of '\n'. Someone who reads this forum on a regular basis would have an alias like "do_find_thingy" that would totally anticipate every aspect of every problem find might oppose (eheh - not).