1. 程式人生 > 實用技巧 >bolt cms V3.7.0 xss和遠端程式碼執行漏洞

bolt cms V3.7.0 xss和遠端程式碼執行漏洞

本文首發於“合天智匯”公眾號 作者:ordar123 宣告:筆者初衷用於分享與普及網路知識,若讀者因此作出任何危害網路安全行為後果自負,與合天智匯及原作者無關! 1. 漏洞環境搭建 github上下載對應版本,這裡下載3.7.0. https://github.com/bolt/bolt/releases 解壓後需要重新命名以下檔案:
mv .bolt.yml.dist .bolt.yml
mv composer.json.dist composer.json
mv composer.lock.dist composer.lock
mv src/Site/CustomisationExtension.php.dist src/Site/CustomisationExtension.php
為了快速搭建這裡使用phpstudy,開啟apache和mysql 點選網站,建立站點,選擇好php版本並建立資料庫,記住域名、資料庫名稱、使用者名稱和密碼 配置資料庫app/config/config.yml。填好資料庫名稱、使用者名稱和密碼然後儲存 然後瀏覽器訪問http://上面自己設定的域名/public即可到安裝頁面,第一次需要設定管理員賬號和密碼 http://上面自己設定的域名/public http://上面自己設定的域名/public/bolt # 管理地址 2. 漏洞分析 1、XSS成因分析 該漏洞存在於vendor/bolt/bolt/src/Controller/Backend/Users.php。有兩個變數$user和$userEntity用於儲存和使用以顯示此程式碼中的使用者資料。$userEntity在傳遞給$form->isValid(),這表明$user有未編碼的輸入和$userEntity是具有編碼的輸入。也就是說使用$user未對使用者輸入編碼,使用$userEntity可以對使用者輸入編碼。
下面程式碼使用$user->getDisplayName()而不是$userEntity->getDisplayName(),顯示未編碼的使用者輸入,所以導致XSS。
switch ($action) {
        case 'disable':
            if ($this->users()->setEnabled($id, false)) {
                $this->app['logger.system']->info("Disabled user
'{$user->getDisplayname()}
'.", ['event' => 'security']); $this->flashes()->info(Trans::__('general.phrase.user-disabled', ['%s' => $user->getDisplayname()])); } else { $this->flashes()->info(Trans::__('general.phrase.user-failed-disabled', ['%s' => $user->getDisplayname()])); } break; case 'enable': if ($this->users()->setEnabled($id, true)) { $this->app['logger.system']->info("Enabled user '{$user->getDisplayname()}'.", ['event' => 'security']); $this->flashes()->info(Trans::__('general.phrase.user-enabled', ['%s' => $user->getDisplayname()])); } else { $this->flashes()->info(Trans::__('general.phrase.user-failed-enable', ['%s' => $user->getDisplayname()])); } break; case 'delete': if ($this->isCsrfTokenValid() && $this->users()->deleteUser($id)) { $this->app['logger.system']->info("Deleted user '{$user->getDisplayname()}'.", ['event' => 'security']); $this->flashes()->info(Trans::__('general.phrase.user-deleted', ['%s' => $user->getDisplayname()])); } else { $this->flashes()->info(Trans::__('general.phrase.user-failed-delete', ['%s' => $user->getDisplayname()])); } break; default: $this->flashes()->error(Trans::__('general.phrase.no-such-action-for-user', ['%s' => $user->getDisplayname()])); }
2.遠端程式碼執行成因分析 normalizePath()函式在第823行acts的同一檔案中定義作為Flysystem的normalizePath()函式的包裝器。已經習慣了 獲取檔案的“真實”路徑。這用於驗證檔案位置等等。 例如,./somedir/../text.txt == ./text.txt == text.txt 所以'./text.txt' 傳遞給此函式,它返回 'text.txt' 所以,從檔名 'backdoor.php/.' 將其傳遞給normalizePath()它返回 'backdoor.php' ,這正是我們所需要的。 所以資料流看起來,首先是值'backdoor.php/.' 傳遞給validateFileExtension()返回NULL,因為後面沒有文字最後一個點。所以,extesion過濾器被繞過了。接下來,相同的值是傳遞給normalizePath(),它刪除最後一個“/.”,因為它看起來像它是指向當前目錄的路徑。最後,檔案被重新命名為'backdoor.php' 3. 漏洞測試 1. xss 構造payload
xxxxxxxxxx POST /preview/page HTTP/1.1Host: localhost    contenttype=pages&title=title&slug=testpage1&teaser=teaser1&body=<script>alert(1)</script>&id=151

2. 遠端程式碼執行 建立一個檔案,然後編輯這個檔案,寫入木馬儲存。
然後將shell.html重新命名危shell.html.php\.
即可變成shell.html.php。 訪問該檔案即可執行命令 4. 影響版本 Bolt CMS<= 3.7.0 5. 防禦方案
 1. XSS

        使用具有編碼值的變數來顯示使用者資訊。使用$userEntity而不是$user

     2. RCE

        重新命名時更改資料流。先把資料傳過來normalizePath()資料,然後通過validateFileExtension()。這樣,驗證函式驗證最終值。
相關實驗: WordPress social-warfare外掛XSS和RCE漏洞 https://sourl.cn/x8jyuV 通過實驗瞭解WordPresssocial-warfare外掛XSS和RCE漏洞的成因和利用方法,學會在無需身份驗證的情況下實現對網站和伺服器的控制。