Why doesn't setting the SUID bit in OpenBSD set effective and saved UIDs to executable file owner? - permissions

I am using a fresh install of OpenBSD 5.3 as a guest OS on Parallels for Mac:
$ uname -a
OpenBSD openbsd.localdomain 5.3 GENERIC#53 amd64
To my surprise, a binary file owned by root with its SUID bit set runs with UIDs as if the SUID was not set. That is, when UID 1000 runs such a program, the program starts in state:
<real_uid, effective_uid, saved_uid> = <1000, 1000, 1000>
and not in state:
<real_uid, effective_uid, saved_uid> = <1000, 0, 0>
as expected.
Why is this the case?
Here are the details regarding how I found the issue:
I have written an interactive C program (compiled as setuid_min.bin) for evaluating setuid behaviour in different Unix systems. The program lives in a subdirectory of UID 1000's home directory, and the sudo command is used to change ownership and SUID; then the program is run and I enter the uid to report the real, effective, and saved UIDs of the process:
$ sudo chown root:staff setuid_min.bin
$ ls -l | grep 'setuid_min\.bin$'
-rwxr-xr-x 1 root staff [...] setuid_min.bin
$ sudo chmod a+s setuid_min.bin
$ ls -l | grep 'setuid_min\.bin$'
-rwsr-sr-x 1 root staff [...] setuid_min.bin
$ ./setuid_min.bin
uid
1000 1000 1000 some_pid
exit
$
Note that some_pid above is the pid of the setuid_min.bin process. The program reports the real UID, effective UID, and saved UID by reporting the output of the following shell command:
ps -ao ruid,uid,svuid,pid | grep '[ ]my_pid$'
where my_pid is the pid is reported by getpid(). My only guess as to why this might be the case is that OpenBSD has some underlying permissions structure that is using the ownership/permissions of the directory where setuid_min.bin resides, or that is not actually changing ownership/SUID bit when an unprivileged user uses sudo to change file permissions.

Most likely your binary is in one of the default partitions that are mounted "nosuid". The default fstab the install script creates will by mount everything nosuid unless it's known to contain suid binaries.

Related

How to copy file from server to local using ssh and sudo su?

Somewhat related to: Copying files from server to local computer using SSH
When debugging on DEV server I can see logs with
# Bash for Windows
ssh username#ip
# On server as username
sudo su
# On server as su
cat path/to/log.file
The problem is that while every line of the file is indeed printed out, the CLI seems to have a height limit, and I can only see the last "so many" lines after the printing is done.
If there is a better solution, please bring it forward, otherwise, how do I copy the "log.file" to my computer.
Note: I don't have a password for my username, because the user is created with echo "$USER ALL=(ALL:ALL) NOPASSWD: ALL" | tee /etc/sudoers.d/$USER.
After sudo su copy the file to the /tmp folder on the server with
cp path/to/log.file /tmp/log.file
After that the standard command should work
scp username#ip:/tmp/log.file log.file
log.file is now in the current directory (echo $PWD).

Foreign chroot with QEMU user mode, binaries not found unless full path is specified

I am setting up a foreign chroot environment to build for architectures other than amd64 from a GitLab CI image. Steps were mostly taken from https://www.hellion.org.uk/blog/posts/foreign-chroots-with-schroot-and-qemu/, except that I am skipping the schroot/sbuild part.
- export CROSS_ARCH=armhf
- export CROSS_ROOT=/opt/chroot/$CROSS_ARCH
- export DISTRO=stretch
- export CROSS_MIRROR=http://deb.debian.org/debian/
- apt-get update
- apt-get -y install debootstrap qemu-user-static binfmt-support
- mkdir -p $CROSS_ROOT
- debootstrap --variant=buildd --include=fakeroot,build-essential --arch=$CROSS_ARCH --foreign $DISTRO $CROSS_ROOT $CROSS_MIRROR
- mkdir -p $CROSS_ROOT/usr/bin
- cp /usr/bin/qemu-arm-static $CROSS_ROOT/usr/bin/
- chroot $CROSS_ROOT ./debootstrap/debootstrap --second-stage
When I now try to run a command in the target environment like this:
chroot $CROSS_ROOT qemu-arm-static uname -a
the command exits with an error (nonzero exit status), but no error message is printed. It works, however, if I specify the path:
chroot $CROSS_ROOT qemu-arm-static /bin/uname -a
And it gives me the following output, which indicates I am running inside the armhf environment:
Linux runner--azerasq-project-40807358-concurrent-0 5.4.109+ #1 SMP Wed Jun 16 20:00:10 PDT 2021 armv7l GNU/Linux
Oddly, the following works:
chroot $CROSS_ROOT qemu-arm-static /bin/bash -c "uname -a"
i.e. full path to bash, but no path for the command after -c.
Suspecting that there could be something wrong with $PATH, I ran:
chroot $CROSS_ROOT qemu-arm-static /bin/bash -c set
I get all of the GitLab-specific variables, as well as a bunch of others, including the following ones:
MACHTYPE=arm-unknown-linux-gnueabihf
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
When I run
chroot $CROSS_ROOT qemu-arm-static /usr/bin/env
some variables (such as $MACHTYPE) are missing but $PATH is the same. So $PATH seems to be set correctly, and a diff of the outputs (after sorting) does not indicate anything that looks related – the extra variables for bash -c set look mostly bash-specific.
Why won’t qemu-arm-static accept binaries without a full path if they are on $PATH? Where else should I look to debug?
Why won’t qemu-arm-static accept binaries without a full path if they
are on $PATH?
Because qemu-user is not a shell, it doesn't have code that would search the PATH. This is the piece of qemu-user code that opens executable image when it's started as in the examples that you give, and as you can see here exec_path comes directly from the command line.
On the other hand you can install qemu-user as a binfmt-misc handler, in which case the shell will do the PATH search and the kernel will invoke qemu-user with an open file descriptor of the executable file in the AT_EXECFD entry in the aux vectors.

