Fix the Bugs, Secure the System
LiquidPC writes: "OpenBSD's Louis Bertrand has put his MUSESS 2002 presentation online, entitled
Fix the Bugs, Secure the System. Does an overview of OpenBSD, then explains Format String Ugliness, Buffer Overflows, The Wrong Way to Fix Overflows, along with numerous other things."
It was a bit tedious flicking through all those slides but the final one did bring a smile to my face.
But then I guess producing a high quality operating system keeps then busy enough...
Programming can be fun again. Film at 11.
Just becomes something does something in error doesn't mean its exploitable. If say the newest OBSD distrib forgot to provide a copy of disklabel, that's a pretty serious bug. You can't do a fresh install. A denial of service? Hardly. If the /etc/services file was missing an entry for httpd, it's an inconvenience, but still a bug.
Maybe I've been trolled, but thought I'd clear that up. A bug is an error in that a piece of functionality isn't right. An exploitable program or process can be a subset of it... that is, if being exploitable isn't part of the original plan.
-
ping -f 255.255.255.255 # if only
Just searching for 'OpenBSD Bug' on Google Groups retrieves over 20,500 queries.
Searching for "Brian bug" on Google shows 441,000 hits. Clearly you're 20 times buggier then OpenBSD, so I wouldn't be slinging implied accusations around.
What's the point of a rock-solid operating system if very few are actually using it (and of course, that happens because of lacking features)? For a server security is always the second issue - the first being the service provided.
(I'm definitely exagerating here, so flame me as you like)
The Raven.
The Raven
One of the problems with secure programming is the inertia in the computer industry; most of the operating systems in widespread use today (The *nix clones and DOS derivitives, these days) we developed in a time when security did not matter; *nix has a crude root-or-not security model and MS-DOS has no conception of security at all.
Personally, I think the solution is a model which has a real security model, such as EROS. The "audit the code so that it is perfect code without bugs" approach to security does not always work, even with OpenBSD.
- Sam
The secret to enjoying Slashdot is to realize that it should not be taken too seriously.
The skeleton in front just left of the middle? The one with a beak and wings?
:-)
That was a penguin.
with the same technique, searching for '"OpenBSD bug"' (note the quotes) returns only 93 results.
but this is only using the same yard stick.
beat yourself which ever way you want.
Note that this was google groups, by the way, not generic google search.
on the generic google search, with quotes, the total results are 352 for "openBSD bug"
"It is a greater offense to steal men's labor, than their clothes"
While we're on this topic, this Secure Programming HOWTO for Linux and UNIX might be of interest. It's a pretty comprehensive book. And best of all, it's free! :-)
granted, a non-executable stack makes it significantly harder to exploit a buffer vulnerability, but it's not impossible. you can also put your shellcode in environment variables, in the heap, or various other places. if you wanted to follow your line of reasoning to completion, you'd have to have an isolated code segment, marked read-only, and everything else marked non-executable. of course, then we have the issue of how to handle run-time dynamic loading, and programs like vmware--pretty much anything that gets machine code from a source outside of itself and the libraries that are linked in at compile time.
i do agree with the idea of a non-executable stack, though. it's just regarded far too often as a panacea for buffer overflows.
#define F(x) int main(){printf(#x,10,#x);}
F(#define F(x) int main(){printf(#x,10,#x);}%cF(%s))
If this had been converted from presentation-style to an actual webpage, it would have been deemed a big waste of time. Where is all the information? There isn't even anything new here, I already knew everything there, and I've only been using OpenBSD for a couple weeks.
The only thing there was a long list of titles with no information, old or new.
Lack of eloquence does not denote lack of intelligence, though they often coincide.
Why is it that when MSFT does something like stopping to fix bugs and secure systems, we make fun of them, but if it's BSD we look at it as something we can learn from?
Standard buffer overflow exploits don't execute the stack. The most common form (so-called single instance exploits) alter the return point from a subroutine so that a particular command (also stored by the malicious code) gets executed. (E.g. in a Unix system, the attacker climbs around until he finds a call to exec, and branches to the exec with a call to /bin/sh in the right place on the stack.) The second most-common form consists of exploits that cause a function pointer to be replaced in a heap variable. Even if these exploits required the insertion of executable code -- and I don't know of any cases where they do -- a non-executable stack won't help against a heap attack.
I'm a CS major, and we just got some sample code from the professor to help us on our first project. The very first thing it does in main is have a buffer overflow.
// BAM!!
#define SZ 100;
char buf[SZ];
cout << "Enter courses filename: ";
cin >> buf;
This is C++! We have the string datatype for this! There's absolutely no excuse for this--especially in code that will be referenced as "good" code by everyone else in the class.
So anyway, the point of this rant is that security will remain horrible until we start teaching people to write securely in the first place.
~~~LXT~~~
Life is like a computer program: anything that can't happen, will.
But no one actually believes C is a good language?
C is a great language for the thing it was designed for -- system level (ie OS) programming. It turns out that it is mostly decent (and at least functional) at other programming tasks, and this helped it become ubiquitous.
Most of the problems in C that arise at the system level are a function of the standard library that it came with. For example, strcpy() should have never existed.
As to whether or not C is any good anywhere else... *shrug*. Minus easy-to-use regexp's, I think once you learn how to write good C code it can be a "good" language for just about anything. Still, I'm not saying I wouldn't mind seeing Java become more common in applications... So long as I can get a good static compiler and libraries for it.
The enemies of Democracy are
strcpy (dest, input); /***WHAM!***/
Here the code copies the input string to the destination, regardless of what size the input string is.
if (strlen(dest) => MAXLEN) {}
Here the code checks to see if the input data is larger than the buffer that it is being copied to, which is great and all except that it is being done AFTER the cpy took place. It's like drinking a bottle of clear liquid in a chemistry lab and THEN checking the label to see if it's sulfuric acid.
I'm no C expert either, so I may have missed something.
Computer Science is no more about computers than astronomy is about telescopes. --E. W. Dijkstra
I can't believe there is not one mention of using a language other than C. Is it the systems community? Is it because of BSD's history?
I don't know why this idea fails to even come up. Network servers are bandwidth-limited, not cpu limited, and writing them in a safe high level language is not only easier, but makes buffer overflows impossible. Being easier to write also of course allows more time for optimization and for other security fixes. (For those that need really high-performance for their gigabit links, maybe a C version and very careful maintenance is possible. For home users, this prospect is ridiculous.)
C seems almost *designed* to allow for buffer overflow exploits. If we want secure programs, we should be starting from more secure foundations!
For more detail, check my previous rant, "C lang remains inappropriate for network daemons": http://slashdot.org/comments.pl?sid=24271&cid=2629 013
For x86 with standard stackframe setup, there is an answer: length _MUST_ be less than (EBP - *ptr) if the stack isn't to be trashed. Note that other local data may well get trashed. But at least the pgm doesn't lose control.
The wrapper could drop early chars or trailing chars, but should signal an error in the unlikely event the code has been made with error trapping. Of course, this wouldn't work if the code was compiled with -fomit-frame-pointer [or equivalent], but there is a price for security.
I don't agree with your assessment that safe high-level languages necessarily perform badly. (What is the difference between speed and performance?) But, let's forget about that.
What is "OS-level" about an ftp daemon? BIND? Mozilla? Gnutella? All sorts of network (and other) applications are written in C, even though there certainly isn't any need for performance or device-level bit manipulation. (At least, I would place security way above performance!)
Cyclone is actually from Cornell, by the way. It's a good project for moving systemsy people away from C, but there are already mature programming languages that are not slow, and yet are secure by default. (Try SML or O'Caml, for instance.)
What? I don't think you know what you're saying. In any modern operating system, it's not possible for one process to write over the memory of another. Furthermore, saying that this is a Java exploit when it necessitates another process in another language is totally missing the point.
If a hacker exploited one process this way, then why would he bother to exploit the java program rather than just execute whatever code he plans on executing?
You are still totally wrong and I WILL be surprised if something like that happens.
The reason for all this bufferoverflow crap is that in C, and thus also in C++, people tend to use arrays or blocks of allocated memory to represent strings. What's needed is a string datatype IN the language, like int and char. Then, the compiler can do as the CLR does: allocate the strings, even local scope ones, on the heap. This way, no buffer overflows can happen, since the type is in fact a black box, so the overflow will cause some kind of error, plus the overflow can't be used to modify the stackframe and thus the returnaddress, since the string variable isn't allocated on the stack.
In C++, there is the string class in the std lib, but it's not native to the language. (almost native ok, but not totally like in C#).
C is a language where the respect for the borders of a block of memory is in the hands of the developer. Clearly, that's too old fashioned today, since languageelements can prevent mistakes C allows developers to make.
Never underestimate the relief of true separation of Religion and State.
Learn it in Python. Really. Python 2.2 offers a whole host of lovely functional-programming features. Continuances, even. :)
I prefer to write functional code in LISP or Scheme, but I won't sneer at someone who uses Python functionally. It might lessen the learning curve for you, let you experiment around with functional programming, and then use what you learn there in Scheme, LISP or Ocaml.