10

I'm trying to learn a bit of packet generation with scapy. It looks pretty cool. Following some documentation I'm doing this:

l3=IP(dst="192.168.0.1", src="192.168.0.2", tos=(46 << 2))

But only to get the error message of:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/scapy/sendrecv.py", line 251, in send
    __gen_send(conf.L3socket(*args, **kargs), x, inter=inter, loop=loop, count=count,verbose=verbose, realtime=realtime)
  File "/usr/lib/python2.7/dist-packages/scapy/arch/linux.py", line 307, in __init__
    self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
  File "/usr/lib/python2.7/socket.py", line 187, in __init__
    _sock = _realsocket(family, type, proto)
error: [Errno 1] Operation not permitted

Running scapy as root solved the problem. But that's not what I wanted. Is it because normal user can't create RAW socket? If so, is there a solution?

jfleach
  • 501
  • 1
  • 8
  • 21
lang2
  • 11,433
  • 18
  • 83
  • 133

4 Answers4

12

Scapy needs root privileges to create raw sockets because it uses the Python socket library. Raw sockets are only allowed to used "with an effective user ID of 0 or the CAP_NET_RAW capability" according to the Linux raw man pages.

I can't find what looks to be reliable documentation on setting the CAP_NET_RAW capability, but if you are looking to a work around to running Scapy scripts that user raw sockets without root, that is what you need to do.

RyPeck
  • 7,830
  • 3
  • 38
  • 58
8

To run Scapy with just cap_net_raw privilege...

The safest and less complicated way I know is, in order:

  1. Make a personal copy of the python binary:

    $ sudo cp /usr/bin/python2.7 ~/python_netraw

  2. Own it:

    $ sudo chown your user name ~/python_netraw

  3. Don't let anybody else run it:

    $ chmod -x,u+x ~/python_netraw

  4. Give it cap_net_raw capability:

    $ sudo setcap cap_net_raw=eip /usr/bin/python_netraw

  5. Run scapy with it:

    $ ~/python_netraw -O /usr/bin/scapy

(Or use sudo each time you need to run Scapy with raw privileges.)

gatopeich
  • 3,287
  • 31
  • 26
5

A dirty approach, possibly insecure: Directly give CAP_NET_RAW capability to Python:

sudo setcap cap_net_raw=eip $(readlink -f $(which python))
tropappar
  • 141
  • 1
  • 5
  • Thanks for your answer, but the other answers also suggest setting CAP_NET_RAW. – Michael Kotzjan May 21 '21 at 11:10
  • Yes, that's true. But I propose to do it for the global executable. However, this gives every user script the capability to create raw sockets. – tropappar May 22 '21 at 17:38
  • Also: Shared libraries cannot be directly included anymore, because the LD_LIBRARY_PATH gets disabled. See https://stackoverflow.com/questions/9843178/linux-capabilities-setcap-seems-to-disable-ld-library-path – tropappar May 22 '21 at 17:39
0

To run a temporary python environment (like for scapy) with cap_net_raw I found this works:

sudo -E capsh --caps="cap_setpcap,cap_setuid,cap_setgid+ep cap_net_raw+eip" --keep=1 --user="$USER" --addamb="cap_net_raw" -- -c /usr/bin/python3

adapted from the Arch Wiki

Mark Finn
  • 53
  • 1
  • 5