scapy: Operation not permitted when sending packets - python

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?

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.

To run Scapy with just cap_net_raw privilege...
The safest and less complicated way I know is, in order:
Make a personal copy of the python binary:
$ sudo cp /usr/bin/python2.7 ~/python_netraw
Own it:
$ sudo chown your user name ~/python_netraw
Don't let anybody else run it:
$ chmod -x,u+x ~/python_netraw
Give it cap_net_raw capability:
$ sudo setcap cap_net_raw=eip /usr/bin/python_netraw
Run scapy with it:
$ ~/python_netraw -O /usr/bin/scapy
(Or use sudo each time you need to run Scapy with raw privileges.)

A dirty approach, possibly insecure: Directly give CAP_NET_RAW capability to Python:
sudo setcap cap_net_raw=eip $(readlink -f $(which python))

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

Related

Creating an FTP server with python [duplicate]

Is it possible to have a one line command in python to do a simple ftp server? I'd like to be able to do this as quick and temporary way to transfer files to a linux box without having to install a ftp server. Preferably a way using built in python libraries so there's nothing extra to install.
Obligatory Twisted example:
twistd -n ftp
And probably useful:
twistd ftp --help
Usage: twistd [options] ftp [options].
WARNING: This FTP server is probably INSECURE do not use it.
Options:
-p, --port= set the port number [default: 2121]
-r, --root= define the root of the ftp-site. [default:
/usr/local/ftp]
--userAnonymous= Name of the anonymous user. [default: anonymous]
--password-file= username:password-style credentials database
--version
--help Display this help and exit.
Check out pyftpdlib from Giampaolo Rodola. It is one of the very best ftp servers out there for python. It's used in google's chromium (their browser) and bazaar (a version control system). It is the most complete implementation on Python for RFC-959 (aka: FTP server implementation spec).
To install:
pip3 install pyftpdlib
From the commandline:
python3 -m pyftpdlib
Alternatively 'my_server.py':
#!/usr/bin/env python3
from pyftpdlib import servers
from pyftpdlib.handlers import FTPHandler
address = ("0.0.0.0", 21) # listen on every IP on my machine on port 21
server = servers.FTPServer(address, FTPHandler)
server.serve_forever()
There's more examples on the website if you want something more complicated.
To get a list of command line options:
python3 -m pyftpdlib --help
Note, if you want to override or use a standard ftp port, you'll need admin privileges (e.g. sudo).
Why don't you instead use a one-line HTTP server?
python -m SimpleHTTPServer 8000
will serve the contents of the current working directory over HTTP on port 8000.
If you use Python 3, you should instead write
python3 -m http.server 8000
See the SimpleHTTPServer module docs for 2.x and the http.server docs for 3.x.
By the way, in both cases the port parameter is optional.
The answers above were all assuming your Python distribution would have some third-party libraries in order to achieve the "one liner python ftpd" goal, but that is not the case of what #zio was asking. Also, SimpleHTTPServer involves web broswer for downloading files, it's not quick enough.
Python can't do ftpd by itself, but you can use netcat, nc:
nc is basically a built-in tool from any UNIX-like systems (even embedded systems), so it's perfect for "quick and temporary way to transfer files".
Step 1, on the receiver side, run:
nc -l 12345 | tar -xf -
this will listen on port 12345, waiting for data.
Step 2, on the sender side:
tar -cf - ALL_FILES_YOU_WANT_TO_SEND ... | nc $RECEIVER_IP 12345
You can also put pv in the middle to monitor the progress of transferring:
tar -cf - ALL_FILES_YOU_WANT_TO_SEND ...| pv | nc $RECEIVER_IP 12345
After the transferring is finished, both sides of nc will quit automatically, and job done.
For pyftpdlib users. I found this on the pyftpdlib website. This creates anonymous ftp with write access to your filesystem so please use with due care. More features are available under the hood for better security so just go look:
sudo pip3 install pyftpdlib
python3 -m pyftpdlib -w
## updated for python3 Feb14:2020
Might be helpful for those that tried using the deprecated method above.
sudo python -m pyftpdlib.ftpserver
apt-get install python3-pip
pip3 install pyftpdlib
python3 -m pyftpdlib -p 21 -w --user=username --password=password
-w = write permission
-p = desired port
--user = give your username
--password = give your password
Install:
pip install twisted
Then the code:
from twisted.protocols.ftp import FTPFactory, FTPRealm
from twisted.cred.portal import Portal
from twisted.cred.checkers import AllowAnonymousAccess, FilePasswordDB
from twisted.internet import reactor
reactor.listenTCP(21, FTPFactory(Portal(FTPRealm('./'), [AllowAnonymousAccess()])))
reactor.run()
Get deeper:
http://twistedmatrix.com/documents/current/core/examples/
The simpler solution will be to user pyftpd library. This library allows you to spin Python FTP server in one line. It doesn’t come installed by default though, but we can install it using simple apt command
apt-get install python-pyftpdlib
now from the directory you want to serve just run the pythod module
python -m pyftpdlib -p 21
I dont know about a one-line FTP server, but if you do
python -m SimpleHTTPServer
It'll run an HTTP server on 0.0.0.0:8000, serving files out of the current directory. If you're looking for a way to quickly get files off a linux box with a web browser, you cant beat it.

