
我試著以 root 身分執行 C++ 編譯的程序,而我是另一個使用者。
程式成功執行,但作為普通用戶,而不是root。
然而,正如互聯網所說,chmod u+s
命令使其以所有者身份運行(在我的例子中是 root)。
程式是一個簡單的system(argv[1])
行,它將執行命令列參數內的所有內容。
例如 - 輸出whoami
返回我的用戶,而不是根用戶。
也嘗試列出/root
「權限被拒絕」結束的內容。
文件的權限 -
-rwsr-xr-x 1 root root 16608 Aug 25 15:20 test
此時我嘗試授予該文件的權限4755
(沒有運氣)。
移動文件/root
也不太幸運。
答案1
system()呼叫使用execl()
系統呼叫來建立一個新的shell程序。但係統呼叫忽略有效使用者 ID 並傳回 EPERM 錯誤(權限被拒絕)。
這是因為 Linux shell 不繼承 seteuid 位元。為什麼?好吧,因為使用有效使用者 ID 作為 root 運行腳本確實存在問題。有關該主題的更多閱讀,請參閱這裡。
可以透過傳遞參數來運行作用於有效 UID 的 shell -p
。從sh
手冊頁:
-p 特權 如果有效 uid 與 uid 不匹配,請勿嘗試重置有效 uid。預設未設定此值,以協助避免 setuid root 程式透過 system(3) 或 popen(3) 錯誤使用。
當然,此限制不適用於系統呼叫。作為演示,此 C 程式嘗試使用 列出 /root system()
,然後使用opendir()
和readdir()
系統呼叫執行相同操作。
如果二進位檔案由 root 擁有並設定了使用者 ID,則執行程式的非 root 使用者將導致第一個 /root 清單失敗,第二個(使用display_dir()
Works.txt )失敗。
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<dirent.h>
#include<errno.h>
int display_dir(const char *dirname)
{
DIR *dp = opendir(dirname);
struct dirent *sd=NULL;
if (!dp) return(errno);
while ((sd = readdir(dp)) != NULL)
{
printf("%s\n", sd->d_name);
}
closedir(dp);
return 0;
}
int main()
{
system("ls /root");
printf("Display returned %d\n", display_dir("/root"));
}