Python Scapy sniff without root - python-2.7

I'm wondering if there is any possibility to run Scapy's 'sniff(...)' without root priveleges.
It is used in an application, where certain packages are captured. But I don't want to run the whole application with root permissions or change anything on scapy itselfe.
Thanks in advance!
EDIT:
For testing I use following code:
from scapy.all import *
def arp_monitor_callback(pkt):
if ARP in pkt and pkt[ARP].op in (1,2): #who-has or is-at
return pkt.sprintf("%ARP.hwsrc% %ARP.psrc%")
sniff(prn=arp_monitor_callback, filter="arp", store=0)
I'm only able to run it using sudo.
I tried to set capabilities with sudo setcap 'cap_net_admin=+eip' test.py. But it doesn't show any effects. Even the all capablity doesn't help.

You need to set capabilities for binaries running your script i-e: python and tcpdump if you want to be able to just execute your script as ./test.py :
setcap cap_net_raw=eip /usr/bin/pythonX.X
setcap cap_net_raw=eip /usr/bin/tcpdump
Where X.X is the python version you use to run the script.
(note that path could be different on your system)
Please note that this allow anyone to open raw sockets on your system.

Although solution provided by #Jeff is technically correct, because of setting the file capabilities directly on binaries in /usr/bin, it has a drawback of allowing anyone in the system to open raw sockets.
Another way of achieving the desired outcome - script running with just the CAP_NET_RAW - is to use ambient capabilities. This can be done by leveraging a small helper binary that sets up ambient capabilities and exec()'s into python interpreter. For a reference please see this gist.
Using the reference implementation, assuming that that proper file capabilities are assigned to ./ambient:
$ sudo setcap 'cap_net_raw=p' ambient
your script would be launched as:
$ ./ambient -c '13' /usr/bin/python ./test.py
Please note that:
13 is the integer value of CAP_NET_RAW as per capability.h
ambient capabilities are available since kernel 4.3
you can use pscap to verify if the process was launched with desired capabilities in its effective set
Why does this method work?
Ambient capabilities are preserved across exec() calls (hence passed to all subsequently created subprocesses) and raised in their effective set, e.g. a python interpreter invoked by the binary or tcpdump invoked by python script. This is of course a simplification, for a full description of transitions between capability sets see capabilities(7)

Related

Starting the default terminal on Linux

Tell me, please, is it possible to call the Linux Terminal, which is installed by default, in some way (method)?
Now, I run the process in the xfce4-terminal terminal, specifying this terminal and the arguments to it:
QProcess up;
QString cArg;
cArg="/tmp/cp.py -y " + ye;
up.start("xfce4-terminal", QStringList()<< "--geometry=120x40" << "--command" << "python3 "+ cArg << "-H");
up.waitForFinished();
up.close();
No, there is no general way in the Linux kernel to find out which (or whether a) terminal emulator is installed on the system by default.
Although the (fairly ubiquitous) freedesktop.org specifications describe how to associate MIME type with a default application, there isn't a specification for default application without an associated file to be opened as far as I can tell. Each desktop environment that has a concept of "default terminal emulator" has their own way of configuring it.
Debian has has "update-alternatives" system that allows configuration of "default" applications based on aliases, and it has a package that creates an alias x-terminal-emulator that can be used to configure the default terminal emulator.
Here is a reasonable strategy for choosing the command in your program:
Let the user configure the command. Use this with highest priority if configured.
Use XDG_CURRENT_DESKTOP environment variable, and implement logic for each desktop environment to read their configuration to find out the configured default emulator. Use this as the second highest priority when available.
Collect a list of commonly used terminal emulators. Put aliases such as x-terminal-emulator with higher priority in the list.
With this list starting with user configuration and ending with your hard-coded list, check each command and see if it's executable and pick the first one that is. In case user has configured the command, and it isn't executable, I recommend an optional error message.
You can use i3's sensible-terminal script.
https://github.com/i3/i3/blob/next/i3-sensible-terminal
While it has been made for i3, if you read the source you'll see it's very simple and doesn't rely on it, so feel free to use this within whatever desktop environment you want.
Though if you don't use i3 you may want to remove the last line (which isn't that important as you are unlikely to have no terminal installed at all).
Explanations
It proceeds by getting, in this order:
A terminal you may have defined in the non-standard $TERMINAL environment variable
x-terminal-emulator which is a similar utility for Debian only
A list of hardcoded terminals, namely mate-terminal gnome-terminal terminator xfce4-terminal urxvt rxvt termit Eterm aterm uxterm xterm roxterm termite lxterminal terminology st qterminal lilyterm tilix terminix konsole kitty guake tilda alacritty hyper

