How to take away the 'execute' permission from the root user? - linux

I'm asked to take away the permission for the root user to execute a bash script, is that even possible? Actually how would one take away any permissions from some user? with chmod I could modify it for the current logged in user, but not for root.

If you are simply looking for a small safeguard, an obstacle to accidentally running the script as root, write the script to voluntarily exit if run as root. Add the following to the beginning of the script:
if [[ $EUID == 0 ]]; then
printf 'Do not run this script as root\n' >&2
exit 1
fi

You can't do that, root can do everything. But there are some measures to make it difficult. You can use the following command in ext{2-4} filesystems:
chattr +i script.sh
Doing this the file can't be modified, but it can be unlocked using chattr -i script.sh
Other thing you can do is: Put the script you want unchangeable for root on remote server and mount it via NFS. If the server does not offer write permissions that locks out the local root account. Of course the local root account could just copy the files over locally, unmount the remote stuff, put the copy in place and change that.
You cannot lock out root from deleting your files. If you cannot trust your root to keep files intact, you are having a social problem, not a technical one.

Related

How to keep run chmod when system boot up

#! /bin/sh
# Carry out specific functions when asked to by the system
case "$1" in
start)
chmod a+rwx /var/www/html/Images/*
echo "success"
;;
stop)
;;
*)
echo "Usage: /etc/init.d/image {start|stop}"
exit 1
;;
esac
Im using run levels to run my chmod when the system is boot up but it is only run once and how can i keep allow chmod to keep running when system is boot up? Anybody can help? i'm using ubuntu 16.04.
Don't use chmod in this way. In the long run it creates lots of pain and will turn your box into a worm pit. What you want to do there is a huge security no-go.
If you want users to be able to write to a certain location, use proper filesystem access rights. Create a new group for whoever shall be able to write to that directory, set its permissions to 1775 (owner and group rwx, others rx, sticky bit enabled) and set the directory owning group to the one created formerly. Then add all users that shall be able to write to that directory to this group.
Why don't you use a cronjob for that? You can set up this script (just the chmod line) to be run every minute...
Ubuntu CronHowto

Perl script can't open file owned by root when called from process (Nagios)

I have a VPS with Nagios installed, and I want to use Nagios to monitor the VPS resources in the /proc/user_beancounters file. The file has the following permissions:
-r-------- 1 root root 0 Oct 26 15:53 /proc/user_beancounters
So I downloaded the script from the Nagios Exchange:
https://exchange.nagios.org/directory/Plugins/Operating-Systems/*-Virtual-Environments/OpenVZ/check-beancounters/details
In the instructions it suggests to:
don’t forget to set the s-bit (chmod +s check_UBC.pl)
So, I copied the script over, and set the s-bit, then run it from the terminal as root. It works as expected. I then delete the temp file it created, su into the nagios user, and run the script. It works as expected. I delete the temp file it created, and start up Nagios. It can't read the /proc/user_beancounters file! The exact error I get, helpfully, is "could not read /proc/user_beancounters". This is, I believe, thrown by the line in the Perl script:
if (! open IN, "<", $UBC )
{
print "could not read $UBC\n";
exit $ERRORS{'CRITICAL'};
}
My OS is CentOS release 6.2 (Final).
My first thought is that it is some kind of SELinux voodoo, but there is no indication that SELinux is running on this server. Just in case, I tried the following:
echo 0 > /selinux/enforce
But this made no difference.
For reference, this is my nagios service running:
nagios 12939 0.0 0.0 203652 3404 ? Ssl 15:39 0:00 /usr/sbin/nagios -d /etc/nagios/nagios.cfg
And this is where I've put the Perl script:
-rwsr-sr-x 1 nagios nagios 2934 Oct 26 15:37 check_UBC.pl
Any suggestions as to what else I can try?
PS apologies if this should go in a different SE site - never sure with questions that involve scripts, permissions etc...
UPDATE 1
I created a shell script to see if I could 'emulate' the nagios service. It is extremely simple:
#!/bin/bash
/usr/lib64/nagios/plugins/check_UBC.pl
And now I have the following permissions:
-rwsr-sr-x 1 root root 2934 Oct 26 15:37 check_UBC.pl
-rwxrwxrwx 1 root root 51 Oct 26 19:29 check_UBC.sh
As root:
[root#/usr/lib64/nagios/plugins]$ ./check_UBC.pl
everything is fine..
[root#/usr/lib64/nagios/plugins]$ ./check_UBC.sh
everything is fine..
As nagios:
-bash-4.1$ ./check_UBC.pl
everything is fine..
-bash-4.1$ ./check_UBC.sh
everything is fine..
So still no clue...
UPDATE 2
My nagios command definition:
define command{
command_name check_beancounters
command_line $USER1$/check_UBC.pl
}
And the service definition:
define service{
use local-service
host_name localhost
service_description VPS Beancounters
check_command check_beancounters
}
UPDATE 3
I managed to get it to work, but am not over the moon about giving the nagios user full sudo access with no password. In /etc/sudoers I put this on the last line:
nagios ALL=(ALL:ALL) NOPASSWD: ALL
And then changed my command definition to:
define command{
command_name check_beancounters
command_line sudo $USER1$/check_UBC.pl
}
Apparently recent versions of linux will not respect the +s permission when running an interpreted script, only a binary. So I guess I will have to compile a binary wrapper for the script?
UPDATE 4
As per Joe Young's suggestion, I changed my visudo entry to:
nagios ALL=NOPASSWD: /usr/lib64/nagios/plugins/check_UBC.pl
Which hopefully is relatively harmless!
Try changing the owner of check_UBC.pl to root so that when nagios executes check_UBC.pl the script runs as setuid of it's owner root and not the nagios user.
chown root:root check_UBC.pl
EDIT:
Can you post your command definition that's calling check_UBC.pl?
The last thing I can think of to try is to install the perl-suid module: https://chrisjean.com/fix-setuid-cannot-exec-sperl/
Although, if check_UBC.pl runs from the command line with no problem, I'm not sure what difference it would make.
What would the risk be to change the permissions on /proc/user_beancounters to 444 (read for all?) It only contains a number, correct? Not sure if that particular file "sticks around" after a reboot, or worse, constantly gets replaced as the services are running, so this could be a problem still.
Also, consider trying to test for actual "existence" of the file, before you attempt to read from it. Since we're in /proc directory, things do change, from time to time....
Lastly, you are asking to open the file, but syntactically is it asking to open in a read only mode? You may want to try a system call to simply "cat" the file contents, in your shell script, and see if you get a response.

Cgi-bin script to cat a file owned by a user

I'm using Ubuntu server and I have a cgi-bin script doing the following . . .
#!/bin/bash
echo Content-type: text/plain
echo ""
cat /home/user/.program/logs/file.log | tail -400 | col -b > /tmp/o.txt
cat /tmp/o.txt
Now if I run this script with I am "su" the script fills o.txt and then the host.com/cgi-bin/script runs but only shows up to the point I last ran it from the CLI
My apache error log is showing "permission denied" errors. So I know the user apache is running under somehow cannot cat this file. I tried using chown to no avail. Since this file is in a user directory, what is the best way to either duplicate it or symbolic link it or what?
I even considered running the script as root in a crontab to sort of "update" the file in /tmp/ but that did not work for me. How would somebody experienced with cgi-bin handle access to a file in a users directory?
The Apache user www-data does not have write access to a temporary file owned by another user.
But in this particular case, no temporary file is required.
tail -n 400 logfile | col -b
However, if Apache is running in a restricted chroot, it also has no access to /home.
The log file needs to be chmod o+r and all directories leading down to it should be chmod o+x. Make sure you understand the implications of this! If the user has a reason to want to prevent access to an intermediate directory, having read access to the file itself will not suffice. (Making something have www-data as its group owner is possible in theory, but impractical and pointless, as anybody who finds the CGI script will have access to the file anyway.)
More generally, if you do need a temporary file, the simple fix (not even workaround) is to generate a unique temporary file name, and remove it afterwards.
temp=$(mktemp -t cgi.XXXXXXXX) || exit $?
trap 'rm -f "$temp"' 0
trap 'exit 127' 1 2 15
tail -n 400 logfile | col -b >"$temp"
The first trap makes sure the file is removed when the script terminates. The second makes sure the first trap runs if the script is interrupted or killed.
I would be inclined to change the program that creates the log in the first place and write it to some place visible to Apache - maybe through symbolic links.
For example:
ln -s /var/www/cgi-bin/logs /home/user/.program/logs
So your program continues to write to /home/user/.program/logs but the data actually lands in /var/www/cgi-bin/logs where Apache can read it.

Detect use of su command in bash

I would like to know if there is anyway to send a mail as soon as someone tries su -, su or su root. I know the mail command and I am trying to write a script but I am very confused as to
where to write it - whether in .bashrc of root or in /etc/process
how to invoke the mail on the use of su
I've tried the usual Google search etc. but got links on usage of su, disabling it, securing ssh etc - none of which answered this question.
Thanks in advance
I guess that your underlying requirement is that you have a bunch of people you have given root privilege to but you don't completely trust them so you want to keep an eye on them. Your solution to this is to get yourself sent mail whenever they become root.
The problem with this solution is that the root user has unlimited privilege and so there's nothing to stop them from counteracting this mechanism. They could for instance, edit the /etc/login.defs file in one session, do the good thing that you want them to do and then later su to root and do the bad thing that you fear and at the end of that session they edit the /etc/login.defs file back to it's original state and you're none the wiser. Alternatively they could just make a copy of /usr/bin/bash and make the copy a suid file that will give them privilege whenever they run it.
You might be able to close any of the vulnerabilities I've just suggested but there will be many, many more. So you either trust them or else don't use su at all and give them sudo permission to run just those commands that they need to do the thing you want them to do.
There's a log file called /var/log/secure which receives an entry any time su is executed. It gets entries under other conditions as well. It's described in the Linux Administrator's Security Guide.
If user "fred" executes su -, an entry will appear which looks something like this:
Jul 27 08:57:41 MyPC su: pam_unix(su-l:session): session opened for user root by fred(uid=500)
A similar entry would appear with su or su root.
So you could set up a script which monitors /var/log/secure as follows:
#!/bin/sh
while inotifywait -e modify /var/log/secure; do
if tail -n1 /var/log/secure | grep " su: "; then
tail -n1 /var/log/secure | grep " su: " | mail -s "su occurred" you#email.com
fi
done
Note that you need to have the inotify-tool package installed to use inotifywait.
If this script is running in the background, it should send an email to you#email.com any time an su entry occurs.
Now where to run the script. One approach would be to put this into an executable script file (say, watchsu) and call it from your rc.local file:
nohup /path/to/watchsu 2>&1 &
I'm sure there are other ideas for where to start it. I'm not familiar with CentOS.
According to the man page for su, in /etc/login.defs you can set either SULOG_FILE file or SYSLOG_SU_ENABLE yes to log all su activity. Then you just need something like inotifywait to watch the log file for su events.

Is this script safe?

I need to execute some server tasks. Now I heard many many times this is very insecure. This is my solution:
Added this line to sudoers:
www-data ALL=NOPASSWD: /var/private-www/bin/webadmin (Not accessible through web)
Created this script var/private-www/bin/webadmin:
# Script for executing server tasks.
#
# Arguments:
# - Password Required for authentication, not all scripts may run this file
# - Action Action to execute
# Exit codes:
# 0 Failed
# 1 Success
# First of all check the password
if [ $1 = "secretpassword" ]
then
whoami
exit 1
else
echo "No access"
exit 0
fi
The file has these rights:
0111
SSH access is only enabled for one account. So nobody can execute the script, except me (and www-data). www-data can now access this file by doing:
exec('/usr/bin/sudo /var/private-www/bin/webadmin secretpassword', $output, $status);
Is this safe enough? How can I make it more secure?
I'm thinking that if your Apache server gets cracked, someone could access that script and execute it, but I might be wrong.
I've came across a resource you might want to read about, especially when it comes to restricting your script to your internal network.
http://www.linuxsecurity.com/content/view/133913/171/
I hope this answers your question.

Resources