user1685041
user1685041

Reputation: 11

What is vulnerable about this C code? (Integer...)

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

#define MAX 3
#define ARG "cat .passwd"
integer main( integer argc, char ** argv )
{
char * names[] = {"strlen", "atoi", "printf", "puts"};
void (*reachable_functions[])( char * ) = {strlen, atoi, printf, puts};
void (*unreachable_functions[])( char * ) = {system};
integer i, index = 0;

for( i=1; i<argc; i++ )
{
    index += strlen(argv[i]);
}

if( index <= MAX )
{
    (reachable_functions[MAX-1])( "Calling ");
    (reachable_functions[MAX-1])( names[index] );
    (reachable_functions[MAX-1])( ".\n" );
    (reachable_functions[index])( ARG );
}
else
{
    (reachable_functions[MAX])( "Out of bounds !\n" );
}

return 0;
}

I can get a Segmentation Fault but impossible to call the unreachable function !?! I know there is a problem with the Integer but i can't exploit it.... :( Is there a way to call it ? Thx

Upvotes: 0

Views: 996

Answers (1)

Daniel Fischer
Daniel Fischer

Reputation: 183968

If you pass enough arguments of sufficient length, the sum of the lengths can overflow (not sure whether the shell can in fact handle such arguments if the integer type is 32 bits, but should work for 16-bit integers).

Overflow of signed integers (I suppose integer should be int) is undefined behaviour, so what happens in that case depends on the compiler and platform (and possibly the phase of the moon), but the sum might wrap around to a negative number. In that case, depending on how the compiler arranged the arrays, the call

(reachable_functions[index])( ARG );

could actually call the "unreachable" function. That's more undefined behaviour, indexing an array with a negative index, but it's a possible exploit.

To prevent that exploit (as far as the undefined behaviour allows), one could cast index to an unsigned type in the comparison,

if( (unsigned int)index <= MAX )

in all reasonable implementations, where the width of unsigned int equals that of int, that guarantees that index is indeed nonnegative (again, with the caveat that after undefined behaviour has occurred, the standard guarantees nothing anymore about the programme's behaviour), since then negative numbers are converted to numbers larger than INT_MAX.

If one is paranoid, one could also cast in the indexing operation.

Upvotes: 3

Related Questions