缓冲区溢出攻击的代码漏洞

问题描述 投票:0回答:3
#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;
}

此代码容易受到缓冲区溢出攻击,我正在尝试找出原因。我尝试了很多,但每个攻击代码都无法绕过“if”语句。

如何利用此代码?

c if-statement buffer-overflow
3个回答
2
投票

除了导致非空终止字符串的确切数字 40 之外,该程序还接受

-1
等作为输入。

read
又具有无符号
size_t
的参数,因此如果我输入
-1
那么
len
将转换为
0xFFFF...
- 一个非常大的数字。

最大的错误是将缓冲区大小声明为有符号整数。缓冲区的大小不能为负。它应该被声明为

size_t
并且输入应该通过
%zu
或更好地作为通过
fgets
和类似的字符串进行处理,然后进行解析和清理。


2
投票

len == 40
时,
read(0, input, len);
读取 40 个字符。
printf("%s", input);
尝试打印
input
,期望它是一个字符串。然而,input中肯定不再有
空字符
,因此
input
不包含 一个字符串

结果:未定义的行为(UB)。

不要使用

printf("%s", input);
,而是使用
printf("<%.40s>\n", input);
查看(不带 UB)读取的内容。


0
投票

类型一致性、适当的缓冲区长度和长度检查至关重要。例如,我建议进行以下更改:

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.