[Tfug] Scripting Question
Choprboy
choprboy at dakotacom.net
Sat Apr 18 03:12:13 MST 2009
On Saturday 18 April 2009 00:52, Charles R. Kiss wrote:
> If I'm a superlazy user and want a keyboard shortcut to run a pair of
> scripts that contain commands that require the superuser's priveleges,
> what's a safe way to do that? For example, a script that is only
> executable, not readable or writeable, and contains commands such as mount
> but is able to run via a user who is not root. Or is this a super
> horrible idea for some reason?
>
> I don't want to have to login in as superuser, I don't want to have to
> enter a password, or sudo, etc.
>
Well... "the safe way" is all relative. And you are really asking for 2
things; a script to run that you don;t have to be superuser to use and a
keybinding to run that script.
The first is fairly easy. However, you can not have something executable
without being readable (directories excepted), in order to execute it your
must have permission to read and interpret it. You can do this by creating
your script to perform the action, changing the ownership to root, and then
applying the "set user ID" flag on the permissions, "chmod 4755 script.sh"
-rwsr-xr-x 1 root root 123 Apr 1 script.sh
The "set user ID" causes the file to be executed with the permissions of the
owner. No here is the hard part... it executes as the owner of the file, but
uses your environment. That means, to make it "safe", you must properly
sanitize any inputs it accepts and you must ensure the user's environment
doesn't corrupt what you expect.
So what does that mean... Well, lets say you write script that takes two
arguments, filenames <file1> and <file2>, that are to be copied from one to
another as root (do to permission issues):
#!/bin/bash
# script.sh - A SUID script to copy <file1> to <file2>
cp -f $1 $2
[user at acme data]$ ls -al
drwxr-xr-x 7 root root 4096 Apr 1 12:34 .
drwxr-xr-x 7 root root 4096 Apr 1 12:34 ..
-rw------- 1 root root 734 Apr 1 12:34 file1
-rw------- 1 root root 132 Apr 1 12:34 file2
-rwsr-xr-x 1 root root 76 Apr 1 12:34 script.sh
Now we execute the SUID script as a normal user, ordinarily a we could not
copy file1 to file2 as we do not own the files or have write permission on
the directory, but the script is SUID "root" so it executes with root's
permissions:
[user at acme data]$ ./script.sh file1 file2
[user at acme data]$ ls -al file*
drwxr-xr-x 7 root root 4096 Apr 1 15:22 .
drwxr-xr-x 7 root root 4096 Apr 1 12:34 ..
-rw------- 1 root root 734 Apr 1 12:34 file1
-rw------- 1 root root 734 Apr 1 15:22 file2
-rwsr-xr-x 1 root root 76 Apr 1 12:34 script.sh
All looks good right? You gave a script to execute a command that normally
takes root permission. Now the problem... your inputs are unsanitized, what
if I had executed:
[evil at acme data]$ ./script.sh "file1 file2; passwd root" ";echo 'p0Wnzd'"
That gets expanded within the script and run as root:
cp -f file1 file2; passwd root ;echo 'p0Wnz3RD'
And an evil user has just changed root's passwd. So, you say you just won't
accept inputs? You will hardcode the copy arguments "cp -f file1 file2"? That
doesn;t fix the environment. As evil user I could write my own evil script
named "cp" in "/home/evil/scripts" and then execute:
[evil at acme data]$ EXPORT PATH=/home/evil/scripts
[evil at acme data]$ ./script.sh file1 file2
The SUID script now executes my script named "cp" as root, because that is
what is found in the path....
OK... so now we are going to thoroughly sanitize inputs and we are going to
make sure we are using the system executable, not something found in the
environment.
#!/bin/bash
# script.sh - A SUID script to copy <file1> to <file2>
/bin/cp -f /data/file1 /data/file2
That starts to resemble something "safe". If your need some very specific
repeatable task it may be fairly easy:
#!/bin/bash
# script.sh - Mount and copy backup data
/bin/mount /dev/sdb1 /backup_drive && /bin/cp -r /data/backup /disk1
&& /bin/umount /backup_drive
If you want to allow the user to specific source/dest/etc., then it gets a bit
more challenging.
As for the binding a key to an action, that can be done as well. How that
works depends on what environment you apply it (i.e. in a console shell, on
the terminal, or in KDE/Gnome/etc.). I will leave that explanation to someone
who has actually done that before.
Adrian
More information about the tfug
mailing list