Reputation: 11
#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
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