| 
                  Buffer Overflows in C
                   Vulnerabilities, Attacks, and Mitigations  | 
            
| 
                   
                      
                     Prof. David Bernstein
                       | 
            
| Computer Science Department | 
| bernstdh@jmu.edu | 
               
            
         
            
         
         
            
         main(int argc, char* argv[]))
              
         
            
         array is a parameter and, so, is a 
              pointer typesizeof(array) is the size of an
              int *, not the size of the array
         
            
         -1 in an array of non-negative
              integers)
         
            
         char and
              wchar_t
                     '\0')gets()
         
         
            
         gets() to read characters (until it reaches a
              newline or end-of-stream character)strcpy()
         
         
            
         strcpy()
                     strcat()
         
         
            
         strcat() to append a source string to
              a target stringsprintf()
         
         
            
         sprintf() to create a (formatted) stringsprintf() assumes that the buffer it is passed
              is large enough and the attacker might provide a string that 
              is too long (i.e., longer than 80 - 2 - 2 - 1 = 75 
              characters in this example)
         
            
         strncpy() to copy the first  
              n characters
              from the source to the target when the source contains
              n or more characters (which results in a non-null
              terminated string)strlen() uses the null character to determine the
              length of the string so any function that uses 
              strlen() will have problemsstrcpy()) iterate until
              a null character is encountered so will have problems
         
            
         
         
            
         
         
            
         
         
            
         
         
            
         
         
            
         Address of       eid: 0x0804a030
                     Address of     grade: 0x0804a024
                     
         
            
         eid only requires 9 bytes, space
              actually exists for 12 (for alignment reasons)
        
         
            
         foo: 00401000 bar: 00401045 Stack (Before): 00000000 00000000 7FFDF000 0012FF80 0040108A 00410EDE
  If you compile using gcc -S smash.c a file containing
  the assembly language code (named smash.s) will be generated.
  
  If you compile using gcc -o smash smash.c and then 
  run gdb smash you can use the command 
  disassemble main to see the assembly code that will be
  executed (i.e., with resolved addresses).
  
         
            
         "Hello"
            Output Interpretation foo: 0x00401000 bar: 0x00401045 Stack (Before): 0x00000000 0x00000000 0x7ffdf000 0x0012ff80 0x0040108a The return address for foo() 0x00410ede Stack (After): 0x6c6c6548 lleH 0x0000006f o 0x7ffdf000 0x0012ff80 0x0040108a The return address for foo() 0x00410ede
         
            
         "AAAAAAAAAAAAAAAAAAAAAAA"
            Output Interpretation foo: 0x00401000 bar: 0x00401045 Stack (Before): 0x00000000 0x00000000 0x7ffdf000 0x0012ff80 0x0040108a The return address for foo() 0x00410ede Stack (After): 0x41414141 AAAA 0x41414141 AAAA 0x41414141 AAAA 0x41414141 AAAA 0x41414141 AAAA (And the return address for foo()!) 0x41414141 AAAA
         
            
         
         
            
         
         
            
         "StaticOverrun ABCDEFGHIJKLMNOP\x45\x10\x40"
            Output Interpretation foo: 0x00401000 bar: 0x00401045 Stack (Before): 0x77fb80db 0x77f94e68 0x7ffdf000 0x0012ff80 0x0040108a The return address for foo() 0x00410eca Stack (After): 0x44434241 DCBA 0x48474645 HGFE 0x4c4b4a49 LKJI 0x504f4e4d PONM 0x00401045 The address of bar() (and the return address for foo()!) 0x00410eca
         
            
         system() or exec()).
         
            
         
         
            
         
         
            
         
         
            
         std::basic_string)memcpy() and use
              memcpy_s() instead (C11) -- specifies the size and 
              reports violations with the return value; reports  
              NULL destination; reports the 
              copying of overlapping segmentsmemmove() and use
              memmove_s() instead (C11) -- specifies the size and
              reports violations with the return value; reports
              NULL destinations 
         
            
         std::basic_string)gets(), use fgets()
              and/or getchar() (which are still vulnerable,
              but better) or gets_s() (C11)strcpy() and strncpy() 
              (which have different vulnerabilities) and use 
              strcpy_s() instead (C11)strcat() and strncat() 
              (which have different vulnerabilities) and use 
              strcat_s() instead (C11)
         
            
         
         
            
         size_t __builtin_object_size(void* ptr, int type)
                     
         
            
         type determines what is considered
              the "end of" the entity
              type is 0 or 2 then 
              size_t __builtin_object_size(p, type) returns
              sizeof(int) plus 20 (i.e., the size to the end
              of a; the maximum remaining size)type is 1 or 3 then 
              size_t __builtin_object_size(p, type) returns
              sizeof(int) (i.e., the size to the end
              of a.id; the minimum remaining size)
         
            
         _FORTIFY_SOURCE is defined
         
            
         
         
            
         CR, LF, NULL
                     
         
            
         -fstack-protector-all flag/GS flag
         
            
         sysctl -w kernel.randomize_va_space
                     /DYNAMICBASE
              linker option
         
            
         
         
            
         
         
            
         /NXCOMPAT
                     
         
            
         
         
            
         -fno-stack-protector
                     -fno-defer-pop
                     su echo 0 > /proc/sys/kernel/randomize_va_space 
              (it normally contains the value 2)execstack -s
                     /GS