-1

我刚刚用 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 个空格?

4

2 回答 2

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.
于 2013-01-27T01:47:32.143 回答
2

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

于 2013-01-27T01:50:38.187 回答