calling mount() system call as a non-root user

I am writing a C/C++ program that needs to be able to mount a disk as an ordinary user (can't run with sudo). Typically, questions of this type pertain to using the mount command in a shell, and the answer is to use the "user" option in the /etc/fstab entry corresponding to the disk in question. However, I don't think that the listings in the /etc/fstab matter at all when using the mount system call in a program.
However, since it is clear that the mount command is capable of allowing non-root users to mount disks (assuming the /etc/fstab is setup right), and presumably the mount command calls the mount system call, then I think it should be possible to achieve what I want.
How can I successfully call the mount() system call without running the program with sudo?
A valid solution to this dilemma is to pack the mount/umount calls into a shell script, provide sudo permissions for that to the application user, and call it from the application e. g. using system(). Make sure that the script does adequate error handling and perhaps logging, returning the appropriate exit code on error or success you can handle in the calling application.
/etc/sudoers.d/myApplication:
<appUser> <host> = (root) NOPASSWD: /usr/local/bin/myMountScript.sh
In your application:
const int result = system("sudo /usr/local/bin/myMountScript.sh <options>");
//Error handling on result follows below
Another possibility is to use capabilities, as mentioned in a comment above, and set them on the binary, but that's bit more complex, so I don't get into details here.

Creating a C++ daemon and keeping the environment

I am trying to create a c++ daemon that runs on a Red Hat 6.3 platform and am having trouble understanding the differences between the libc daemon() call, the daemon shell command, startproc, start-stop-daemon and about half a dozen other methods that google suggests for creating daemons.
I have seen suggestions that two forks are needed, but calling daemon only does one. Why is the second fork needed?
If I write the init.d script to call bash daemon, does the c code still need to call daemon?
I implemented my application to call the c daemon() function since it seems the simplest solution, but I am running into the problem of my environment variables seem to get discarded. How do I prevent this?
I also need to run the daemon as a particular user, not as root.
What is the simplest way to create a C++ daemon that keeps its environment variables, runs as a specific user, and is started on system boot?
Why is the second fork needed?
Answered in What is the reason for performing a double fork when creating a daemon?
bash daemon shell command
My bash 4.2 does not have a builtin command named daemon. Are you sure yours is from bash? What version, what distribution?
environment variables seem to get discarded.
I can see no indication to that effect in the documentation. Are you sure it is due to daemon? Have you checked whether they are present before, and missing after that call?
run the daemon as a particular user
Read about setresuid and related functions.
What is the simplest way to create a C++ daemon that keeps its environment variables, runs as a specific user, and is started on system boot?
Depends. If you want to keep your code simple, forget about all of this and let the init script do this via e.g. start-stop-daemon. If you want to handle this in your app, daemon combined with retresuid should be a good approach, although not the only one.

A method to change effective user id of a running program?

I'm writing a simple package manager and I'd like to automatically try sudo if the program isn't run as root. I found a function called seteuid, which looks likes it's exactly what I need, but I don't have the permissions to run it. So far all I can think of is a bash script to check before they get to the actual binary, but I'd like to do this all as C++ if possible.
Is there any method of changing a processes's euid after it starts executing? Or a way to call sudo?
Here's how these functions work.
If a program has the setuid bit, it will execute as it's owner. Once it is executing, it can call seteuid to run as the original user instead of its owner. Ditty for setgid.
The principle is the principal of least privilege. If I write a program that needs special access, I want as little code as possible to run with the access. So, I install it setuid, but the first thing it does it give back the privileges until the narrow window of code that needs them.
You can't call sudo (except, of course, via fork/exec). You can be a program like sudo that is installed setuid and which decided when to use that awesome power appropriately.
As bmargulies says in his answer, you can do this if you binary is owned by root and has the setuid bit set - but then you will need to implement the authentication part (checking that the user is actually allowed to become root) yourself too.
You'd be essentially rewriting sudo within your application - the best way to handle this is to do what you suggested yourself, and install your application with a wrapper script that uses /usr/bin/id to check if it is root, and if not, call out to sudo (or su).

writing pexpect like program in c++ on Linux

Is there any way of writing pexpect like small program which can launch a process and pass the password to that process?
I don't want to install and use pexpect python library but want to know the logic behind it so that using linux system apis I can build something similar.
You could just use "expect". It is very light weight and is made to do what youre describing.
For very simple cases, empty is one option. It's a lightweight C program, and it can be used straight from a shell script and doesn't require Tcl.
For Debian/Ubuntu, the package is empty-expect.