python socket protocol not support

I useed python-can-isotp on RaspberryPi3, and test it with example code, but I got an error.
My simple code:
import isotp
s = isotp.socket()
s2 = isotp.socket()
# Configuring the sockets.
s.set_fc_opts(stmin=5, bs=10)
#s.set_general_opts(...)
#s.set_ll_opts(...)
s.bind("vcan0" rxid=0x123 txid=0x456) # We love named parameters!
s2.bind("vcan0", rxid=0x456, txid=0x123)
s2.send(b"Hello, this is a long payload sent in small chunks of 8 bytes.")
print(s.recv())
ERROR:
File "/usr/local/opt/python-3.7.0/lib/python3.7/socket.py", line 151, in __init__
_socket.socket.__init__(self, family, type, proto, fileno)
OSError: [Errno 93] Protocol not supported
Can someone please help me find the solution to the problem?
I followed these instructions (with slight modifications) to make isotp work on a Raspberry Pi 3B+ with the latest Raspbian Stretch.
Here is the exact sequence of commands I carried out:
sudo apt update
sudo apt upgrade
git clone https://github.com/hartkopp/can-isotp.git
cd can-isotp
sudo apt install build-essential raspberrypi-kernel-headers
make install
sudo make modules_install
modprobe can
sudo insmod ./net/can/can-isotp.ko
However, I don't use it in Python. I simply tested the tools provided for use with isotp, such as e.g. isotpsend and isotprecv.

Python 3: accessing windows share under Linux by UNC path

