溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

為PHP執(zhí)行賦予root權(quán)限

發(fā)布時(shí)間:2020-07-15 00:50:31 來(lái)源:網(wǎng)絡(luò) 閱讀:519 作者:ihanxiao2100 欄目:web開發(fā)

這幾天弄的東西涉及到php利用shell腳本與Linux的交互,我們知道利用php運(yùn)行腳本來(lái)訪問Linux是以Apach的身份來(lái)執(zhí)行的,因此它自己能夠所做的事情很少的,因?yàn)闆]有足夠的權(quán)限,這里就涉及到要將為php執(zhí)行的時(shí)候賦予root權(quán)限。

接下來(lái)介紹的這種方法,我自己是親自做了的,可以實(shí)現(xiàn),但是畢竟有它的缺點(diǎn),這里跟大家分享一下,希望大家有什么好的做法可以提示一下:

這是利用C來(lái)實(shí)現(xiàn)互換權(quán)限的,如果你想徹底明白到底為什么接下來(lái)的程序可以運(yùn)行成功,請(qǐng)徹底弄清楚SUID與SGID到底起什么作用。

[plain] view plaincopy

  1. #include <stdio.h>  

  2. #include <stdlib.h>  

  3. #include <sys/types.h>  

  4. #include <unistd.h>  

  5.   

  6. int main()  

  7. {  

  8.     uid_t uid , euid ;  

  9.     uid = getuid();  

  10.     euid= geteuid();  

  11. //  printf("my uid:%u\n",getuid());  

  12. //  printf("my euid:%u\n",geteuid());  

  13.     if(setreuid(euid,uid))  

  14.        perror("setreuid");  

  15. //  printf("after setreuid uid:%u\n",getuid());  

  16. //  printf("after setreuid euid:%u\n",geteuid());  

  17.     system("/home/houqingdong/myshell/mkdir.sh /home/ hou_test");  

  18.     return 0;  

  19. }  

其中的主要函數(shù)說(shuō)明:

1.getuid()所需要的頭文件為:
    #include <sys/types.h>
    #include <unistd.h>
  函數(shù)原型:uid_t getuid(void);
  函數(shù)說(shuō)明:uid_t是定義在sys/types.h中的,其實(shí)就是unsigned int類型,函數(shù)返回一個(gè)調(diào)用程序的真

實(shí)用戶的ID。
2. geteuid()
   函數(shù)原型:uid_t geteuid(void);
   函數(shù)說(shuō)明:geteuid()用來(lái)取得執(zhí)行目前進(jìn)程有效的用戶識(shí)別碼。有效的用戶識(shí)別碼用來(lái)決定進(jìn)程執(zhí)行

的權(quán)限,借由此改變此值進(jìn)程可以獲得額外的權(quán)限。倘若執(zhí)行文件的setID位已被設(shè)置,該文件執(zhí)行時(shí),

其進(jìn)程的euid值便會(huì)設(shè)成該文件的所有者的uid。例如,執(zhí)行文件/usr/bin/myshell.sh的權(quán)限為:-r-s-

-x--x,其s位即為setID(SUID)位,而當(dāng)任何用戶在執(zhí)行myshell.sh時(shí)其有效的用戶識(shí)別碼會(huì)被設(shè)成為

myshell.sh所有者的uid,即root的uid值為0.

3. setreuid();  可以理解為交換ID

編譯該文件:     gcc -o run -Wall run.c    生成可執(zhí)行文件run

接下來(lái)做的是最重要的一步,為run賦予suid的權(quán)限:chmod u+s run   它的作用是設(shè)置uid,當(dāng)普通用戶執(zhí)行的時(shí)候是以root的權(quán)限來(lái)執(zhí)行的,在run.c里面會(huì)交換進(jìn)程的ID,從而利用root的ID為0,來(lái)執(zhí)行,權(quán)限就可想而知了。

但 是利用這個(gè)方法有一個(gè)很不好的地方,在run.c中,我執(zhí)行的命令是:system("/home/houqingdong/myshell /mkdir.sh /home/ hou_test");   mkdir.sh是我自己寫的腳本,而后面的兩個(gè)參數(shù)是寫死的,也就是說(shuō)參數(shù)的傳遞非常不方便,當(dāng)然如果你執(zhí)行一些不需要傳遞參數(shù)的程序,這個(gè)方法還是很 可行的,而我想做的是用戶選擇Linux下的某個(gè)目錄,可以在這里面創(chuàng)建文件file或者目錄directory,此時(shí)的參數(shù)就非常不好辦了。

 

關(guān)于這個(gè)問題還嘗試了另一種方法:

        就是直接將自己寫的shell腳本,執(zhí)行:  chmod 777 mkdir.sh                chmod u+s mkdir.sh

       這樣我調(diào)用mkdir.sh的時(shí)候同樣是以root的身份來(lái)執(zhí)行的,但是我在網(wǎng)頁(yè)端運(yùn)行的時(shí)候,仍然報(bào)錯(cuò),初步認(rèn)定為我要?jiǎng)?chuàng)建文件的那個(gè)目錄下 Apache的權(quán)限不夠,我嘗試著將權(quán)限改為: chmod -R 777 /home/     然后在運(yùn)行就可以創(chuàng)建成功了,但是這樣為Apache添加權(quán)限的方法是很不正規(guī)的吧,我知道如何為Apache添加主目錄和虛擬目錄的權(quán)限

但是這樣的就不知道了,總不能都改權(quán)限吧。



今天晚上:19:30分,這個(gè)困擾了我好久的問題終于解決,其中的原理也終于弄清楚了,總之是利用sudo來(lái)賦予Apache的用戶root的執(zhí)行權(quán)限,下面記錄一下:

