I don't understand this security hole.

This is a discussion on I don't understand this security hole. within the C Programming forums, part of the General Programming Boards category; Here is the buggy c code Code: include <stdio.h> #include <stdlib.h> #define MAX 8 int main(void) { char namebuf[MAX]; printf("Enter ...

  1. #1
    Registered User
    Join Date
    Jan 2006
    Location
    Berkeley, Ca
    Posts
    195

    I don't understand this security hole.

    Here is the buggy c code

    Code:
    include <stdio.h>
    #include <stdlib.h>
    
    #define MAX 8
    
    int main(void) {
    
        char namebuf[MAX];
    
        printf("Enter your name: "); fgets(namebuf,5,stdin);
    
        printf(namebuf);
    
        return 0;
    }
    $gdb over
    GNU gdb 6.1
    Copyright 2004 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB. Type "show warranty" for details.
    This GDB was configured as "i586-suse-linux"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

    (gdb) run
    Starting program: /home/cdalten/over
    Enter your name: %s

    Program received signal SIGSEGV, Segmentation fault.
    0x400913cb in strlen () from /lib/tls/libc.so.6
    (gdb) bt
    #0 0x400913cb in strlen () from /lib/tls/libc.so.6
    #1 0x40066c76 in vfprintf () from /lib/tls/libc.so.6
    #2 0x4006c310 in printf () from /lib/tls/libc.so.6
    #3 0x0804842f in main () at over.c:12
    (gdb) q
    The program is running. Exit anyway? (y or n) y

    I know the bug is in this line
    Code:
    printf(namebuf);
    It has something due with the fact printf() has been passed an unchecked string. But that is about is. Would someone care to enlighten me on what is going on?

  2. #2
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,658
    printf was designed to validate format strings and write. You could type
    Code:
    printf("%8s", namebuf);
    or if it makes no difference whether a newline is there
    Code:
    puts(namebuf);

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    Code:
    printf("%8s", namebuf);
    or just
    Code:
    printf("%s", namebuf);
    If you call printf() like
    Code:
    printf("%s");
    (which is what your code does if you enter "%s"), it will see the %s in the format string and expect a char pointer. It will get 4 bytes* off the stack, assuming it's a char pointer. But it;s really garbage, whatever happened to be there, because you didn't pass a char pointer to printf().

    * On a 32-bit machine.
    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.

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    Registered User
    Join Date
    Mar 2006
    Posts
    725
    If I manage to get some shellcode into the program stack/heap, I could exploit your format string (if it is user-accessible) and try to get the CPU instruction register to point to my shell code and execute it. If the shellcode opened remote shell access to me on your server, you're practically *splat*.
    Code:
    #include <stdio.h>
    
    void J(char*a){int f,i=0,c='1';for(;a[i]!='0';++i)if(i==81){
    puts(a);return;}for(;c<='9';++c){for(f=0;f<9;++f)if(a[i-i%27+i%9
    /3*3+f/3*9+f%3]==c||a[i%9+f*9]==c||a[i-i%9+f]==c)goto e;a[i]=c;J(a);a[i]
    ='0';e:;}}int main(int c,char**v){int t=0;if(c>1){for(;v[1][
    t];++t);if(t==81){J(v[1]);return 0;}}puts("sudoku [0-9]{81}");return 1;}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can you find a hole?
    By axon in forum A Brief History of Cprogramming.com
    Replies: 23
    Last Post: 08-29-2004, 03:01 PM
  2. Security on automated home
    By stimpyzu in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 04-11-2004, 01:14 AM
  3. Painfully true but funny...
    By shaik786 in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 04-01-2003, 02:39 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21