我想以root用户身份启动一个bash脚本(读取:bash not sh脚本),而不是用户调用它,但是bash忽略了脚本上的setuid,所以我选择编写一个非常小的脚本来获取脚本/参数并用setuid set调用它。
这很好用,我甚至进一步验证脚本是否已设置setuid,可执行文件和setuid()调用文件的所有者而不是root用户,以避免任何滥用程序的行为,我最终得到了以下计划..
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char **argv)
{
char *command;
int i, file_owner, size = 0;
struct stat status_buf;
ushort file_mode;
// Check argc
if (argc < 2) {
printf("Usage: %s <script> [arguments]\n", argv[0]);
return 1;
}
// Make sure the script does exist
if(fopen(argv[1], "r") == NULL) {
printf("The file %s does not exist.\n", argv[1]);
return 1;
}
// Get the attributes of the file
stat(argv[1], &status_buf);
// Get the permissions of the file
file_mode = status_buf.st_mode;
// Make sure it's executable and it's setuid
if(file_mode >> 6 != 567) {
printf("The file %s should be executable and should have setuid set, please chmod it 0106755.\n", argv[1]);
return 1;
}
// Get the owner of the script
file_owner = status_buf.st_uid;
// setuid
setuid(file_owner);
// Generate the command
for (i = 1; i < argc; i++) {
size += strlen(argv[i]);
}
command = (char *) malloc( (size + argc + 11) * sizeof(char) );
sprintf(command, "/bin/bash %s", argv[1]);
if (argc > 2) {
for (i = 2; i < argc; i++) {
sprintf(command, "%s %s", command, argv[i]);
}
}
// Execute the command
system(command);
// free memory
free(command);
return 0;
}
练习不仅是为了解决我的问题,而且也是一种进入C的方式,所以你们有什么建议?有什么我应该改进的吗?
谢谢..
答案 0 :(得分:2)
if(file_mode >> 6 != 567) {
魔术数据不好。请改用S_I*
位掩码。
system(command);
你在* nix;使用fork()
和exec*()
将消除之前在循环中执行的大多数杂技。