利用php利用root權(quán)限執(zhí)行shell腳本必須進(jìn)行以下幾個(gè)步驟:(所有步驟都是我親自實(shí)驗(yàn),若有不妥可指出,謝謝?。?/p>

1. 確定一下你的Apache的執(zhí)行用戶是誰(shuí)。注:不一定就是nobody,我自行安裝的httpd,我的Apache的用戶就是daemon

2. 利用visudo為你的Apache執(zhí)行用戶賦予root執(zhí)行權(quán)限,當(dāng)然還有設(shè)置無(wú)密碼。注:為了安全起見,這里最好是新建一個(gè)用戶,讓他作為Apache的執(zhí)行用戶即可(修改httpd.conf文件,后面我會(huì)指出)

3. 這步就簡(jiǎn)單了,編寫你的腳本,利用php的exec,system...函數(shù)來(lái)執(zhí)行。

接下來(lái)就是詳細(xì)的實(shí)現(xiàn)過程:

1. 查看一下你的Apache的執(zhí)行用戶是誰(shuí): lsof -i:80         運(yùn)行之后的結(jié)果為:

   

從圖中我們可以清楚的看到,httpd(也就是Apache)的執(zhí)行用戶為:exec_shell(注:這是我本機(jī)上改過之后的用戶,只是用來(lái)說(shuō)明一下,你的肯定不是這個(gè)!)  

lsof 就是 List of file 的縮寫,就是列出當(dāng)前系統(tǒng)打開文件的工具,關(guān)于他具體的使用方法可參考:http://club.topsage.com/thread-234763-1-1.html   說(shuō)的比較不錯(cuò)

確定了你的Linux上Apache的執(zhí)行者是誰(shuí),下面為了安全起見,新建一個(gè)用戶將Apache的執(zhí)行用戶修改為我們新建的用戶。

2. 新建Apache的執(zhí)行用戶

    useradd your_exec_user  我們知道創(chuàng)建用戶的時(shí)候都會(huì)默認(rèn)創(chuàng)建一個(gè)用用戶名同樣的用戶組,也就是說(shuō)現(xiàn)在我們也有一個(gè)your_exec_user的用戶組

    下面我們修改一下Apache的配置文件,使它的執(zhí)行用戶改為我們剛才新建的這個(gè)用戶your_exec_user :

     vi  /home/houqingdong/httpd-exe/config/httpd.conf(這個(gè)是你的Apache所在的目錄位置)

    找到下面的地方,修改為你新建的用戶:your_exec_user

    

   重新啟動(dòng)Apache:   /home/houqingdong/httpd-exe/bin/apachect1  restart              -------------> 重啟完之后你可以利用:lsof -i:80 查看一下。

3. 執(zhí)行visudo(或者是 vi /etc/sudoers) , 為your_exec_user賦予root權(quán)限,并且不需要密碼,還有一步重要的修改(我被困擾的就是這個(gè)地方)

    visudo    找到這個(gè)地方,添加your_exec_user,并且設(shè)置無(wú)需密碼

    

   我之前的時(shí)候,做完這里就去執(zhí)行php腳本去了,結(jié)果一直創(chuàng)建不成功,而且很郁悶的是我切換到y(tǒng)our_exec_user用戶下直接執(zhí)行是可以執(zhí)行成功的。

   后來(lái),查看了一下Apache的日志文件,發(fā)現(xiàn):   

      這里明顯看出,在執(zhí)行sudo的時(shí)候說(shuō)必須要有一個(gè)tty去運(yùn)行sudo , 知道問題出在哪里問題就好解決了: vi /etc/sudoers   將下面的這句注釋掉:      

      這是因?yàn)槟J(rèn)的情況下,執(zhí)行sudo需要一個(gè)終端,這里注釋掉就可以了。接下來(lái),寫你的shell腳本和php命令吧

4. 這里貼一下我寫的很簡(jiǎn)單的一個(gè)腳本,就是利用在php端傳來(lái)的$directory和$name,在該目錄下創(chuàng)建一個(gè)$name的目錄

   

[plain] view plaincopy

  1. #!/bin/bash  

  2. #Program  

  3. #     This program will execute mkdir: cd $directory ; mkdir $name  

  4. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin  

  5. export PATH  

  6. cd $1  

  7. if [ ! -d $2 ]; then  

  8.     mkdir $2  

  9. else  

  10.     echo "Already exist..."  

  11.     exit 1  

  12. fi  


功能很簡(jiǎn)單,就是進(jìn)入到$directory   判斷要?jiǎng)?chuàng)建的目錄名是否存在,  然后創(chuàng)建該目錄 。

構(gòu)造的php執(zhí)行函數(shù):(部分)

[php] view plaincopy

  1. if($type=="dir"){  

  2.           $make_dir_command="/usr/bin/sudo /home/houqingdong/myshell/mkdir.sh /$directory/ $name" ;  

  3.           echo $make_dir_command;  

  4.           exec($make_dir_command,$output,$return);  

  5.   

  6.               if($return == 0){  

  7.                   echo "<script>alert('Build directory seccuss!');location.href='right.php?id=\"$directory\"';</script>";  

  8.               }else{  

  9.                   echo "<script>alert('Build directory err!');history.go(-1);</script>";  

  10.               }  

這里順帶提一句:構(gòu)造的命令里面最好都使用絕對(duì)路徑。

5. 在網(wǎng)頁(yè)端的執(zhí)行結(jié)果:

    

提交之后,要過幾秒中才會(huì)彈出執(zhí)行結(jié)果的提示信息:

     執(zhí)行成功,在我們的/home/目錄下:

哈哈。。。大功告成!


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI