It's time to rethink OpenBSD security

OpenBSD is positioned as a secure OS. However, over the past few months, a number of vulnerabilities have been found in the system. Of course, there is nothing extraordinary about this. Although some vulnerabilities are quite unusual. You could even say critical. OpenBSD developers have several guidelines on how to ensure security. Here are two of them:

  • avoid mistakes;
  • minimize the risk of errors.

Not everyone agrees that these principles are enough to build secure systems. It seems to me that it makes sense to study whether the OpenBSD approach works, or if it is initially doomed.

For illustration, I did not select all, but only a few interesting bugs that accidentally coincide with the topic of our conversation.

libc auth


The auth functions run helpers without argv checking. Report . Patch .

This is a strikingly simple mistake, but it probably didn't seem too obvious during the code review. It seems to me, partly, the reason in some confusion is who is responsible for checking the input data. You can call each of the three components involved: a program, a library, or login_passwd - and it is reasonable to assume that someone else is checking. In the end, I think the library was found guilty, because it was for her that a patch appeared, but personally to me at first glance its code does not seem to be clearly wrong.

A more interesting part of the story is that even with the libc error mentioned, the login_passwd functionI wouldn’t be vulnerable this way if not for another bug. In 2001, login_passwd was rewritten to support kerberos, and maybe that's when they introduced what is the real cause of the error. A request-response type authentication offer (as in the s / key system) returns an authenticated state, not silence. Many years later, the kerberos code was deleted, but part of the code to support it remained, as well as the introduced error.

If the kerberos code were thoroughly cleaned, the authentication bug would still remain (there were some other related problems with argv parsing), but its effect would certainly be greatly reduced.

It is not easy to correctly parse argv in a security context. Many logical tips and approaches do not work here. I will only note that this vulnerability popped up afteranother discussion of the problem with file names on Unix / Linux / POSIX , although the leading minus (hyphen) does not really refer to the file name.

ld.so


Bad environment variables have not been removed from ld.so code . Report . Patch .

Something like a memory error. But no. The bug here is to link the success of one operation - splitting the environment variable - to deleting that variable. Very confident.

Of course, proponents of various typing systems will assure that they will process these operations in the correct order, but not the fact that this will help. C code did not crash due to a lack of error handling or because the memory allocation error remained invisible.

ftp


ftp follows redirects to local files. Report . Patch .

The NetBSD ftp redirect bug has long been a typical example of uncontrolled functions . And here again the same mistake (fortunately, with minor consequences)! Guys, well, sit at home. Do not add extra features to your programs.

smtpd from


smtpd cannot check some sender addresses. Report . Patch . Comment .

I think that everything is said in the commentary of Gilles, but I recall the background. Once upon a time, all mail was stored locally for each user in / var / mailin mbox files. This is not very cool, because there is a chance of damage if mua deletes the email while mda delivers a new one (not to mention other issues like distorting the From field). Therefore, the mbox file needs to be locked. But locking on a network file system does not work reliably. So instead of locking we use lock files. However, you need to come to an agreement on a specific blocking protocol, because the user owns the mbox files, and the root itself owns the directory. Thus, in order to actually modify the mbox file, you need to run the setuid helper function each time. Well, this is the first problem. Another relic of the old days is the mda settings, which can be used not just as a program, but as a shell pipeline. People prescribe something likespam-assassin | mail.mdaand you can’t just pass it on execve().

There are a lot of difficulties that are rooted in the past. And, unfortunately, this problematic code cannot simply be replaced. E-mail is used a long time ago, and very complex systems and workflows are built on its basis, so it is very difficult to simply cut one piece of code and paste a new one. Despite the varying levels of privilege segregation, a root-level parent process still relies heavily on its less privileged child processes. He will execute the commands and arguments that he will receive.

Avoiding this seems as simple as switching to the maildir storage format, but it requires various changes in many places. Standard mua maildoes not understand this format. As for me, mbox has long outlived its life, but it still suits many people, and the update procedure may not be completely transparent and will not work automatically.

smtpd read


Reading outside the scope in smtpd can be used to execute commands. Report . Patch .

This is really a memory security issue. By sending some funny status bars, the remote smtp server can inject commands into the smtpd queue for execution. When an email is queued for re-delivery, smtpd adds some destination information to the header to know which command to execute (see above). This attack is similar to the “smuggling” of http requests . If you can generate a “shit” with unexpected commands in the header, smtpd will execute them when you try to re-deliver.

As above, one of the problems is that the most sensitive parts of smtpd are too close to the attack surface. It seems to me that the real problem is that smtpd stores its own metadata inside email data. Because of this, a parsing out of sync attack becomes possible. If the quoted response from the server was stored completely separate from the file with the delivery instructions, then reading outside the borders would not do much harm.

This vulnerability seems indicative to me, because here we see the danger of mixing data with different levels of trust. This danger has never been discussed. And she definitely is.

findings


Of course, the conclusion was clear from the very beginning, but we’ll talk about it anyway.

I think some of these errors help to demonstrate how principles such as removing obsolete interfaces and reducing code complexity are vital to security . For the most part, the failure occurred due to the fact that these principles were not followed up to the end, and not because the principles themselves are spoiled or untenable. Some things are slipping out of sight, but I don't agree that developers need some kind of superhuman vigilance. It is easy to give useless advice, such as be careful, do not make mistakes and git gud [slang gamer expression means 'get good', that is, “get better, get well soon” - approx. trans.]. But I think OpenBSD has more serious problems.

Even OpenBSD can risk security for utilitarian practicality. That is why some outdated projects have not been amended for a long time. So, perhaps the lesson is that effective principles should always be followed, and not only when it is convenient. Although it is often difficult to make the right choice.

The three most serious vulnerabilities, auth and two smtpd, are more or less suitable for exploitation only because of architectural problems that go beyond the scope of the original bug. They should have remained just minor flaws that demonstrate that in a well-protected system it is not necessary to strive for the perfect code, that is, minor errors are permissible - and they do not affect security. Alas, it can be difficult to identify design flaws in an abstract form. And all parts of the system individually look protected, but if they are combined, weaknesses may appear.

Separation of privileges is a key component of OpenBSD security, and it is based on interprocess communication. It makes sense to take a closer look at what problems may arise with damaged processes. Protected browsers are increasingly reinforcing protection and hindering attacks. In particular, smtpd must be protected against memory corruption in network tasks. But the ease with which he is able to control the parental process is alarming.

Only one mistake could be prevented using a more secure language. Yes, probably, there is some kind of program idiom, which in some cases can help if you follow it with religious perseverance. But I'm not sure yet that by default every programmer will correctly encode all the corresponding invariants.

Writing a mail server is a tricky business. Especially if legacy frames are tightening you.




All Articles