How To Conduct Your Very Own Buffer Overflow
Adam writes "If you've ever wanted to create your own buffer overflow or just to see how one works, check out this tutorial. The article talks about how a buffer overflow works and gives a guided example through an exploit to help you on your way. Definitely worth checking out." From the article: "Every now and again we all hear about an exploit that takes place thanks to a buffer overflow, but what is a buffer overflow? By definition it is when a program attempts to store more data in an array (buffer) than it was intended to hold, thus overwriting the return address of the function. To show how this is actually done, I'll explain how to do a simple attack on a fairly small program."
Zonk posts a story from a submitter that wrote the page being submitted for the story, who, as it turns out, blatantly plagarized the content from Bryant and O'Hallaron's Computer Systems book.
As a matter of fact, on the webpage itself, the very first response to the post calls Adam out about this, but apparently, it is still suffficiently 'news' to merit posting here.
Way to go, Zonk...once again, you've lowered the standard.
the author of the article states: "-o tells gcc to compile the file"
but fortunately he didnt write the example, its taken from Bryant and O'Hallaron's Computer Systems.
-mr silver
By imposing array bound checking at every operation? I know that the check is redundant for a tight linear algebra loop that is obviously bug free, but I think that I'm in a position to mandate that all these people take the penality hit just because I like the idea of imposing my view on people that are smarter than me. Oh yeah and mandate training wheels on all bicycles too.
This kid is just trying to drum up visitors to his site. The site itself is pretty much devoid of content and the code is taken without citation.
DJ Bernstein Will Tell You Why
Among my favorite advice of his is to completely give up on the standard C library. Really, everybody should have done it a while ago. It's one of those things like the unix pipe model that was a good start, but now that it has hung around for 25 years, it needs an upgrade. How about everybody stop using the standard C library and switch to something like the Apache Portable Runtime?
Write bug-free code. I've mostly given up on the standard C library. Many of its facilities, particularly stdio, seem designed to encourage bugs. A big chunk of qmail is stolen from a basic C library that I've been developing for several years for a variety of applications. The stralloc concept and getln() make it very easy to avoid buffer overruns, memory leaks, and artificial line length limits.
How aboutGood enough?
Yeah, I know. You're wondering, "why that trailing 1"? It's because Perl explicitly checks for the boneheaded maneuver of dereferencing NULL in an unpack and prevents it. Of course (as the docs point out), there's not much it can do to prevent you using this particular tool to shoot yourself in the foot.
I've been hearing about reuse of code and the development of stable shared libraries for the past 20 years and its probably been going on for longer than that. Why don't people, especially OS and application people, create, debug, and reuse a set of overflow-proof buffer-handling libraries? The libraries could include a range of forked versions for different usage patterns (e.g., big buffers of small data objects, small buffers of big data objects, buffers optimized for variable or fixed size, buffers optimized for frequent writes/sorts/reads/etc. Why is that so hard?
Every buffer-overflow exploit is just evidence of re-invention of a bug-filled wheel.
Two wrongs don't make a right, but three lefts do.
This is a buffer overflow, but not all overflows will trample on the stack causing unexpected code execution.
The main problem with buffer overflows wrt security vulnerabilities is that an overflow has the potential to "return" to a block of code that what not where it was called from
e.g.
overflowBuffer = {binary code that executes a new program + padding bytes}{return ip address that points back to the address of stack buffer that is about to be overflowed}
memcpy(buffer to overflow, overflowBuffer, bytes needed);
In this example, a deliberate byte pattern is copied to the buffer to be overflowed that causes the computer to jump back to that spot when the function returns and that allows dynamic code execution through that vulnerability.
While your overflow demonstrates the capability of a language to overflow a specific buffer, not all overflows are unwelcomed.
for example, I'll often define a struct as follows:
struct {
int setting;
int sequenceCount;
int otherVariables;
int bytes;
char buffer[1];
} data;
I'll then do this
ptr = (struct data *)malloc(sizeof(struct data) + bufferBytes);
memcpy(ptr->buffer, source, bufferBytes);
ptr->bytes = bufferBytes;
I've implemented this trick for my own PVR recording program I wrote that reads from the video capture card and stuffs it in a fifo.
In this case, buffer overflow is desired as it allows me to allocate an arbitrary number of bytes that follows a specific structure.
In any case, you've missed the point.
Actually I didn't miss the point. I could have made a far more elaborate program that actually did demonstrate that very fact, but I didn't want to spend 20 hours writing the damn thing then post 20 hours later when everybody else moved on.
If you look at the memset before the function call, I set the entire 8k buffer to zeros, and then when I call overflowMe(), I copy 8k - 256 bytes beyond the 256 byte local buffer, extending well past over the return address. A fact that I even commented at the start of the function. That the return address is reset to 0x00000000.
The purpose was not to actually give a working example of a successful exploit but to give an example of how it could be done.
I know full well that I what I need to do is to put the machine code for the 'malicious' code in the actual buffer and to keep overflowing with nop instructions for the proper number of bytes so the final 4 bytes I copy into that overflowed buffer on any intel 32bit processor will align with the return address from that function and if it is set correctly by taking into account the proper stack trace, can be known beforehand and thus when the function returns, it resumes execution of code at the start of the buffer that you overflowed.
That point was not lost on me.