首页 > 解决方案 > 以编程方式安全地执行 shell 命令

问题描述

可以通过调用执行 shell 命令的系统函数来执行 shell 命令。

这显然是不安全的,因为有人可以滥用程序并执行攻击者特定的操作系统命令。

系统的手册页建议使用exec(3)函数:

不要使用特权程序(set-user-ID 或 set-group-ID 程序,或具有功能的程序)中的 system(),因为某些环境变量的奇怪值可能会用于破坏系统完整性。例如,可以操纵 PATH 以便以特权执行任意程序。请改用 exec(3) 系列函数,但不要使用 execlp(3) 或 execvp(3)(它们也使用 PATH 环境变量来搜索可执行文件)。

虽然我真的不明白其中的区别。是的,权限可能会有所不同,但我们仍然执行 os 命令并且它仍然容易受到攻击,不是吗?我错过了什么吗?

如何安全地执行系统命令而不用担心它会被滥用?

标签: csecurity

解决方案


我们仍在执行 os 命令,它仍然很脆弱,不是吗?

想象一下下面的 C 程序(为了清楚起见,忽略所需的 C 错误处理):

char file[20];
fgets(file, sizeof(file), stdin);
file[strcspn(file, "\n")] = 0; // https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input
char cmd[200];
snprintf(cmd, sizeof(cmd), "touch %s", file);
system(cmd);

一切都好 - 一个创建文件的简单程序。但现在我运行程序并输入:

file; sudo rm -r /

所以会发生什么,file="file; sudo rm -r /"然后cmd="touch file; sudo rm -r /"和结果system命令运行touch file,然后运行sudo rm -r /删除所有文件并造成灾难性损坏。

相比之下:

execl("touch", "touch", file, NULL);

将始终只运行touch(在当前目录中),并且touch只会尝试触摸一个/名为字面意思的目录(因为尾随 )file; sudo rm -rf /。(但是PATH可以操纵并且touch可以替换可执行文件,这就是为什么使用execv而不是execl-您的报价说明了这一点)。


推荐阅读