这个C代码容易受到什么影响? (整数...)

时间:2012-09-20 06:45:36

标签: c linux exploit secure-coding

#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;
}

我可以获得分段错误但无法调用无法访问的功能!?! 我知道整数有问题,但我无法利用它...... :( 有办法打电话吗? THX

1 个答案:

答案 0 :(得分:3)

如果你传递了足够长度的足够的参数,长度的总和可能会溢出(如果整数类型是32位,不确定shell是否实际上可以处理这样的参数,但是应该适用于16位整数)。 / p>

有符号整数的溢出(我认为integer应该是int)是未定义的行为,所以在这种情况下会发生什么取决于编译器和平台(可能还有月亮的相位),但是总和可能会换成负数。在这种情况下,根据编译器如何排列数组,调用

(reachable_functions[index])( ARG );

实际上可以调用“无法访问”功能。这是更加未定义的行为,索引具有负索引的数组,但这可能是一种利用。

为了防止这种攻击(就未定义的行为而言),可以在比较中将index转换为无符号类型,

if( (unsigned int)index <= MAX )

在所有合理的实现中,unsigned int的宽度等于int的宽度,这可以保证index确实是非负的(同样,在发生未定义的行为之后需要注意,标准不再保证程序的行为,因为那时负数转换为大于INT_MAX的数字。

如果一个是偏执狂,也可以在索引操作中进行投射。