Sponsored Content
Top Forums UNIX for Beginners Questions & Answers Answers to Frequently Asked Questions Tips and Tutorials The Whole Story on #! /usr/bin/ksh Post 302112883 by Perderabo on Saturday 31st of March 2007 11:09:51 PM
Old 04-01-2007
Part 3 -- SUID Shell Scripts

When executable shell scripts were first introduced they honored the suid bit. This was a disaster for security. Consider a script call /usr/sbin/disaster. And we did:
chown root /usr/sbin/disaster
chmod 4755 /usr/sbin/disaster
Naturally, /, /usr, /usr/sbin are only writable by root. And the script itself is just:
#! /bin/sh
That's right. The script is a single line with no hidden characters. The shell will ignore it because it is a comment and then exit because there are no other lines. This script is already insecure and is vulnerable to two different attacks.

Attack 1: link to -i

If we do:
ln -s /usr/sbin/disaster ./-i
and arrange to execute our new symbolic link called "-i". If we execute the real /usr/sbin/disaster, we do the equivalent of:
execl("/bin/sh", "/usr/sbin/disaster", "/usr/sbin/disaster", (char *) NULL)
No problem there. That is what we expected. But when we run copy special link called "-i" we do:
execl("/bin/sh", "-i", "-i", (char *) NULL)
This causes the suid shell to behave as an interactive shell! The shell was quickly modified to accept a single hyphen as the end of switch setting arguments. So we modify our one line script to read:
#! /bin/sh -
Now the same trick would result in:
execl("/bin/sh", "-i", "-", "-i", (char *) NULL)
Augument zero is still "-i", but this is harmless. It might even be considered useful because it makes this attack more noticable with the ps command.

Attack 2: changing the link

This one is harder to explain. As before, we make a symbolic link to the script under attack, but this time the name does not matter. Then we run the script via our new symbolic link. Then we quickly change the symbolic link to point to an evil script. We want to change what the symbolic link points to after the kernel opens it but before the interpreter opens it. This is a race condition and it will not work every time. It also requires a bit of clever programming to pull this one off. But done correctly, we will have our evil script running as root.

Suid Scripts Disabled

Because it was not possible to write a secure suid shell script, the concept of suid shell scripts was removed from Unix. Around this time the program sudo was written and this largely oviated the need for suid shell scripts. I don't believe any version of unix released in the past 15 years has these problems. (And if I did, I would not have discussed these attacks. Smilie) By now I hope you can see why many old time system admins (such as myself) still have a dim view of suid shell scripts.

The Return of Suid Scripts

Solaris now supports suid shell scripts but it is immune to these attacks. It does this by ensuring that the script is opened only once in the case of a suid script. If the suid bit is set, Solaris uses the fd filesystem to pass the script to the interpreter. Had my perlargs script been suid on Solaris, it would have been run something like:
execl("/usr/local/bin/perl", "/usr/local/bin/perl", "-w", "/dev/fd/3", "one", "two", "three", (char *) NULL)
and when perl opened /dev/fd/3, it just gets another open file descripter pointing to the same file as whatever has been opened as fd 3. Note that inside the script, there is no way to obtain the name other than /dev/fd/3.

Because the name used is concealed from the intrepreter, there is no harm if that name was something odd like "-i". Because the script is opened one time, there is no harm if a symbolic link is suddenly switched to an evil script.

But note that this finally gets us to a stage where a one line script containing only a comment can be safely run. There can still be other security problems with a poorly written suid script. If you must use suid shell scripts, here are a few tips:

1. Use ksh
Dave Korn analysed all of the attacks on shell scripts and closed as many holes as he could. In particular, ksh is immune to IFS based attacks. Also if it finds that it is going interactive with an effective uid of root together with a real uid which is not root, it will use its root authority to set the effective uid to the real uid prior to issuing a prompt.

2. Control PATH
Explicitly set your PATH variable as the first step in your script. Make the list of directories as short as possible. Do not start or end the list with a colon or have two consecutive colons. And do not put . or .. in the list. Explicitly export PATH. And ensure that every directory mentioned in PATH is writable only by root. For example, /usr/local/bin is on the PATH, then in addition to the obvious need for /usr/local/bin being non-writable, you also need to ensure that /, /usr, /usr/local are all not be writable. If /usr/local is a mounted filesystem, it must not be possible for a non-root user to arrange for /usr/local to be unmounted. You can further protect your script by relying on PATH as little as possible. So, for example, use "/usr/bin/rm" rather than just "rm".

Note: while I used /usr/local/bin as an example, I would strongly resist putting /usr/local/bin in the PATH of a suid script. Again: make the list of directories as short as possible. I would rarely go beyond "PATH=/usr/bin" in a suid script.

