29

I want to ensure that my program can only be run by user xyz using root privilege. To do this, I set the setuid bit with:

chmod u+s program1.sh
ls -l program1.sh
rwsr-x--- 1 root house 1299 May 15 23:54 program1.sh

Also, I added user xyz to the house group so that only xyz and root can run program1.sh.

In program1.sh there is

id -u

so that it can show me the effective ID.

Running program1.sh as root, it shows root. But running with the xyz account, it shows xyz. It seems that it didn't run with root privilege. I don't know what's wrong here.

Thomas Dickey
  • 76,765

1 Answers1

60

When executing shell scripts that have the setuid bit (e.g., perms of rwsr-xr-x), the scripts run as the user that executes them, not as the user that owns them. This is contrary to how setuid is handled for binaries (e.g., /usr/bin/passwd), which run as the user that owns them, regardless of which user executes them.

Check this page: https://access.redhat.com/site/solutions/124693

This is a security measure taken by operating system. You should use your script with sudo instead.

If you really need to use setuid o your script you can create a binary that will do the work. Create a new file “program.c” and copy the following code:

   #include <stdio.h>
   #include <stdlib.h>
   #include <sys/types.h>
   #include <unistd.h>

   int main()
   {
     setuid(0);
     system("./program.sh"); #This line is dangerous: It allows an attacker to execute arbitrary code on your machine (even by accident).
     return 0;
   }

Compile and execute the code using the following commands:

$ gcc program.c -o program
$ sudo chown root.root program
$ sudo chmod 4755 program
$ ./program

This way it will work. The setuid works for compiled file, and this file can execute others files as root.

cioby23
  • 3,319
  • 1
    great information – Marcus Thornton May 26 '14 at 09:47
  • 1
    It's a beautiful thing! – ElasticThoughts Dec 21 '17 at 12:59
  • Related: https://unix.stackexchange.com/questions/364/allow-setuid-on-shell-scripts https://unix.stackexchange.com/questions/166817/using-the-setuid-bit-properly – phyatt Mar 15 '18 at 18:47
  • Great hack! You saved my afternoon :) – Vicente Bolea Jul 26 '18 at 07:18
  • 5
    Please note, that this solution is dangerous, as long as the user can edit or replace ./program.sh. This would enable every user who can execute program to run arbitrary code as the user who owns program. From my point of view, a safer solution would be to port the code from ./program.sh directly into C code and add it to program.c. – tones Nov 06 '18 at 12:17
  • 1
    Great hack indeed, which allows ANY USER to run ANY COMMAND as root –  Mar 21 '20 at 18:43
  • Please note, that this solution is dangerous, a user does not even have to replace ./program.sh. This would enable every user who can execute program to run arbitrary code as the user who owns program. It runs ./program.sh in the present working directory. – ctrl-alt-delor Feb 07 '21 at 10:43
  • @VicenteBolea The code is dangerous. It allows execution of arbitrary code: make an executable program.sh is any directory. Then run Path/to/that/program. – ctrl-alt-delor Feb 07 '21 at 10:47
  • @ElasticThoughts The code is dangerous. It allows execution of arbitrary code: make an executable program.sh is any directory. Then run Path/to/that/program. – ctrl-alt-delor Feb 07 '21 at 10:48
  • @MarcusThornton The code is dangerous. It allows execution of arbitrary code: make an executable program.sh is any directory. Then run Path/to/that/program. – ctrl-alt-delor Feb 07 '21 at 10:48
  • The link to redhat site is broken. – mathway Jan 31 '22 at 16:53
  • So essentially, setting set-id is useless when executable shell scripts is executed directly? – Akhil Raj May 16 '22 at 00:41