Friday, December 21, 2007

chmod "+s"

Purpose of this blog is to just break this loooog Sannata mode. Many people might be aware of this, but for those who dont know can read.

We all know the basic file access permissions on linux. Access permissions can be set per file for owner, group and others on the basis of read (r), write (w) and execute permissions (x).

Linux processes run under a user-ID. The effective user-ID is the one that determines the access to files. So we can set user or group ID on execution using chmod command with 's' bit


>chmod 4755 suidtest
or
>chmod u+s suidtest


This causes the file to be executed under the user-ID of the user that owns the file rather than the user that executes the file. Same thing is applicable for group ID.


As you can see this is a very powerful feature especially if root owns the file with s-bit set. Any user can then do things that normally only root can do. A few words on security. When you write a SUID program then you must make sure that it can only be used for the purpose that you intended it to be used. Always set the path to a hard-coded value. Never rely on environment variables or functions that use environment variables. Never trust user input (config files, command line arguments....). Check user input byte for byte and compare it with values that you consider valid.


Here is the sample program with output.

1)

#!/bin/sh

#suid.sh: Print user information

echo " effective user-ID:"

id -un

echo " real user-ID:"

id -unr

echo " group ID:"

id -gn


2)

/*suid.c*/

#include

#include

int main(){

/*secure SUID programs MUST

*not trust any user input or environment variable!! */


char *env[]={"PATH=/bin:/usr/bin",NULL};

char prog[]="/tmp/suid.sh";

if (access(prog,X_OK)){

fprintf(stderr,"ERROR: %s not executable\n",prog);

exit(1);

}

printf("running now %s ...\n",prog);

setreuid(geteuid(),geteuid());

execle(prog,(const char*)NULL,env);

perror("suid");


return(1);

}


Now, with root user do

'gcc -Wall suid.c'

'chmod u+s a.out'


Here is the output

vinitd@orchid:/tmp> whoami

vinitd

vinitd@orchid:/tmp> ./a.out

running now /tmp/suid.sh ...

effective user-ID:

root

real user-ID:

root

group ID:

users

vinitd@orchid:/tmp>


--Note: It is possible to switch off Suid when mounting a file system. If you find the option "nosuid" in /etc/fstab then this Suid feature is switched off. For details have a look at the man-page of mount.