3. Control IFS
Set IFS to a space, a tab, and a newline. And then export IFS. While ksh is immune to the IFS attack, some other shells are not immune. Something you do in your script may indirectly invoke another shell.

4. Make sure that the script is not writable
Most versions of unix these days will remove the suid bit on a file as it is being written by a process owned by a user different than the owner of the file. But don't depend on that behavior.

5. Do not execute directly or indirectly any user supplied input
You must ensure that user input is never delivered to the shell to interpret as executable code. If you don't know how to ensure this, then you should not process any user input. Note that the parameters of the script must be considered user input.

6. Be careful if you invoke programs that solicit input from the user
Do not invoke programs that allow the user to execute arbitrary programs. For example, do not ask the user to vi a file. vi offers a way for the user to execute a subshell. Yes, ksh's built-in protection will protect you if the user invokes ksh interactively. But, unfortunately, other shells exist. And the user doesn't need an interactive shell with vi. A command like ":!rm /etc/passwd" will work from vi and this is not using an interactive shell.

These steps will go a long way toward securing any suid scripts you write, but I can't guarantee that they are enough to completely secure a script.
These 2 Users Gave Thanks to Perderabo For This Post:
 

8 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

#!/usr/bin/ksh Command Interpreter in a sh script

Hi, I have a developer that is trying to start a script with sh "scriptname". In the script, he is specifying #!/usr/bin/ksh as the command interpreter. For some reason sh is ignoring the #!/usr/bin/ksh. We are running Solaris 8. Does anyone have any ideas what could be causing this? Here... (3 Replies)
Discussion started by: ckeith79
3 Replies

2. UNIX for Dummies Questions & Answers

ksh: /usr/bin/ls: arg list too long

I am using IBM AIX unix version 4.3.3.0. In a directory there are many files with different patterns. When I am trying to execute the command, ls -l with the file pattern, which have fewer files it gives the desired result. However when I am trying to execute the same command for file pattern,... (2 Replies)
Discussion started by: jitindrabappa
2 Replies

3. Solaris

How do I link ld in /usr/ucb/ to /usr/ccs/bin?

Hi all, below is the problem details: ora10g@CNORACLE1>which ld /usr/ucb/ld ora10g@CNORACLE1>cd /usr/ccs/bin ora10g@CNORACLE1>ln -s /usr/ucb/ld ld ln: cannot create ld: File exists ora10g@CNORACLE1> how to link it to /usr/ccs/bin? (6 Replies)
Discussion started by: SmartAntz
6 Replies

4. Shell Programming and Scripting

!/usr/bin/ksh error

Usually we use !/usr/bin/ksh at the start of the script.But if I am having this stuff in the scripts and calling one script from other its not working.What may be the reason behind it ? xyz.ksh #!/usr/bin/ksh echo "Hi" abc.ksh #!/usr/bin/ksh echo "I am fine" ksh xyz.ksh Its... (4 Replies)
Discussion started by: dr46014
4 Replies

5. AIX

aix:ksh: /usr/bin/rm: 0403-027 The parameter list is too long.

Hi, I am getting the below error message When i am trying to delete the files from the directory.Could you please guide me? rm *.aud ksh: /usr/bin/rm: 0403-027 The parameter list is too long. and find /oracle/admin/testP/adump/*.aud -mtime +5 -exec rm {} \; ksh: /usr/bin/find:... (3 Replies)
Discussion started by: nokiae63
3 Replies

6. OS X (Apple)

When to use /Users/m/bin instead of /usr/local/bin (& whats the diff?)?

Q1. I understand that /usr/local/bin means I can install/uninstall stuff in here and have any chance of messing up my original system files or effecting any other users. I created this directory myself. But what about the directory I didn't create, namely /Users/m/bin? How is that directory... (1 Reply)
Discussion started by: michellepace
1 Replies

7. Shell Programming and Scripting

/usr/bin/ksh -E

I saw one script using the first line as below /usr/bin/ksh -E I have used -x for debug but couldn't find what is this -E option for ? Pls let me know what is this -E used for Thanks RL (1 Reply)
Discussion started by: reldb
1 Replies

8. BSD

FreeBSD: /usr/bin/ld not looking in /usr/local/lib

I'm not sure if this is the default behavior for the ld command, but it does not seem to be looking in /usr/local/lib for shared libraries. I was trying to compile the latest version of Kanatest from svn. The autorgen.sh script seems to exit without too much trouble: $ ./autogen.sh checking... (2 Replies)
Discussion started by: AntumDeluge
2 Replies
All times are GMT -4. The time now is 02:11 AM.
Unix & Linux Forums Content Copyright 1993-2022. All Rights Reserved.
Privacy Policy