c - 以编程方式安全地执行 shell 命令
问题描述
可以通过调用执行 shell 命令的系统函数来执行 shell 命令。
这显然是不安全的,因为有人可以滥用程序并执行攻击者特定的操作系统命令。
不要使用特权程序(set-user-ID 或 set-group-ID 程序,或具有功能的程序)中的 system(),因为某些环境变量的奇怪值可能会用于破坏系统完整性。例如,可以操纵 PATH 以便以特权执行任意程序。请改用 exec(3) 系列函数,但不要使用 execlp(3) 或 execvp(3)(它们也使用 PATH 环境变量来搜索可执行文件)。
虽然我真的不明白其中的区别。是的,权限可能会有所不同,但我们仍然执行 os 命令并且它仍然容易受到攻击,不是吗?我错过了什么吗?
如何安全地执行系统命令而不用担心它会被滥用?
解决方案
我们仍在执行 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
-您的报价说明了这一点)。
推荐阅读
- python - 找出列表和集合之间的区别
- python - /cart/update-transaction/0cqydz1f/ 处的 IntegrityError
- python - 我需要从漂亮的 json 创建输出
- vulkan - Vulkan的执行模型和同步
- keras - 为 Keras Fit Generator 函数中使用的验证数据设置 Training 为 False
- mysql - 在不使用 .raw 的情况下在 Knex.js 中选择一个总和
- r - 通过布尔数据框过滤数据框以插入 NA
- maven - 如何在 Docker 中从系统路径添加 jars
- r - 如何在R中重复观察n次?
- python - matplotlib中的缩小椭球体