First, lets ensure that windows share is accesable:
$ sudo mkdir /mnt/test
Let's try mount, but it's fail:
$ sudo mount -t cifs //192.168.0.10/work /mnt/test
mount: wrong fs type, bad option, bad superblock on //192.168.0.10/work,
missing codepage or helper program, or other error
(for several filesystems (e.g. nfs, cifs) you might
need a /sbin/mount.<type> helper program)
In some cases useful info is found in syslog - try
dmesg | tail or so.
But if provide dummy user/pass (i.e. point exactly 'USERNAME' and 'PASSWD'), mount success:
$ sudo mount -t cifs -o username=USERNAME,password=PASSWD //192.168.0.10/work /mnt/test
$ ls /mnt/test/*.txt
/mnt/test/1.txt
$ umount test
Now lets try python:
$ python -V
Python 3.5.2+
$ python
>>> import os
>>> os.listdir(r'//192.168.0.10/work')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '//192.168.0.10/work'
I'm trying four slashes, backslashes, combine it, with or without r, unicode escaping (bytes(path, "utf-8").decode("unicode_escape")), all this fail with No such file or directory. May be reason of this fail is user/pass, but I have no imagine how add it to UNC.
ps. Also I try pysmb library, it's work fine without user/pass. But I dont want using additional lib if it possible.
You must mount a UNC path on Linux. The OS has no way of understanding two backslashes except when mounting the path. So to make this automatic, just write some Python code to call the necessary Linux commands to accomplish the mount task and then refer to a file path as you normally would.
Example running Linux "ls" command from Python.
import os
os.system('ls')
Now follow one of these two methods.
https://unix.stackexchange.com/questions/18925/how-to-mount-a-device-in-linux
https://www.putorius.net/mount-windows-share-linux.html

stratum-mining-proxy error - Can't decode message

I'm attempting to run stratum-mining-proxy with minerd. Proxy starts and runs with the following command:
python ./mining_proxy.py -o ltc-stratum.kattare.com -p 3333 -pa scrypt
Proxy starts fine. Run Minerd (U/P removed):
minerd -a scrypt -r 1 -s 6 -o http://127.0.0.1:3333 -O USERNAME.1:PASSWORD
Following errors are received. This one from the proxy:
2013-07-18 01:33:59,981 ERROR protocol protocol.dataReceived # Processing of message failed
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/stratum-0.2.12-py2.7.egg/stratum/protocol.py", line 185, in dataReceived
self.lineReceived(line, request_counter)
File "/usr/local/lib/python2.7/dist-packages/stratum-0.2.12-py2.7.egg/stratum/protocol.py", line 216, in lineReceived
raise custom_exceptions.ProtocolException("Cannot decode message '%s'" % line)
'rotocolException: Cannot decode message 'POST / HTTP/1.1
And this from minerd. What am I doing wrong? Any help is appreciated!
[2013-07-18 01:33:59] HTTP request failed: Empty reply from server
[2013-07-18 01:33:59] json_rpc_call failed, retry after 30 seconds
I am a little curious, I don't know as a fact but I was under the impression that the mining proxy was for BTC not LTC.
But anyways I believe I got a similar message when I first installed it as well. To fix, or rather to actually get it running I had to use the Git installation method instead of installing manually.
Installation on Linux using Git
This is advanced option for experienced users, but give you the easiest way for updating the proxy.
1.git clone git://github.com/slush0/stratum-mining-proxy.git
2.cd stratum-mining-proxy
3.sudo apt-get install python-dev # Development package of Python are necessary
4.sudo python distribute_setup.py # This will upgrade setuptools package
5.sudo python setup.py develop # This will install required dependencies (namely Twisted and Stratum libraries), but don't install the package into the system.
6.You can start the proxy by typing "./mining_proxy.py" in the terminal window. Using default settings, proxy connects to Slush's pool interface.
7.If you want to connect to another pool or change other proxy settings, type "./mining_proxy.py --help".
8.If you want to update the proxy, type "git pull" in the package directory.

One line ftp server in python

Is it possible to have a one line command in python to do a simple ftp server? I'd like to be able to do this as quick and temporary way to transfer files to a linux box without having to install a ftp server. Preferably a way using built in python libraries so there's nothing extra to install.
Obligatory Twisted example:
twistd -n ftp
And probably useful:
twistd ftp --help
Usage: twistd [options] ftp [options].
WARNING: This FTP server is probably INSECURE do not use it.
Options:
-p, --port= set the port number [default: 2121]
-r, --root= define the root of the ftp-site. [default:
/usr/local/ftp]
--userAnonymous= Name of the anonymous user. [default: anonymous]
--password-file= username:password-style credentials database
--version
--help Display this help and exit.
Check out pyftpdlib from Giampaolo Rodola. It is one of the very best ftp servers out there for python. It's used in google's chromium (their browser) and bazaar (a version control system). It is the most complete implementation on Python for RFC-959 (aka: FTP server implementation spec).
To install:
pip3 install pyftpdlib
From the commandline:
python3 -m pyftpdlib
Alternatively 'my_server.py':
#!/usr/bin/env python3
from pyftpdlib import servers
from pyftpdlib.handlers import FTPHandler
address = ("0.0.0.0", 21) # listen on every IP on my machine on port 21
server = servers.FTPServer(address, FTPHandler)
server.serve_forever()
There's more examples on the website if you want something more complicated.
To get a list of command line options:
python3 -m pyftpdlib --help
Note, if you want to override or use a standard ftp port, you'll need admin privileges (e.g. sudo).
Why don't you instead use a one-line HTTP server?
python -m SimpleHTTPServer 8000
will serve the contents of the current working directory over HTTP on port 8000.
If you use Python 3, you should instead write
python3 -m http.server 8000
See the SimpleHTTPServer module docs for 2.x and the http.server docs for 3.x.
By the way, in both cases the port parameter is optional.
The answers above were all assuming your Python distribution would have some third-party libraries in order to achieve the "one liner python ftpd" goal, but that is not the case of what #zio was asking. Also, SimpleHTTPServer involves web broswer for downloading files, it's not quick enough.
Python can't do ftpd by itself, but you can use netcat, nc:
nc is basically a built-in tool from any UNIX-like systems (even embedded systems), so it's perfect for "quick and temporary way to transfer files".
Step 1, on the receiver side, run:
nc -l 12345 | tar -xf -
this will listen on port 12345, waiting for data.
Step 2, on the sender side:
tar -cf - ALL_FILES_YOU_WANT_TO_SEND ... | nc $RECEIVER_IP 12345
You can also put pv in the middle to monitor the progress of transferring:
tar -cf - ALL_FILES_YOU_WANT_TO_SEND ...| pv | nc $RECEIVER_IP 12345
After the transferring is finished, both sides of nc will quit automatically, and job done.
For pyftpdlib users. I found this on the pyftpdlib website. This creates anonymous ftp with write access to your filesystem so please use with due care. More features are available under the hood for better security so just go look:
sudo pip3 install pyftpdlib
python3 -m pyftpdlib -w
## updated for python3 Feb14:2020
Might be helpful for those that tried using the deprecated method above.
sudo python -m pyftpdlib.ftpserver
apt-get install python3-pip
pip3 install pyftpdlib
python3 -m pyftpdlib -p 21 -w --user=username --password=password
-w = write permission
-p = desired port
--user = give your username
--password = give your password
Install:
pip install twisted
Then the code:
from twisted.protocols.ftp import FTPFactory, FTPRealm
from twisted.cred.portal import Portal
from twisted.cred.checkers import AllowAnonymousAccess, FilePasswordDB
from twisted.internet import reactor
reactor.listenTCP(21, FTPFactory(Portal(FTPRealm('./'), [AllowAnonymousAccess()])))
reactor.run()
Get deeper:
http://twistedmatrix.com/documents/current/core/examples/
The simpler solution will be to user pyftpd library. This library allows you to spin Python FTP server in one line. It doesn’t come installed by default though, but we can install it using simple apt command
apt-get install python-pyftpdlib
now from the directory you want to serve just run the pythod module
python -m pyftpdlib -p 21
I dont know about a one-line FTP server, but if you do
python -m SimpleHTTPServer
It'll run an HTTP server on 0.0.0.0:8000, serving files out of the current directory. If you're looking for a way to quickly get files off a linux box with a web browser, you cant beat it.

Categories

Resources