chown: invalid user: ‘nfsnobody’ in fedora 32 after install nfs

I am install nfs using this command in fedora 32:
sudo dnf install nfs-utils
and then I create a dir to export storage:
[dolphin#MiWiFi-R4CM-srv infrastructure]$ cat /etc/exports
/home/dolphin/data/k8s/monitoring/infrastructure/jenkins *(rw,no_root_squash)
now I could mount this dir with root user like this:
sudo mount -t nfs -o v3 192.168.31.2:/home/dolphin/data/k8s/monitoring/infrastructure/jenkins /mnt
now I want to make a step forward to make it it avaliable to any user from any ip(the client could mount nfs without using sudo), so I first try to chown of this folder:
chown 777 jenkins
and then I want to make this jenkins folder group and user to nfsnobody:
[dolphin#MiWiFi-R4CM-srv infrastructure]$ chown -R nfsnobody jenkins
chown: invalid user: ‘nfsnobody’
and I do not find any nfsnobody content from /etc/passwd. what should I do to fix invalid user: ‘nfsnobody’ problem? should nfs-util added it automatically?
Right now nobody used by default probably after RedHat/Centos versions 8
You can simply use
chown -R nobody jenkins
Or
Change it from /etc/idmapd.conf
[Mapping]
Nobody-User = nfsnobody
Nobody-Group = nfsnobody
To put the changes into effect restart the rpcidmapd service and remount the NFSv4 filesystem:
service rpcidmapd restart
mount -o remount /nfs/mnt/point
On Red Hat Enterprise Linux 6, if the above settings have been applied and UID/GID’s are matched on server and client and users are still being mapped to nobody:nobody then a clearing of the idmapd cache may be required.
# nfsidmap -c

How to create a symbolic link to a BusyBox binary?

So currently I have Busybox installed on an embedded kernel in its /system/bin/ folder and can call manually to the VI editor by typing busybox vi and vi will be executed. HOWEVER, I want to create a symbolic link to busybox vi by just typing vi file.txt instead of busybox vi file.txt so I won't have to type busybox every time. How to do this? I already tried this:
Installing Busybox
If the Busybox executable is renamed to one of the commands it supports, it will act as that command automatically:
ln -s busybox pwd
./pwdfrom
...from Busybox's website but still doesn't work, all it says is on my terminal for which command is:
127|root#nitrogen6x:/system/bin # ln -s busbox which
root#nitrogen6x:/system/bin # which ls
/system/bin/sh: which: not found
127|root#nitrogen6x:/system/bin # ls -la which lrwxrwxrwx root root 1970-01-03 18:15 which -> busbox
any ideas what I'm doing wrong? My $PATH is: /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin
I figured out how to get this to work
HERE'S HOW:
So I went to root directory:
cd /
Then I remounted the /system/ directory:
mount -o rw,remount /system
Then I went into the binary folder where busybox was located:
cd /system/bin/
Then I used the link command for the busybox binary I wanted:
ln -s busybox lsusb (remember you must be in /system/bin directory already)
For Already Linked Files:
For already linked files like ls, remove the linked file and replace with Busybox binary instead (I know it sounds crazy but you can always go back to system's binary utilities):
sudo rm /system/bin/ls
ln -s busybox ls (remember you must be in /system/bin directory already)
You should get something like this when you do ls -l ls:
lrwxrwxrwx 1 0 0 7 Jan 4 21:53 ls -> busybox
One point to consider is that you have to be on the same file system.
For example if you are trying to create a symbolic link from one mounted file system to a file on another file system then that's an issue.
If your / and /usr are not on the same mounted file system as there might be the case for embedded systems, then you cannot create a symbolic link /usr/bin/which to point to /bin/busybox.
One possible solution is to put a copy of busybox binary in /urs/bin and create link to that.

how to read shadow file in linux using python script

file = open('/etc/shadow', 'r')
print(file)
getting error like this
file = open('/etc/shadow', 'r')
IOError: [Errno 13] Permission denied: '/etc/shadow'
On most systems /etc/shadow is owned by root with rw permissions.
$ ls -la /etc/shadow
-rw------- 1 root root 692 Jun 10 19:24 /etc/shadow
You need to either:
Change the permissons (don't do this it is not safe)
but you could this by running 'chmod o+r /etc/shadow' as root. This will give the 'other' users read rights to
Run your program as root. Either by
a. Starting it as root
su -c 'python myPython.py' //you will be asked to provide the root password.
b. Starting it with sudo [1]
sudo python myPython.py this all depends on you sudo configuration but is your best bet other then just starting python as root.
Also an example to call sudo from within python[5].
c. Set setuid bit on the program [2]
This will most likely not work as Python is an interpreted language and most modern Unix systems will disallow (exception being Perl) setuid on interpreted programs as opposed to compiled/binaries.
chown root programName # Set owner to be root
chmod +s programName # This gives the program itself the right to run as root.
Regardless of whom starts it.
[1]http://en.wikipedia.org/wiki/Sudo
[2]http://en.wikipedia.org/wiki/Setuid
[3]Open a file as superuser in python
[4]Setuid bit on python script : Linux vs Solaris
[5]Using sudo with Python script
The problem is not with the source code or python. But with not having the correct file system rights to the '/etc/shadow' file.
In python 3 you can do:
import spwd
spwd.getspnam('username')
More information about the spwd module can be found here: https://docs.python.org/3/library/spwd.html#module-spwd