2020-10-24 23:49:00
One of the benefits of teaching Linux to a group of young adults, is that it forces me to go back to the books myself. The Linux+ objectives cover a few things I haven't worked with yet (such as MDM), but also touches on things I haven't given much thought yet. Case in point: PAM.
Just about every Linux sysadmin certification exam requires that you can work with Pluggable Authentication Modules. They want you to make your SSHd or SU authenticates correctly, or to include pam_tally. So we learn about /etc/pam.conf and /etc/pam.d/* and how to setup an auth or session stack correctly.
What led me down a rabbithole was this: what if I want to make a Python app that authenticates users? I found references to python-pam and other modules, but most discussions ended with: "You need to run as root, or add your application user to the shadow group."
Initially this felt odd to me because, aren't we teaching everybody that services shouldn't run as "root"? In the end it does make sense, of course, because if any arbitrary user could (ab)use PAM to verify another user's password that'd be problematic. The process might be very noisy, but you could still try to brute-force the password.
One source of confusion was the pam_unix documentation, which states:
"A helper binary, unix_chkpwd(8), is provided to check the user's password when it is stored in a read protected database. This binary is very simple and will only check the password of the user invoking it. It is called transparently on behalf of the user by the authenticating component of this module. In this way it is possible for applications like xlock(1) to work without being setuid-root."
Stupidly my brain glossed over the important parts (I need sleep) and latched onto the "without being setuid-root". The important part being that it "will only check the password of the user invoking it".
What made me finally understand the workings of unix_chkpwd is a project of Marco Bellaccini's that I found on Github -> chkpwd_buddy. It should me the proper way of interacting with unix_chkpwd as a non-root user: FIFO pipes.
$ mkfifo /tmp/myfifo
$ echo -ne 'testing\0' > /tmp/myfifo &
$ /sbin/unix_chkpwd tess nullok < /tmp/myfifo
$ echo $?
0
$ echo -ne 'testing\0' > /tmp/myfifo &
$ /sbin/unix_chkpwd testaccount nullok < /tmp/myfifo
$ echo $?
7
$ sudo -i
# mkfifo /tmp/rootfifo
# echo -ne 'testing\0' > /tmp/rootfifo &
# /sbin/unix_chkpwd tess nullok < /tmp/rootfifo
# echo $?
0
# echo -ne 'testing\0' > /tmp/rootfifo &
# /sbin/unix_chkpwd testaccount nullok < /tmp/rootfifo
# echo $?
0
Root can verify both my "tess" password and the one on "testaccount", while I could only verify my own password with my normal account.
What's interesting, is that only the failed validation attempt shows up in journalctl. The successful attempts are not registered:
$ sudo journalctl -t unix_chkpwd
Oct 22 16:08:53 kalivm unix_chkpwd[86131]: check pass; user unknown
Oct 22 16:08:53 kalivm unix_chkpwd[86131]: password check failed for user (test)
To sum it up, if you want a Python app to authenticate the running-user's identity, you can use the python_pam module. But if you want the Python app to authenticate any/every user, then it will need to run as "root".
kilala.nl tags: teaching, work,
View or add comments (curr. 0)
2020-10-06 19:30:00
EDIT: The tweaks outlined in this blog post are no longer needed. Read this update!
Sometimes you just have an odd need or craving! You just have to have some spicy curry udon after midnight! You just have to get an old RAID controller to work in your homelab! Or in this case: you just really have to get VirtualBox and Hyper-V to play nice on Windows 10.
That's something that just wouldn't fly until recently. But now it'll work!
I would like to extend my warmest thanks to my colleage Praveen K-P, who worked with me to figure all of this out. =)
These instructions are a work-in-progress and the solution is not 100% rock-solid.
Some mathematical functions, such as SHA2 or CRC, may fail depending on the OS you run in the VM. This means that outright installing an OS from DVD or ISO may fail during extraction: SHA1 or SHA2 checksums won't match up and the installer will refuse to continue. This is likely caused by the layered CPU virtualization and is under research with the VirtualBox team.
Also, please be careful when choosing base images for your VirtualBox VMs! Do not assume that you can trust every VM image on the Vagrant repositories! Only install images from trusted providers such as:
Installing untrusted base images may lead to malware infections or worse.
Kali Linux is one of the distributions whose installation fails due to the caveat involving mathematical functions. So let's use Vagrant instead, which pulls pre-built images from an online repository.
Open Powershell. Run the following commands:
cd $HOME
mkdir Vagrant; cd Vagrant;
vagrant init kalilinux/rolling
Before continuing, edit the "vagrantfile" file (e.g. with Notepad) and replace this line:
config.vm.box = "kalilinux/rolling"
With the following configuration. Edit the amount of RAM and CPUs to your liking. Me, I like 6GB and 3 cores.
config.vm.define "kali" do |kali|
kali.vm.box = "kalilinux/rolling"
kali.vm.hostname = "haxor"
kali.vm.provider "virtualbox" do |vb|
vb.gui = true
vb.memory = "6144"
vb.cpus = 3
vb.customize [ "modifyvm", :id, "--paravirtprovider", "minimal" ]
end
kali.vm.synced_folder '.', '/vagrant', disabled: true
kali.vm.provision "shell", inline: <<-SHELL
echo "Here we would install..."
[[ ! -d /etc/gcrypt ]] && mkdir /etc/gcrypt
[[ ! -f /etc/gcrypt/hwf.deny ]] && echo "all" >> /etc/gcrypt/hwf.deny
SHELL
end
Save the configuration file and now run the following in Powershell:
vagrant up kali
The init-command sets up your "Vagrant" directory and basic configuration file. By editing the "vagrantfile" we can change a lot of the behavior, including the way Kali perceives the VirtualBox hypervisor. We also tweak GCrypt, so it will refuse to try hardware accellerated cryptography. Both are required to make hashing and other maths work better.
The up-command actually starts the build of the VM, after which it is booted. The first installation will take a few minutes, after that you can just manage the VM using the VirtualBox user interface.
The Kali Linux Vagrant build includes the full graphical user interface! But you can also ssh -P 2222 vagrant@localhost to login to the VM. Be sure to create your own account and to change all passwords!
Your Linux distribution may have problems performing SHA2 calculations correctly. According to this source, it’s “Because apt use sha256 method from libgcrypto20, but optimized too much. We can deny this opt. using configuration file /etc/gcrypt/hwf.deny.”
$ sudo bash
# mkdir /etc/gcrypt
# echo all >> /etc/gcrypt/hwf.deny
In addition, we learned that in our nested situation (VirtualBox on top of Hyper-V) it may be a good idea to change your VM's "paravirtualization interface" from "Normal" to "Minimal". #TIL that this is not about how VBox provides better performance, but about what paravirtualization information is passed to the guest OS. In my case this change did fix hashing problems. This change can be made manually by editing the VM settings in VirtualBox (VM → Settings → System → Acceleration → Paravirtualization interface), or in the Vagrant file:
vb.customize [ "modifyvm", :id, "--paravirtprovider", "minimal" ]
Vagrant.configure("2") do |config|
config.vm.define "kali" do |kali|
kali.vm.box = "kalilinux/rolling"
kali.vm.hostname = "haxor"
kali.vm.network "forwarded_port", guest: 22, host: 2222, host_ip: "127.0.0.1"
kali.vm.network "forwarded_port", guest: 3389, host: 2389, host_ip: "127.0.0.1"
kali.vm.provider "virtualbox" do |vb|
vb.gui = true
vb.memory = "6144"
vb.cpus = 3
vb.customize [ "modifyvm", :id, "--paravirtprovider", "minimal" ]
end
kali.vm.synced_folder '.', '/vagrant', disabled: true
kali.vm.provision "shell", inline: <<-SHELL
echo "Here we would install..."
[[ ! -d /etc/gcrypt ]] && mkdir /etc/gcrypt
[[ ! -f /etc/gcrypt/hwf.deny ]] && echo "all" >> /etc/gcrypt/hwf.deny
SHELL
end
config.vm.define "centos8" do |centos8|
centos8.vm.box = "centos/8"
centos8.vm.hostname = "centos8"
centos8.vm.box_check_update = true
centos8.vm.network "forwarded_port", guest: 22, host: 2200, host_ip: "127.0.0.1"
centos8.vm.provider "virtualbox" do |vb|
vb.gui = false
vb.memory = "1024"
vb.cpus = 1
vb.customize [ "modifyvm", :id, "--paravirtprovider", "minimal" ]
end
centos8.vm.provision "shell", inline: <<-SHELL
echo "Here we would install..."
[[ ! -d /etc/gcrypt ]] && mkdir /etc/gcrypt
[[ ! -f /etc/gcrypt/hwf.deny ]] && echo "all" >> /etc/gcrypt/hwf.deny
SHELL
centos8.vm.synced_folder '.', '/vagrant', disabled: true
end
end
kilala.nl tags: work, sysadmin,
View or add comments (curr. 0)
All content, with exception of "borrowed" blogpost images, or unless otherwise indicated, is copyright of Tess Sluijter. The character Kilala the cat-demon is copyright of Rumiko Takahashi and used here without permission.