[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