LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   What is really SUID? (https://www.linuxquestions.org/questions/linux-newbie-8/what-is-really-suid-4175486045/)

Madhu Desai 11-27-2013 08:12 AM

What is really SUID?
 
Hi Everybody

I've some issue with SUID. Until now, i thought i'm comfortable with the understanding of SUID/SGID/Sticky Bit. Infact, i have explained (theoretically) so many people about them - How to set/check SUID/SGID/Sticky. I've always explained SUID as

"The Set-User-ID bit is used to execute a file with its owner permissions, not with the user-who-launch-the-executable permissions as it is with classic permissions set."

...and gave example of /usr/bin/passwd file.

I've applied Sticky bit many a times since from time to time I've to create a shared folder for some project or other. But i've never used SUID/SGID.

But today, one of my colleague asked me to explain SUID (practically), and boy it was a spectacular fail. Hmmm i thought i knew it.

Anyway, following are the steps i tried to explain him about SUID, similar to passwd/shadow example.

The idea is to create a text file as root which has no permissions, and hence cannot be read/written to from regular users. And then, create a script as root, which can edit that text file. Give that script SUID permission, so that regular users can write to the text file through script only and hence they cannot read/write to text file directly.

Following steps should be self explanatory:

1. As root, create text & script file, give permissions and add some data:

Code:

# touch /etc/mydata.txt

# chmod 000 /etc/mydata.txt

# ls -l /etc/mydata.txt /etc/shadow
----------. 1 root root    0 Nov 27 01:43 /etc/mydata.txt
----------. 1 root root 1044 Nov 26 12:49 /etc/shadow


# cat > /bin/addit
#!/bin/bash
printf "$1\t$2\n" >> /etc/mydata.txt
^D


# chmod 4755 /bin/addit

# ls -l /bin/addit /usr/bin/passwd
-rwsr-xr-x. 1 root root    49 Nov 27 01:45 /bin/addit
-rwsr-xr-x. 1 root root 32200 Jan 28  2010 /usr/bin/passwd


# addit Redhat Linux
# addit Solaris Unix

# cat /etc/mydata.txt
Redhat        Linux
Solaris        Unix

2. As regular user, try adding records
Code:

# su - dummy

$ addit Vista Windows
/bin/addit: line 2: /etc/mydata.txt: Permission denied

$ ls -l /bin/addit
-rwsr-xr-x. 1 root root 49 Nov 27 01:45 /bin/addit

Why i'm not able to add records using addit script even-though i have given SUID bit? Isn't it the purpose of SUID - run-as-root-user, and hence write to mydata.txt file.

Did i get the whole concept of SUID wrong, or is it just applied to built-in binaries only and not to user-made scripts.

Any light on this will be much appreciated.

Thanks

pan64 11-27-2013 08:38 AM

addit is a shell script, not a binary. The real running binary is /bin/bash, that will interpret and execute your script line by line.
Therefore you ought to set sticky bit on the interpreter, not on the script. I suggest you to copy bash to your home and use that one instead of the original (that one must not be altered).

Madhu Desai 11-27-2013 09:28 AM

Quote:

Originally Posted by pan64 (Post 5071432)
addit is a shell script, not a binary. The real running binary is /bin/bash, that will interpret and execute your script line by line.
Therefore you ought to set sticky bit on the interpreter, not on the script. I suggest you to copy bash to your home and use that one instead of the original (that one must not be altered).

Thanks for reply.

Since the assumption is 'addit' to be portable app, so instead of copying /bin/bash to user's directory, i converted addit script to binary.

Code:

# mv /bin/addit ~/addit.sh

# shc -v -e 20/12/2015 -m "Command expired" -r  -T  -f addit.sh
shc shll=bash
shc [-i]=-c
shc [-x]=exec '%s' "$@"
shc [-l]=
shc opts=
shc: cc  addit.sh.x.c -o addit.sh.x
addit.sh.x.c: In function 'chkenv':
addit.sh.x.c:211: warning: cast from pointer to integer of different size
shc: strip addit.sh.x
shc: chmod go-r addit.sh.x


# ls -l addit*
-rwxr-xr-x. 1 root root  49 Nov 27 20:32 addit.sh
-rwx--x--x. 1 root root 9216 Nov 27 20:48 addit.sh.x
-rw-r--r--. 1 root root 9579 Nov 27 20:48 addit.sh.x.c


# cp addit.sh.x /bin/addit

# chmod 4755 /bin/addit

# ls -l /bin/addit
-rwsr-xr-x. 1 root root 9216 Nov 27 20:50 /bin/addit

# file /bin/addit
/bin/addit: setuid ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

# file /usr/bin/passwd
/usr/bin/passwd: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

# su - dummy

$ addit Vista Windows
addit: line 1: /etc/mydata.txt: Permission denied

Still the same problem... :confused:

BrainReaper 11-27-2013 07:03 PM

I reproduced the problem. Even the SUIDed bash copy thing. Then I wrote a helloworld in C++.
Code:

#include <fstream>
using namespace std;

int main()
{
  ofstream fs("file");
  fs << "Hello world" << endl;
  fs.close();

  return 0;
}

Compile it as root and give SUID permission.
Touch file "file" with no write rights.
Execute helloworld as regular user and cat "file".

It works just fine so I conclude this is an issue of "in the name of who bash handles filedescriptors when pipelining".

rknichols 11-27-2013 07:35 PM

Quote:

Originally Posted by mddesai (Post 5071451)
Code:

# su - dummy

$ addit Vista Windows
addit: line 1: /etc/mydata.txt: Permission denied

Still the same problem... :confused:

If you were executing the compiled C program, where did the "line 1" in that error message come from? It would appear that you still have a script somewhere named "addit" and were executing that. What does "which addit" and "file $(which addit)", both executed as user "dummy", show? What happens if you use the full path, "/bin/addit Vista Windows"?

Madhu Desai 11-27-2013 11:50 PM

Quote:

Originally Posted by BrainReaper (Post 5071724)
It works just fine so I conclude this is an issue of "in the name of who bash handles filedescriptors when pipelining".

It is necessary that scripts get SUIDed as i and others are comfortable with scripting only. However, i will try other ways to write to text file, check it and get back to you. Thanks anyway.

Quote:

Originally Posted by rknichols (Post 5071729)
It would appear that you still have a script somewhere named "addit" and were executing that. What does "which addit" and "file $(which addit)", both executed as user "dummy", show? What happens if you use the full path, "/bin/addit Vista Windows"?

Code:

$ which addit
/bin/addit

$ file $(which addit)
/bin/addit: setuid ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

$ less /bin/addit
"/bin/addit" may be a binary file.  See it anyway? n

$ /bin/addit Vista Windows
/bin/addit: line 1: /etc/mydata.txt: Permission denied

:(

zhjim 11-28-2013 01:46 AM

As you are also aware of script files dont honor the suid bit thus you converted the bash script into an executable but maybe that still is the problem. I don't know how the internal works but maybe try to set bash suid to. And then run the addit again.

Madhu Desai 11-28-2013 04:18 AM

@zhjim

Gave SUID to /bin/bash, also ran /bin/bash directly.... Still no luck.

Code:

# chmod u+s /bin/bash

$ ls -l /bin/bash /bin/addit
-rwsr-xr-x. 1 root root  12928 Nov 27 20:50 /bin/addit
-rwsr-xr-x. 1 root root 938832 Jul 18 18:49 /bin/bash


$ /bin/addit Vista Windows
addit: line 1: /etc/mydata.txt: Permission denied

$ /bin/bash -c "/bin/addit Vista Windows"
/bin/addit: line 1: /etc/mydata.txt: Permission denied

Is there any other way to write to text files besides output redirection (> and >>)? Googled about it, cant find other way...

Next Step, i'll try to build RPM from script, then install that RPM package and then i'll try again. I'll see what happens. (But before that, i've to learn how to build rpm packages first...:p)

pan64 11-28-2013 05:53 AM

As I told you do not modify /bin/bash it will/may have unpredictable result. If you want to play with it just make a copy and use that one.

Madhu Desai 11-28-2013 06:16 AM

Quote:

Originally Posted by pan64 (Post 5071953)
As I told you do not modify /bin/bash it will/may have unpredictable result. If you want to play with it just make a copy and use that one.

OK Thanks.

Code:

$ ls -l /home/dummy/bash
-rwsr-xr-x. 1 dummy dummy 938832 Nov 28 17:40 /home/dummy/bash

$ /home/dummy/bash -c "/bin/addit Vista Windows"
/bin/addit: line 1: /etc/mydata.txt: Permission denied


zhjim 11-28-2013 06:46 AM

Could try with chowing to root and chmodding to 700. I had the case where I wanted to delete a directory for which I did not have write permission as a normal user. Also root may go well with what ever permission is set maybe suid works a bit different under the hood.

jpollard 11-28-2013 07:17 AM

It really depends on what you are trying to do.

There are two identifications involved: the real uid (the original), and the effective uid.

All the setuid flag does is change the effective uid to the owner of the binary. For many things (such as file access controls) this is more than sufficient.

SOME things do check the real UID as well. Those activities tend to want to verify that it really really is root doing something - so they check the real uid - which isn't root. The easiest way a program can determine if it is running setuid is to check that the real UID and effective UID are the same. For a user process, both of these are the same. For a root process they are also the same, but both are root.

The advantage of having the effective UID and real UID separate is that it allows a setuid program to drop privileges (file access) very easily - just set the effective UID to the real UID. The process is no longer privileged. It also partitions roots privileges - setuid can give processes file control access, but not device control. In UNIX systems this was more distinctly separated, but in Linux nearly any kernel control is available through a filesystem access (either sys, proc, devfs...) so that
partitioning is much weaker in Linux.

Madhu Desai 11-28-2013 08:16 AM

@jpollard

What i understand from you is that if only real/effective uid are same(root in this case), addit will be able to edit text file. Since uid of addit script will be Real=dummy, Effective=root and so addit cannot write to mydata.txt file which has no permission (or just root permission).

Now, the question is how to set real and effective uid to script?

man search gave these results:

Code:

# man -k set.*uid
nfs4_set_debug [nfs4_uid_to_name] (3)  - ID mapping routines used for NFSv4
setegid [seteuid]    (2)  - set effective user or group ID
seteuid              (2)  - set effective user or group ID
seteuid              (3p)  - set effective user ID
setfsuid            (2)  - set user identity used for file system checks
setregid [setreuid]  (2)  - set real and/or effective user or group ID
setresgid [setresuid] (2)  - set real, effective and saved user or group ID
setresuid            (2)  - set real, effective and saved user or group ID
setreuid            (2)  - set real and/or effective user or group ID
setreuid            (3p)  - set real and effective user IDs
setuid              (2)  - set user identity
setuid              (3p)  - set user ID

All i can see is (2) - System Calls and (3p) - C Library Functions POSIX. No (1) - User Commands and (8) - System Administration tools and Deamons. This means only binaries created in C/C++ with appropriate real/effective uid set can only be used for SUID/SGID. Bash scripts wont allow such options, so setting SUID/GUID to bash scripts is of no use...

rknichols 11-28-2013 09:02 AM

You are right that SUID/SGID on the file containing a script does not work. It has been disabled for a long time now due to many security issues. SUID/SGID should work on a compiled program, but make sure that the file system where you are doing these experiments has not been mounted with the "nosuid" option. You could still set the SUID permission bits there, but they would be ignored.

Madhu Desai 11-28-2013 11:04 PM

That cleared my problem. Thanks everybody.


All times are GMT -5. The time now is 03:24 PM.