3 ms·
And OpenBSD is doing this because? (Presumably it reduces attack surface by getting exploits in the session out of the listener but does it have greater signif
by Affric 2y ago
And OpenBSD is doing this because?
(Presumably it reduces attack surface by getting exploits in the session out of the listener but does it have greater significance?)
- ainar-g 2y agoPrivilege separation[1], most likely. If your system needs to do three things, it could either just do all of them using a single executable requiring all three permissions (thus also theoretically allowing an attacker to use it to do all three things as well) or split your system into three executables, each only having the permission to do one thing (thus reducing the amount of potential damage). [1]: https://en.wikipedia.org/wiki/Privilege_separation https://en.wikipedia.org/wiki/Privilege_separation
- ape4 2y agoYes, the main daemon needs to run as root so it can become any user. Once you're logged in you just run as a regular user.
- crest 2y agoYes and no. At least one process needs to run as root to be able to become any (other) user. It doesn't have to be the one accepting incoming connections, or the one handling user authentication and authorisation. OpenBSD already contains several examples of this e.g. OpenBGPd limits the attack surface by putting the BGP session handling (and protocol parsing) in one process running with reduced privs (dedicated user and group, chroot(), pledge()/unveil()). To communicate with the other processes the parent creates unix socket pairs to be inherited. The children also re-exec after fork() so they're re-randomised and can't be abused as oracles for the memory layout of other processes.
- Brian_K_White 2y agoThe last sentence in the article seems like a clue.
- m000 2y agoAssuming that baseline protections (ASLR, DEP/Nx etc.) are present, the goal when pruning parts of a binary is probably to reduce the availability of ROP gadgets [1]. This will make it harder to exploit any remaining bugs in the "useful" code. OpenBSD appears to be taking a safe/conservative approach based on linking. More aggressive approaches have also been researched, where the pruning is driven by dynamic analysis, and applied using binary rewriting. [1] https://en.wikipedia.org/wiki/Return-oriented_programming https://en.wikipedia.org/wiki/Return-oriented_programming
- throw0101c 2y ago> More aggressive approaches have also been researched, where the pruning is driven by dynamic analysis, and applied using binary rewriting. Any place(s) one can read more about this research?
- crest 2y agoThis LWN article could be a good starting point: https://lwn.net/Articles/959562/ https://lwn.net/Articles/959562/ The best source for the history of the work are probably the OpenBSD mailing list archives and commit logs, but digging through that is slow and requires context.
- m000 2y agoOff the top of my head I can remember BinREc [1]. I believe I have seen more papers along the same lines, but I can't recall the details. [1] https://bibbase.org/network/publication/kroes-altinay-nash-na-volckaert-bos-franz-giuffrida-binrecattacksurfacereductionthroughdynamicbinaryrecovery-2018 https://bibbase.org/network/publication/kroes-altinay-nash-n...
- crest 2y agoOpenBSD recently added a bunch of new security mitigations most hardening processes against remote code execution. As of the latest release (OpenBSD 7.4) the runtime linker registers all system call entry points per memory mapping with the kernel (offset in the mapping + the system call number). They also removed the indirect system call (where the syscall number is the first argument). With this in place a process can only perform those system calls still allowed by its pledge()+unveil() for which there exists an entry point. If dead code elimination removed all fork() and exec() syscalls from your process your attack won't be able to turn the compromised process into a (useful) reverse shell. The idea appears something like this: You have a very small TCP listener that probably that forks+execs per accepted connection. The reduced complexity of this piece makes it both easier to audit and harder to exploit. * The per session binary only contains the code to handle authentication and authorization (and accounting) of a single connection and fork/exec() into the next stage. * The listener could also re-exec() itself every so-and-so number of connection attempts to replace its image with a newly randomised instance of the same executable. This would limit the number of attempts an attacker has to reuse any information learned about the current listener process's memory layout should such a leak be found. The goal is to provide defense in depth instead of a single "magic bullet" e.g. rewriting it a "safe language" (trading new logic bugs in new code against memory safety bugs not yet found in old code). Splitting the OpenSSH server into multiple smaller processes also allows existing mitigations (some of them OpenBSD specific) to become more effective.
- yjftsjthsd-h 2y agoMeta: To write a literal * character on HN, you want to escape it as \*
- sillywalk 2y agoIn addition, it says that, like sshd before, sshd-session will be randomly re-linked on boot/upgrade (along with the kernel and libc I believe) and so have different addresses.