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."
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.
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! :-)
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.
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
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.
Try the Secure Programming for Linux and Unix HOWTO
It explains the basics of secure programming and common problems with a variety of programming languages including buffer overflow and many more tricky problems.
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.