0
#include <stdio.h>

int main(void){
  int len;
  char input[40]="";

  printf("input length : \n");
  scanf("%d", &len);
  if(len > 40){
    return 0;
  }
  
  read(0, input, len);
  printf("%s", input);
  return 0;
}

This code is vulnerable to a buffer overflow attack, and I am trying to figure out why. I tried a lot, but every attack code is failed to bypass 'if' statements.

How do I exploit this code?

6
  • Your code invokes undefined behaviour because input is not a nul-terminated string. You initialize as all 0 bytes, but if you read 40 bytes from the file, the nul-terminator is replaced with whatever comes from the file. But I wouldn't call that a buffer overflow. Commented Apr 19, 2024 at 6:41
  • What is read? I'm guessing the standard libc function, but then the appropriate header file appears to be missing (even if stdio.h includes e.g. unistd.h, it's not clear where read comes from). Commented Apr 19, 2024 at 6:47
  • Please note that your example code doesn't have any error handling, because you don't check return value of scanf. If I give invalid input, such as a, then program behave randomly because len is not initialized and will have random value. Commented Apr 19, 2024 at 7:59
  • @user694733 undefined value, not "random". Commented Apr 19, 2024 at 8:25
  • 1
    @Clifford If we avoid laymans terms and use words from the standard, I believe the correct term is indeterminate value. :) Commented Apr 19, 2024 at 8:54

3 Answers 3

2

Apart from the exact number 40 leading to a non-null terminated string, this program also accepts -1 etc as input.

read in turn has a parameter of unsigned size_t, so if I enter -1 then len will get converted to 0xFFFF... - a very large number.

The biggest mistake is to declare the buffer size as a signed integer. Buffers cannot have negative size. It should have been declared as size_t and input should have been taken with %zu or better yet as a string through fgets and similar, which is then parsed and sanitized.

Sign up to request clarification or add additional context in comments.

Comments

2

When len == 40, read(0, input, len); reads 40 characters. printf("%s", input); attempts to print input, expecting it to be a string. Yet there is not certainly a null character in input anymore and so input does not contain a string.

Result: undefined behavior (UB).

Instead of printf("%s", input);, use printf("<%.40s>\n", input); to see (without UB) what was read.

Comments

0

Type consistency, appropriate buffer lengths and length checks are critical. For example I would suggest the following changes:

int main(void)
{
  size_t len = 0 ;           // *** Correct type for read() length parameter
  char input[41] = "" ;      // *** Include room for nul terminator

  printf( "Input length : \n" );

  int cvt = scanf("%zu", &len);  // *** Correct format specifier for size_t
  if( cvt == 0 ||                // *** Check valid conversion of input
      len > sizeof(input) - 1 )  // *** Leave room for nul terminator 
                                 // *** And no "magic" number
  {
    return 0;
  }
  
  read( 0, input, len ) ;
  printf( "%s", input ) ;

  return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.