14

Is it possible to create a raw socket without root privileges? If not, can a script elevate its privileges itself?

I wrote a Python script using a raw socket:

#!/usr/bin/env python

import socket
rawSocket = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.htons(0x0800))
print "Worked!"

Running it with root privileges prints Worked!. However, it gives an error when run with normal user privileges.

I want to execute my script as a normal user, and it should create a raw socket without asking for anything. Is it possible?

smeso
  • 4,165
  • 18
  • 27
ρss
  • 5,115
  • 8
  • 43
  • 73

3 Answers3

13

As you noted raw sockets require higher privilege than a regular user have. You can circumvent this issue in two ways:

  1. Activating the SUID bit for the file with a command like chmod +s file and set its owner to root with chown root.root file. This will run your script as root, regardless of the effective user that executed it. Of course this could be dangerous if your script has some flaw.
  2. Setting the CAP_NET_RAW capability on the given file with a command like setcap cap_net_raw+ep file. This will give it only the privileges required to open a raw socket and nothing else.

EDIT:

As pointed out by @Netch the given solutions will not work with any interpreted language (like Python). You will need some "hack" to make it work. Try googling for "Python SUID", you should find something.

smeso
  • 4,165
  • 18
  • 27
  • 2
    Most modern systems ignore suid/sgid bits on scripts with any interpreter. Perl directly invented "suidperl" to override this in an explicit require case. – Netch Dec 24 '13 at 15:45
  • Yes this is true. The process executed first is the interpreter, so any SUID/CAP set on the file will be ignored. – smeso Dec 24 '13 at 15:50
  • I tried google a lot and every one is saying the same thing what you guys are mentioning. Well if there is no solution to my problem then the answer is that, there is no solution to do by using entirely python. – ρss Dec 24 '13 at 19:27
  • The only thing I could think is to write a small program in C, enable the SUID bit on it and use it to exec your script. But then you should do some check to avoid a malicious user to execute arbitrary code as root. – smeso Dec 25 '13 at 00:11
11

There is not a way for an unprivileged process (Python or otherwise) to elevate their own privileges. It's kind of the cornerstone of having this whole privileged/unprivileged users thinga-ma-jig. In regards to raw sockets, from manual page raw(7):

Only processes with an effective user ID of 0 or the CAP_NET_RAW capability are allowed to open raw sockets.

User ID of 0 means root. See here for info about raw sockets on linux.

As pointed out in Faust's answer/comments you won't be able to directly set the CAP_NET_RAW capability for your python program, due to it being a script that gets executed by the Python interpreter, but there may be solutions out on the web that can get around this limitation.

mshildt
  • 8,782
  • 3
  • 34
  • 41
0

You can also go another path and set up the application using the sudoers file, then run it via sudo

Or my preferred option is just to compile it with Nuitka, then it runs like any other executable and can be assigned run as root etc

davetayl
  • 113
  • 1
  • 7