前言
PHP命令執行漏洞
應用程序的某些功能功能需要調用可以執行系統命令的函數,如果這些函數或者函數的參數被用戶控制,就有可能通過命令連接符將惡意命令拼接到正常的函數中,從而隨意執行系統命令,這就是命令執行漏洞。
基本函數
1.system()用於執行外部程序,並且顯示輸出
<?php system('whoami'); ?>
2.exec()函數用於執行一個外部程序
<?php exec('whoami');?>
3.shell_exec()函數通過shell環境執行命令,並且將完整的輸出以字符串的方式返回
<?php shell_exec('whoami'); ?>
4.passthru函數用於執行外部程序並且顯示原始輸出
<?php passthru('whoami'); ?>
5.popen()函數用於打開進程文件指針
- r: 只讀。
- w: 只寫 (打開並清空已有文件或創建一個新文件)
<?php touch popen("3.txt","r"); ?> 在當前目錄創建名為3.txt的文件
6.Proc_popen函數用於執行一個命令,並且打開來輸入輸出的文件指針(有問題)
proc_open (字符串 $cmd
,數組 $descriptorspec
,數組 &$pipes
[,字符串 $cwd
=NULL
[,數組 $env
=NULL
[,數組 $other_options
=NULL
]]])

<?php $proc=proc_open("whoami", array( array("pipe","r"), array("pipe","r"), array("pipe","r")),$pipes); print stream_get_contents($pipes[i]); ?>
7.反單引號
反單引號(`)是PHP執行運算符,PHP將嘗試將返單引號中的內容作為shell命令來執行,並將其輸出信息返回 執行下面代碼返回whoami的結果
<?php echo `whoami`;?>
Windows下的命令執行漏洞
1.windows下面的命令連接符
windows下的命令連接符:&、&&、|、||
(1)&命令連接符
&前面的語句為假,則直接執行&后面的語句:&前面的語句為真,則&前后的語句都執行
(2)&&命令連接符
&&前面的語句為假,則直接報錯,&&后面的語句也不執行;&&前面的語句為真,則&&前后的語句都執行
(3)|命令連接符
|前面的語句為假,則直接報錯,|后面的語句也不執行;|前面的語句為真,則執行|后面的語句
(4)||命令連接符
||前面的語句為假,則執行||后面的語句;||前面的語句為真,則執行||前面的語句,不執行||后面的語句
2.windows下的執行命令漏洞利用
代碼
<?php $ip=$_GET['ip']; system("ping ".$ip); ?>
代碼中調用了system函數執行ping命令
$ip是可控參數,可以通過Windows下的命令連接符執行多條命令,達到攻擊的目的。輸入?=127.0.0.1|whoami,成功執行,返回當前用戶的信息,當然我們也可以進行其他的惡意操作。
linux下的命令執行漏洞
1linux下的命令連接符
Linux下的命令連接符:&、&&、|、||
(1).;命令連接符
;使多個命令順序執行,前面的命令和后面的命令都會執行
2.&命令連接符
&的作用是使命令在后台運行,這樣就可以同時執行多條命令
3.&&命令連接符
&&的作用是:如果前面的命令執行成功,則執行后面的命令
4.|命令連接符
|的作用是:將前面的命令的輸出作為后面命令的輸入,前面的命令和后面的命令都會執行,但只顯示后面的命令執行結果
5.||命令連接符
||的作用類似於程序中的if-else語句。若前面的命令執行成功,則后面的命令就不會執行;若前面的命令執行失敗,則執行后面的命令。
漏洞利用部分和windows下面代碼一樣就是命令連接符部分不一樣!!!!
命令執行繞過方法
命令執行繞過
開發人員在開發過程中,為了避免命令執行漏洞,可能會過濾一些命令或者比較常見的攻擊payload。攻擊者會通過多種方式繞過過濾規則。
(1) 繞過空格過濾
1.${IFS}繞過
$IFS是shell的特殊環境變量,是Linux下的內部區域分隔符。$IFS中存儲的值可以使空格、制表符、換行符或者其他自定義符號。
Payload: http://127.0.0.1/test.php?ip=127.0.0.1;ls${IFS}-l
2.$IFS$9繞過
Payload: http://127.0.0.1/test.php?ip=127.0.0.1;ls$IFS$9-l
3.制表符繞過
%09是制表符的URL編碼,可以通過%09來代替空格,繞過空格過濾
Payload: http://127.0.0.1/test.php?cmd=ping%09127.0.0.1
4.{ }繞過
5.<繞過
(2) 繞過關鍵字過濾
1. 變量拼接繞過
Linux支持變量賦值,可以通過變量拼接來繞過過濾規則
繞過ls命令
2. 空變量繞過
3. 系統變量繞過
${SHELLOPTS}是系統變量,可以利用系統變量的字符拼接繞過過濾
4. \繞過
5. 通配符繞過
Linux支持利用通配符進行字符匹配。通配符的作用是在模糊查詢時表示文件名中某些不確定的字符
*代表0到多個任意字符
?代表任意一個字符
[]內為字符范圍,代表該字符范圍中的任意一個字符
6. shell反彈繞過
在利用shell反彈進行攻擊時,如果存在過濾,可以通過通配符來繞過過濾
7. BASE64編碼繞過
利用系統函數base64對命令進行Base64編碼,以繞過過濾。例如,id命令的Base編碼為aWQ=,在利用base64 -d對aWQ=進行解碼,這樣就繞過了過濾,並且正常執行了命令
8. expr和awk繞過
通過expr和awk命令從其他文件中獲取字符並進行命令構造
xiaohua文件內容為字符串xiaohua,通過以下命令可以獲取xiaohua文件中存儲的第一個字符。
9. 無回顯的命令執行
如果存在命令執行漏洞,但是沒有回顯,可以通過shell反彈的方式將shell反彈到VPS上,然后通過VPS執行命令。如果無法反彈shell,也可以通過DNS管道解析的方式獲取命令的執行結果。
PHP命令執行漏洞的修復
1.服務器配置修復
可以通過PHP配置文件中的disable_functions禁用敏感函數來修復命令執行漏洞
2.函數過濾
(1)escapeshellarg()函數:把字符串轉碼為可以在shell命令里使用的參數,以過濾命令中的參數。
(2) escapeshellcmd()函數:可以對shell元字符進行轉義,過濾命令
其他學習文章
https://www.freebuf.com/articles/web/137923.html
參考學習:《web安全原理分析與實踐》