SV.CODE_INJECTION.SHELL_EXEC

命令注入漏洞

当将 system() 函数或 popen() 函数与受外部影响的输入一起使用时,可能导致恶意用户通过攻击进程的特权来注入字符串以及执行任意的命令和代码。例如,攻击者可以注入分号来结束一个命令,然后插入并执行不相关的新命令。

漏洞与风险

容易受到命令注入攻击的 system() 调用或 popen() 调用可能导致以下后果

  • 执行恶意代码
  • 创建新的用户帐户以访问受损的系统
  • 通过比标准用户更高的特权级别来执行任意命令

在最坏的情况下,攻击者可以注入能够控制系统的字符串,例如,删除根分区的内容。

缓解与预防

要避免此问题,最佳做法是

  • 仅通过系统调用来使用常数字符串
  • 在命令执行之前添加验证代码
  • 使用库调用而非外部进程
  • 使用白名单而非黑名单输入验证
  • 使用 exec 系列函数来运行外部可执行文件
  • 确保用户不能写入任何外部可执行文件
  • 直接在调用现有库的程序中实施功能

漏洞代码示例

复制
  char *constbuf = "bash";
  int main()
  {
       char buf[100];
       scanf("%s",buf);
       system("echo \"constant string: no warning\"");
  
       system(constbuf);
       system(buf);
      popen("echo OK","r");
      popen(constbuf, "r");
      popen(buf, "r");
      return 0;
 
 }

在本示例中,Klocwork 针对第 9 行生成问题报告,指出 system() 函数可能接受会受到用户影响的命令行,从而导致执行任意代码。针对第 12 行中的 popen() 函数也报告了类似的警告。在这两种情况中,攻击者都可以注入命令以执行恶意代码,甚至是控制系统或删除根分区。第 6 行和第 8 行中的系统函数调用将常数字符串和库调用用作参数,所以它们不会受到代码注入攻击,因此没有被标记。

相关检查器