Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
By krishvij at 2005-05-04 01:30
There has always been a void in every newbies mind when it comes to sticky bits. The books say that the SUID allows an unprivileged user to run executables and scripts with the credentials of the owner of the file. But we all try to implement it and fail as newbies. This HOWTO is dedicated to newbies of sticky bit so that they don't have to waste time in implementing it. The answer is right here.
I am taking an example of a huge organization with 1 Sysadmin who has under him/her a few Assistant Admins. In such cases, the sysadmin cannot be creating users all the time. So, the Assistant Admins do the user creation. But, to create users, the root password needs to be given to them, which is a big headache for the main Sysadmin. So, what does the sysadmin do? He/She will need to do the following :-
1. Login as root.
2. Create a shell script that will create the users specified and set a default password for each of these users
3. Copy this script to the home directory of these assistant admins.
4. Set SUID Sticky bit to the script copied in each of the assistant admins' directories
5. Copy the sysadmin commands that will be used by your script to /bin (because most of the sysadmin commands are in the /usr/sbin directory and unprivileged users' PATH does not point to /usr/sbin)
6. Set SUID to each and every command that you copy into the bin as well (my script uses the useradd, chown and chpasswd commands)
My example shell script that creates users and sets default password for each user is as follows :-
--------------------------------------------------------------------------------------------------------------------------
echo -n "enter the starting login id : "
read beg
echo -n "enter the ending login id : "
read final
fend=`date +"%d%m%y"`
i=$beg
rm -f "users$fend"
touch "users$fend"
while [ $i -le $final ];
do
if [ $i -lt 10 ]; then
useradd "j2ee00$i"
chown -R "j2ee00$i:j2ee00$i" "/home/j2ee00$i"
echo "j2ee00$i:elmaqedu" >> "users$fend"
fi
if [ $i -ge 10 ] && [ $i -lt 100 ]; then
useradd "j2ee0$i"
chown -R "j2ee0$i:j2ee0$i" "/home/j2ee0$i"
echo "j2ee0$i:elmaqedu" >> "users$fend"
fi
if [ $i -ge 100 ] && [ $i -lt 1000 ]; then
useradd "j2ee$i"
chown -R "j2ee$i:j2ee$i" "/home/j2ee$i"
echo "j2ee$i:elmaqedu" >> "users$fend"
fi
i=$[ $i + 1 ]
done
chpasswd < "users$fend"
--------------------------------------------------------------------------------------------------------------------------
Save this script as addusers.sh
copy this script to the directories of each assistant admin. once you have copied the script, set SUID to this file using the following command :-
chmod 4755 addusers.sh
(or)
chmod u+s addusers.sh
copy the useradd and chpasswd scripts to /bin and then, issue the following commands to set the SUID to these files :-
THAT'S IT. IT'S ALL DONE. Now, login as any of the assistant admins and execute the addusers.sh script. The unprivileged users will be added to the /etc/passwd file
EXPLANATION
---------------------
When an unprivileged user logs into Linux, his uid and gid are embedded into his shell. From this point on, any command or script that you run forks a child shell process. Remember, every process runs with the uid and gid of the currently logged on user and hence, unprivileged users cannot write to files like /etc/passwd. Hence, SUID is actually a way in which the sysadmin can create scripts to be run by unprivileged users but still need some root like access to some system files.
once the SUID sticky bit is set on an executable created by root, the following happens :-
1. unprivileged user with uid 501 and gid 501 logs on.
2. executes a script which has SUID set.
3. Script creates a child shell process and sets it's uid and gid to 0 (the root)
4. Performs all that it needs to do and then exits
If the same unprivileged user tries to run a script without SUID set, the process will run with uid 501 and gid 501 and hence, will not have permissions to perform desired actions on system centric files, even though the sysadmin would want it to.
Hope this HOWTO helps people out there. In case you have any suggestions or feedback, please mail me at vijaykrishnan@elmaqedu.com
Um, please do correct me if im wrong, as this is confusing me severely..
We fisr make the script, and suid it, yes, that I can understand. The thing is, why do the commands used have to be suid too?
exec suid script > child process with uid 0 > exec the commands as uid 0
So why are the tools suid too? A thought comes to mind, that now that the tools are suid, any user can use adduser and so on with the suid binaries?
What am I getting wrong here? (:
by krishvij on Thu, 2005-06-16 03:23
Hi Artanicus,
Thanks for your comment. Would like to clarify a few things here. What I have used is just an example to understand the concept of SUID. It is not to be taken as is and applied onto the production systems. Basic idea is to make people understand the concept of SUID.
One part of what you have said is right. If you apply whatever I have said in my example as is, then yes, anyone and everyone can use the suid'd useradd, chpasswd etc without being root. This is actually a security loophole. so, probably u can just copy these binaries into the home directories of each user who needs to use it and make them as SUID instead of making the /usr/bin binaries as SUID. Further, the same things can also be done by using sudo in a more secure way.
With regard to your query of a process execing another one, the same UID's do not pass on.That means, if adduser.sh is suid'd as root, then it will run as UID 0. But, if it calls useradd and if useradd is not suid'd, then useradd will take the UID of the user and so, it will not be able to write to the /etc/passwd file. Just try out the same example by setting SUID for just the adduser.sh and then execute. You will find that the users will not be added. Of course, login as an unpreviliged user and try it out :-)
by Artanicus on Thu, 2005-06-16 03:40
Thanks this clarified alot.. (:
Only one question remains, why suid the script in the first place if the only real root tools we are using are suid too? Can't the script run suid binaries if it isn't suid itself?
Sorry for the troublesome questions, but your great article confused me a tad, but on some level I now understand how suid works, thanks for that.. (:
by krishvij on Thu, 2005-06-16 06:41
Hi Artanicus,
There is no need for the adduser.sh to be suid'd. Guess I got a little bit carried away while writing this article :-). It is not necessary for adduser.sh in my example to be suid'd. It will still work. Good to note that the info helped you. That gives me a lot of satisfaction and also, makes me believe that the effort I spent on writing that article was worth it.
by oriate on Fri, 2005-06-17 07:13
Hi,krishvij,
As you said,such a program cannot get a root shell:
#include <unistd.h>
I tried, yes, I cannot get root shell, but how do buffer flow get root shell using suid ?
Thx
by krishvij on Sat, 2005-06-18 00:33
every process is just a running instance of a program. it needs to have a UID/GID (just like an ID card) while running so that the OS can decide what the process can access and what it can't.
in unix/linux, when a user executes a program, the OS checks if it has a SUID/SGID set on it. If it is set, then it looks at the owner/group owner of the program, gets the corresponding UID/GID and then, runs the process with these UID/GID. Otherwise, it starts the process by exporting the logged in user's UID/GID.
by oriate on Sat, 2005-06-18 06:43
Can you explain how "buffer flow" get the root shell?
Thx
by donald.j.wood on Tue, 2005-06-21 14:36
There is a big problem with this example beyond the fact that SUID is not required. SUID/SGID is considered insecure, and as such the Linux kernel ignores the bit when running shell scripts.
by oriate on Tue, 2005-06-21 22:49
Quote:
Originally posted by donald.j.wood There is a big problem with this example beyond the fact that SUID is not required. SUID/SGID is considered insecure, and as such the Linux kernel ignores the bit when running shell scripts.
I am sorry, I cannot much understad you.
"shell scripts" do you mean "shell code" ?
But how does the kernel know whether a piece of code is shell code?
by Michael Slade on Sat, 2009-02-28 08:38
This post demonstrates a clear misunderstanding of setuid and it security implications. If followed, the directions given will allow any user with local access to the machine, to change the password of any other user, including root. Thus it essentially disables all security.
When most programs have their setuid bit set, they will execute as the owner of the program file rather than the executing user. The exceptions are scripts - basically any programs whose first line starts with "#!".
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
We fisr make the script, and suid it, yes, that I can understand. The thing is, why do the commands used have to be suid too?
exec suid script > child process with uid 0 > exec the commands as uid 0
So why are the tools suid too? A thought comes to mind, that now that the tools are suid, any user can use adduser and so on with the suid binaries?
What am I getting wrong here? (:
Thanks for your comment. Would like to clarify a few things here. What I have used is just an example to understand the concept of SUID. It is not to be taken as is and applied onto the production systems. Basic idea is to make people understand the concept of SUID.
One part of what you have said is right. If you apply whatever I have said in my example as is, then yes, anyone and everyone can use the suid'd useradd, chpasswd etc without being root. This is actually a security loophole. so, probably u can just copy these binaries into the home directories of each user who needs to use it and make them as SUID instead of making the /usr/bin binaries as SUID. Further, the same things can also be done by using sudo in a more secure way.
With regard to your query of a process execing another one, the same UID's do not pass on.That means, if adduser.sh is suid'd as root, then it will run as UID 0. But, if it calls useradd and if useradd is not suid'd, then useradd will take the UID of the user and so, it will not be able to write to the /etc/passwd file. Just try out the same example by setting SUID for just the adduser.sh and then execute. You will find that the users will not be added. Of course, login as an unpreviliged user and try it out :-)
Only one question remains, why suid the script in the first place if the only real root tools we are using are suid too? Can't the script run suid binaries if it isn't suid itself?
Sorry for the troublesome questions, but your great article confused me a tad, but on some level I now understand how suid works, thanks for that.. (:
There is no need for the adduser.sh to be suid'd. Guess I got a little bit carried away while writing this article :-). It is not necessary for adduser.sh in my example to be suid'd. It will still work. Good to note that the info helped you. That gives me a lot of satisfaction and also, makes me believe that the effort I spent on writing that article was worth it.
As you said,such a program cannot get a root shell:
#include <unistd.h>
int main()
{
char *name[2];
name[0] = "/bin/sh";
name[1] = 0;
execve(name[0],name,0);
}
I tried, yes, I cannot get root shell, but how do buffer flow get root shell using suid ?
Thx
in unix/linux, when a user executes a program, the OS checks if it has a SUID/SGID set on it. If it is set, then it looks at the owner/group owner of the program, gets the corresponding UID/GID and then, runs the process with these UID/GID. Otherwise, it starts the process by exporting the logged in user's UID/GID.
Thx
There is a big problem with this example beyond the fact that SUID is not required. SUID/SGID is considered insecure, and as such the Linux kernel ignores the bit when running shell scripts.
"shell scripts" do you mean "shell code" ?
But how does the kernel know whether a piece of code is shell code?
When most programs have their setuid bit set, they will execute as the owner of the program file rather than the executing user. The exceptions are scripts - basically any programs whose first line starts with "#!".
I won't explain further than this, but please see http://en.wikipedia.org/wiki/Setuid if you want to know more.
Mick.