2
\$\begingroup\$

I have a system that needs to be able to reboot a different piece of hardware partway through a script that programs it. It used to wait for me to come and reboot the hardware halfway through, but I've since automated that. I use this python script to control a USB Net Power 8800.

I have two setups to show you: First is a system that I'm sure is secure, but is pretty annoying to maintain; I'm sure the second is insecure.

First:

/usr/bin/power (not set-uid)

#!/bin/sh
if [ -e /opt/usbnetpower/_powerwrapper_$1 ] ; then
        /opt/usbnetpower/_powerwrapper_$1
else
        /opt/usbnetpower/_powerwrapper_
fi

/opt/usbnetpower/_powerwrapper_reboot.c (The source code to one of six almost identical set-uid programs)

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
   setuid( 0 );
   system( "/usr/bin/python /opt/usbnetpower/usbnetpower8800.py reboot" );

   return 0;
}

The reason why there are six is that I didn't trust myself to write correct sanitization code in C that wasn't vulnerable to buffer overflows and the like.

/opt/usbnetpower/usbnetpower8800.py (not set-uid)

Essentially this, but modified to add a reboot command.

This setup is what I am currently using.

Second:

/opt/usbnetpower/usbnetpower8800.py (set-uid)

Much simpler, but I'm concerned that a vulnerability like this would apply. Also, suid python programs appear to be disabled on my system. (CentOS 6)

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Personally I gradually abandon all set-uid things in my system. I primarily use daemons listening UNIX sockets which nonprivileged programs can connect to and ask commands. That way you control what exactly is being used (instead of just all user environment by default). I've developed a program to start other programs over UNIX sockets in controlled way. \$\endgroup\$
    – Vi.
    May 22, 2013 at 22:37

1 Answer 1

3
\$\begingroup\$

Both of your programs are insecure. The problem is that I can set PYTHONPATH to anything I like before executing the program. I can set it to something so that it loads my own usb module which can execute whatever code I like. At that point, I'm executing code as the root user and can do whatever I please. That's why set-uid doesn't work on scripts, and your binary C program wrapper doesn't change that at all.

For more information see: https://unix.stackexchange.com/questions/364/allow-setuid-on-shell-scripts

In your case, what you should be doing is changing the permissions so that your user has access to the USB device you are supposed to be controlling. That way you don't need to run the script as another user. That's what this portion of the script you are using is referring to:

# If you have a permission error using the script and udev is used on your
# system, it can be used to apply the correct permissions. Example:
#  $ cat /etc/udev/rules.d/51-usbpower.rules
#  SUBSYSTEM=="usb", ATTR{idVendor}=="067b", MODE="0666", GROUP="plugdev"

Discussion of how to adjust your system to give you permission to access the USB device is out of scope for this site. I'm also not really an expert on that. So you may need to ask elsewhere for that.

\$\endgroup\$
1
  • \$\begingroup\$ In your case, what you should be doing is changing the permissions so that your user has access to the USB device you are supposed to be controlling. This is what I ended up doing; I open-sourced my changes \$\endgroup\$
    – Nick ODell
    Apr 2, 2013 at 0:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.