我的C ping脚本安全吗?

时间:2013-01-27 01:23:50

标签: c cgi

我刚用C语言为CGI写了一个ping脚本。

它按预期工作但我很确定它不安全,因为我认为用户输入是理所当然的。 我不知道是否有办法将一个命令拼接在一起,以便它仍然被识别?

有人知道如何利用我的脚本以及我应该如何解决它?

ping脚本来源

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

int main()
{
  printf("Content-Type: text/plain;charset=us-ascii\n\n");

  FILE* in = NULL;

  char buffer[100][100] = {};
  char server[100] = {};
  char concat_str[100] = {};

  char* ping = "ping ";
  char* option = " -c 4";

  int print_counter = 0;
  int read_counter = 0;

  char* query;
  query = getenv("QUERY_STRING");
  if(query == NULL)
    printf("ERROR\n");
  else
    sscanf(query,"server=%s", server);

  strcat(concat_str, ping);
  strcat(concat_str, server);
  strcat(concat_str, option);

  in = popen(concat_str, "r");
  if(in == NULL)
  {
    printf("ERROR\n");
    exit(1);
  }

  while(fgets(buffer[read_counter], 99, in) != NULL)
  {
    read_counter++;
  }

  pclose(in);

  if(read_counter != 9)
  {
    printf("ERROR\n");
    exit(1);
  }

  while(print_counter < (read_counter + 1))
  {
    printf("%s", buffer[print_counter]);
    print_counter++;
  }

  return 0;
}

html来源

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
</head>

<body>
<form action="http://xx.xx.xx.xx/ping.cgi">
<div><label>Server<input name="server" size="40"></label></div>
<div><input type="submit" value="start test"></div>
</form>

</body>
</html>

在相关的说明中,是否有一种简单的方法可以直接在此处发布源代码,而无需手动将其设置为4个空格?

2 个答案:

答案 0 :(得分:4)

  1. 所有字符串文字都应该是const。例如:const char *v = "value"const char v[] = "value"
  2. 您的sscanf可能会导致堆栈溢出。告诉它最多读取N个字符,它应该是安全的。例如:sscanf(query,"server=%99s", server);
  3. 在没有完全控制缓冲区的情况下调用strcat也可能导致堆栈溢出。请改用strncat。例如:strncat(concat_str, option, sizeof(concat_str)-strlen(concat_str)-1)
  4. 您的while(fgets(buffer[read_counter], 99, in) != NULL)也可能无限循环并访问buffer数组中的越界位置。您还应该检查read_counter是否在有效范围内0..99

答案 1 :(得分:2)

绝对不安全。 popen()函数将其参数传递给子shell,因此可以通过查询字符串传递像;这样的shell元字符来执行任意命令。