Thread: Stack Smashing

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    19

    Stack Smashing

    Hello. I was playing around with gets(), specifically because its supposed to be insecure. The program accepts a string of 5 chars, and is only there for me to be able to play with what happens with an overflow. I compiled using gcc.

    When I executed the program it gives me a stack smashing detected error which I read is something gcc does to protect against buffer overflows. I was trying to see if I could issue the ls command so I wrote in abcdels.

    My question is this: If gcc did not protect against buffer overflows would this have worked? After entering my characters would I have gotten a directory listing? Thanks for any interesting discussion or topics that are related to this.

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,739
    When there's a buffer overflow, we enter the realm of undefined behavior, meaning that on different systems the outcome would be different. Speaking about the stack on x86 systems, the program may crash, or another variable may be overwritten.
    Devoted my life to programming...

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    No, the particular approach you are using (causing the letters "ls" to appear on the stack) will not magically cause ls to run. Explaining exactly how you could cause that to happen would probably be a violation of the forum rules.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Registered User
    Join Date
    Sep 2011
    Posts
    19
    Thank you both for answering, I definitely do not want to violate the rules of the forum. It was just a thought that popped in my head when fiddling around. Thanks for replying.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I don't think it's a violation of the forum rules to explain the basic flaw of a buffer overflow... I mean it's useful to know what can go wrong other than just saying "buffer overflows are bad". Of course we shouldn't be posting shellcode or anything like that but a general overview is a different story:

    Typically when you have a buffer overflow you'll be overwriting other variables on the stack or the actual stack frame information that you're inside (since the stack grows downwards, the frame will be at higher addresses). One way to exploit a buffer overflow is to overwrite the return address and get it to point inside the buffer you just filled in. You can then fill some of the buffer with code you want to have executed (e.g. the assembly code for execv("/bin/ls", NULL)). When the function goes to return it unthinkingly jumps to its return address, and now suddenly you're executing the data/code in the buffer.

    So basically a buffer overflow lets a user overwrite other variables and maybe program control information (like the stack frame). This is bad because the program may crash (really this is the best outcome, because nothing too bad happens and you may notice the problem); variables like did_the_user_enter_the_correct_password might get overwritten; and worst of all a malicious user may be able to start getting data executed as code.

    But the latter is hard to do, in the example I described above you'd need to juggle return addresses and generate some assembly code (and handle endianness) and feed it into the buffer. So when you just experiment with putting a few random characters in a buffer overflow, you're not going to see "ls" getting executed. (But trust me, if you have a buffer overrun someone could make this happen, if they tried hard enough.) You may however see either a program crash or other variables changing seemingly at random... quite a joy to debug.

    P.S. This is why you see technologies like "data-execution prevention". The real danger with buffer overruns is that somehow a malicious user can start executing data as code... because when that happens they could do anything at all.

    [edit] By the way, a lot of buffer-overrun detection works by putting sentinel values on the stack. Just before a function returns, it might check these values to make sure they haven't changed. If they're different then probably a buffer overrun accidentally went amok and smashed the stack... I don't know if this is what gcc is doing but it's one possibility. [/edit]
    Last edited by dwks; 11-15-2012 at 02:36 AM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    Registered User
    Join Date
    Sep 2011
    Posts
    19
    Thanks for the reply. That is very interesting stuff. Its so fascinating what consequences there can be to something that seems so small. So is there ever any reason to use a function like gets() instead of say fgets(), or is it just something that remains for legacy reasons? Thanks again.

  7. #7
    Registered User
    Join Date
    Nov 2012
    Location
    Some rock floating in space...
    Posts
    32

    Exclamation

    Quote Originally Posted by dtow1 View Post
    Thanks for the reply. That is very interesting stuff. Its so fascinating what consequences there can be to something that seems so small. So is there ever any reason to use a function like gets() instead of say fgets(), or is it just something that remains for legacy reasons? Thanks again.
    Try the -fno-stack-protector option and see what you come up with

    I doubt a simple string will result in a command being executed though

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by dtow1 View Post
    Thanks for the reply. That is very interesting stuff. Its so fascinating what consequences there can be to something that seems so small. So is there ever any reason to use a function like gets() instead of say fgets(), or is it just something that remains for legacy reasons? Thanks again.
    There is never a reason to use gets(), but you should keep in mind that you can easily write your own flawed functions with the same vulnerabilities. Any time you access memory in an array context you have the possibility of accessing something that doesn't belong to you. As we've pointed out, literally anything can happen if you do that. gets() remains in the language so that obsolete programs can still compile, but don't make the mistake of thinking fgets() is "safe" and gets() is not. You need to think clearly about all memory accesses. Just one of the facets of the language.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Stack Smashing Detected
    By halexh in forum C Programming
    Replies: 13
    Last Post: 05-19-2010, 02:10 AM
  2. *** stack smashing detected ***
    By chakra in forum C Programming
    Replies: 2
    Last Post: 06-09-2009, 09:12 PM
  3. Smashing The Stack
    By 0624167 in forum Linux Programming
    Replies: 1
    Last Post: 03-03-2009, 02:09 PM
  4. smashing the stack
    By rohit in forum C Programming
    Replies: 3
    Last Post: 10-07-2002, 07:06 AM
  5. smashing the stack
    By rohit in forum Linux Programming
    Replies: 1
    Last Post: 10-07-2002, 02:47 AM