Rand函數引發的安全問題 —— OSSN任意文件讀取漏洞(CVE-2020-10560)


前言

Open Source Social Network(OSSN),是一款用PHP編寫的社交網絡軟件。OSSN允許用戶創建一個社交網站,幫助擁有相似專業或個人興趣的人建立社交關系。該軟件擁有約50萬下載量。

OSSN官網地址:

https://www.opensource-socialnetwork.org/

漏洞簡介

Open Source Social Network(OSSN)5.3之前版本中存在一處任意文件讀取漏洞(CVE-2020-10560)。漏洞因OSSN生成的Site_Key強度過低從而可以遭受被暴力破解而產生,成功破解Site_Key的攻擊者可以利用Site_Key構造出任意文件讀取鏈接,通過components\OssnComments\ossn_com.php文件提供的文件預覽接口,讀取文件。

漏洞分析

Open Source Social Network應用可以從如下官網鏈接下載:

https://www.opensource-socialnetwork.org/download

應用首頁如下圖

OSSN中提供Comment功能,訪問者可以對帖子進行評論,見下圖:

評論帖子時,用戶可以上傳圖片以及表情,如下圖紅框處:

當選擇本地圖片並上傳后,將在評論中生成一個預覽,見下圖:

注意,這時還沒有點擊發布評論,上圖圖片只是上傳成功后的一個預覽圖片。該臨時圖像文件存儲於tmp目錄並在前端呈現了預覽。

我們來看下這個臨時圖片文件是如何獲取並在頁面中展示的。查看一下圖片鏈接,如下圖:

鏈接如下:

http://192.167.30.119/comment/staticimage?image=UiszT0RJYStoQll2N2g5cHhmQW9PRHlCNVgrSWFKVzFQRHE4eTJqSWthVUVjUFBIb3pxME1FNUJFdk5ER2pONXI4V2pyeXJSMm9VPQ==

我們可以猜測出image參數對應的字符串應該是文件地址的加密形式,只有構造出正確的base64字符串,攻擊者就可以讀取任意文件。

最重要的是,經過測試發現,訪問這個鏈接並不需要用戶登陸。任何人都可以通過這個鏈接直接訪問我們上傳的這個圖片文件。

接下來分析下后台代碼,看看這個base64字符串是如何還原出文件路徑以及如何被構造出來的

上文鏈接對應的后台代碼位於 \components\OssnComments\ossn_com.php

在ossn_com.php中case 'staticimage'分支里,程序將請求中image參數值取出,並進行base64_decode解碼。見下圖:

隨后,對解碼后的值再次base64_decode解碼,然后利用ossn_string_decrypt方法解碼並獲取文件地址。見下圖:

接着,通過ossn_validate_filepath方法對文件路徑進行校驗。見下圖紅框:

ossn_validate_filepath方法如下圖所示,可見該方法對目錄遍歷進行了過濾

即使過濾了../ 我們仍然可以通過絕對路徑來進行文件讀取,例如直接讀取/etc/passwd

最后,程序利用file_get_contents方法對文件內容進行讀取,並使用echo進行打印。見下圖紅框:

通過閱讀代碼也可以驗證之前的測試結果:該接口並未進行身份校驗,未登錄的用戶依然可以通過該接口訪問文件。

問題又回到了如何構造加密字符串上。我們首先來看一下程序是如何解碼的,位於libraries\ossn.lib.system.php文件中

通過上圖的代碼看,在解碼過程中,需要用到site_key值。

經過分析后發現,程序通過ossn_site_settings方法在數據庫中讀取site_key值,我們先來看一下存儲於ossn_site_settings表中site_key值是什么,見下圖:

site_key值為c1a725ed,可見是一個8位數

這樣看來,只要破解出這個8位數的site_key,即可構造出指向任意文件路徑的鏈接。

我們接着分析這個site_key是如何生成的,生成代碼位於libraries\ossn.lib.upgrade.php文件中,見下圖:

通過分析上圖加密過程不難發現,該8位隨機數是通過如下方式產生的:

  1. 以字符串“ ossn”開頭。

  2. 通過rand方法生成一個隨機數並拼接到“ ossn”字符串后。

  3. 計算此字符串的md5值。

  4. 將字符3-11取出作為site_key值。

本次漏洞就出在計算site_key值的第二步,也就是通過rand產生隨機數這一步。

關於rand方法,可以參考php官網

在官網介紹頁面中明確的給出了警告,見上圖底部

警告

此函數不會生成加密安全值,並且不應將其用於加密目的。如果需要密碼安全的值,請考慮改用random_int(),random_bytes()或openssl_random_pseudo_bytes()。

rand方法之所以不安全,其中一個比較重要的原因是它能產生的隨機數范圍有限:

rand方法在沒有提供可選參數 min 和 max時,返回 0 到 RAND_MAX之間的偽隨機整數.

在筆者的windows主機上,RAND_MAX值僅為32767

而在筆者的Linux環境中,這個值為2147483647

據資料顯示,rand最大可能值為2,147,483,647

因此,只需要生成最多20億個rand值,將其依次帶入ossn_generate_site_secret計算出對應的site_key值,這些site_key值即為所有的site_key值可能值。如果運氣好,目標主機是一台windows主機,這樣的操作僅僅重復3萬多次即可,因為windows主機下rand產生的最大值僅為32767。

在分析了弱密鑰是如何生成之后,我們需要一種方法來識別生成的密鑰是否有效。在臨時圖片文件被上傳到服務器時,會被存儲於ossn_data/tmp/photos文件夾中,見下圖:

因此上文中的加密數據成功解碼后,其字符串中一定會包含tmp/photos字符串。我們這里用我們的密鑰解一下上文中的編碼,看一下這個推論是否正確,結果如下圖:

可見成功解開的文件路徑中的確存在tmp/photos字符串

因此,暴力破解的思路很明朗了

1、攻擊者在評論里上傳一個圖片,不點擊發送,查看此時圖片臨時預覽鏈接,獲取鏈接中image參數值。例如:http://192.167.30.119/comment/staticimage?image=UiszT0RJYStoQll2N2g5cHhmQW9PRHlCNVgrSWFKVzFQRHE4eTJqSWthVUVjUFBIb3pxME1FNUJFdk5ER2pONXI4V2pyeXJSMm9VPQ==中的UiszT0RJYStoQll2N2g5cHhmQW9PRHlCNVgrSWFKVzFQRHE4eTJqSWthVUVjUFBIb3pxME1FNUJFdk5ER2pONXI4V2pyeXJSMm9VPQ==>

2、將數字0-2147483647依次帶入ossn_generate_site_secret中計算出對應的site_key

3、依次將site_key與image值帶入ossn_string_decrypt中,獲取解密后的明文

4、如果明文中含有tmp/photos字符串,解密成功,此時的site_key即為正確的site_key值

漏洞利用

在獲取site_key值后,可以通過ossn_string_encrypt方法,對想要讀取的文件進行加密,通過http://192.167.30.119/comment/staticimage?image=接口進行讀取即可

上文所涉及的工具如下:

site_key計算工具

https://github.com/LucidUnicorn/CVE-2020-10560-Key-Recovery

加密解密工具

https://github.com/kevthehermit/CVE-2020-10560


免責聲明!

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



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