I had a job once which involved designing hardening procedures for systems that we were going to be use for security-related projects. It was fascinating. This was probably 15 years ago, and not only were guides a little thin on the ground for the Linux distribution I was using, but what we were doing was quite niche. At first, I think I’d assumed that I could just write a script to close down a few holes that originated from daemons[1] that had been left running for no reasons: httpd, sendmail, stuff like that. It did involve that, of course, but then I realised there was more to do, and started to dive down the rabbit hole.
So, after those daemons, I looked at users and groups. And then at file systems, networking, storage. I left the two scariest pieces to last, for different reasons. The first was the kernel. I ended up hand-crafting a kernel, removing anything that I thought it was unlikely we’d need, and then restarting several times when I discovered that the system wouldn’t boot because the things I thought I understood were more … esoteric than I’d realised. I’m not a kernel developer, and this was a salutary lesson in quite how skilled those folks are. At least, at the time I was doing it, there was less code, and fewer options, than there are today. On the other hand, I was having to hack back to a required state, and there are more cut-down kernels and systems to start with than there were back then.
The other piece that I left for last was just pruning the installed Operating System applications and associated utilities. Again, there are cut-down options that are easier to use now than then, but I also had some odd requirements – I believe that we needed Java, for instance, which has, or had …. well let’s say a lot of dependencies. Most modern Linux distributions[3] start off by installing lots of pieces so that you can get started quickly, without having to worry about trying to work out dependencies for every piece of external software you want to run.
This is understandable, but we need to realise when we do this that we’re making a usability/security trade-off[5]. Every utility, every library, every executable that you add to a system increases your attack surface, and increases the likelihood of vulnerabilities.
The problem isn’t just that you’re introducing vulnerabilities, but that once they’re there, they tend to stay there. Not just in code that you need, but, even worse, in code that you don’t need. It’s a rare, but praiseworthy hacker[6] who spends time going over old code removing dependencies that are no longer required. It’s a boring, complex task, and it’s usually just easier to leave the cruft[7] where it is and ship a slightly bigger package for the next release.
Sometimes, code is refactored and stripped: most frequently, security-related code. This is a very Good Thing[tm], but it turns out that it’s far from sufficient. The reason I’m writing this post is because of a recent story in The Register about the “beep” command. This command used the little speaker that was installed on most PC-compatible motherboards to make a little noise. It was a useful little utility back in the day, but is pretty irrelevant now that most motherboards don’t ship with the relevant hardware. The problem[8] is that installing and using the beep command on a system allows information to be leaked to users who lack the relevant permissions. This can be a very bad thing. There’s a good, brief overview here.
Now, “beep” isn’t installed by default on the distribution I’m using on the system on which I’m writing this post (Fedora 27), though it’s easily installable from one of the standard repositories that I have enabled. Something of a relief, though it’s not a likely attack vector for this machine anyway.
What, though, do I have installed on this system that is vulnerable, and which I’d never have thought to check? Forget all of the kernel parameters which I don’t need turned on, but which have been enabled by the distribution for ease of use across multiple systems. Forget the apps that I’ve installed and use everyday. Forget, even the apps that I installed once to try, and then neglected to remove. What about the apps that I didn’t even know were there, and which I never realised might have an impact on the security posture of my system? I don’t know, and have little way to find out.
This system doesn’t run business-critical operations. When I first got it and installed the Operating System, I decided to err towards usability, and to be ready to trash[9] it and start again if I had problems with compromise. But that’s not the case for millions of other systems out there. I urge you to consider what you’re running on a system, what’s actually installed on it, and what you really need. Patch what you need, remove what you don’t. It’s time for a Spring clean[10].
1- I so want to spell this word dæmons, but I think that might be taking my Middle English obsession too far[2].
2 – I mentioned that I studied Middle English, right?
3 – I’m most interested in (GNU) Linux here, as I’m a strong open source advocate and because it’s the Operating System that I know best[4].
4 – oh, and I should disclose that I work for Red Hat, of course.
5 – as with so many things in our business.
6 – the good type, or I’d have said “cracker”, probably.
7 – there’s even a word for it, see?
8 – beyond a second order problem that a suggested fix seems to have made the initial problem worse…
9 – physically, if needs be.
10 – In the Northern Hemisphere, at least.