大田後生仔之playSMS1.4版代碼審計

0x00

關於playSMSv1.4,sendfromfile位置文件RCE漏洞的代碼審計。
首先根據代碼邏輯找到用戶輸入的位置:
在這裏插入圖片描述
在這裏插入圖片描述
可以看到系統首先加載程序的主文件app\main.php,然後根據用戶請求的url進行分解找到功能代碼位置,用戶輸入的位置ROOT\plugin\feature\sendfromfile\sendfromfile.php。
在這裏插入圖片描述
找到上傳文件的除了模塊。

0x01

對該模塊進行測試,發現53行輸入的filename存到filename122filename變量,然後在122行添加到content變量當中直接返回,然後在167行使用函數輸出:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
關於_p()函數跟進一下,看看是否有重寫,然後發現首先調用core_print()函數:
在這裏插入圖片描述
再跟進:發現core_print()是普通的輸出函數:
在這裏插入圖片描述

重新會到sendfromfile.php,通過_p打印的$content變量沒有異常,但是爲什麼裏面的惡意代碼會被當成代碼執行?
之後又在其他地方多次echo惡意代碼,最後發現在此php文件中輸出的全部惡意代碼都是可以執行的,那麼漏洞產生原因肯定不在這個頁面。測試形如下圖。
在這裏插入圖片描述

0x02

之後重新回到main.php,發現此處存在一個未接觸的點:
在這裏插入圖片描述
程序中使用了ob_get_clean()函數來獲取緩衝區的數據,關於這個函數:
在這裏插入圖片描述
在這裏插入圖片描述
也就是說,我們在sendfromfile.php中的所有輸出,全部都是存在緩衝區當中,現在使用ob_get_clean()函數就能夠獲取到緩衝區當中的所有輸出,包括惡意代碼。
之後繼續跟進,在程序輸出緩衝區內容之前,經歷了themes_apply()函數,漏洞形成原因應該在這個函數當中。
函數如下:
在這裏插入圖片描述
在這個函數中會調用一個core_thems_get()函數,這個函數是是用來獲取當前主題的,然後將主題當成參數傳遞給core_hook(()函數:
在這裏插入圖片描述
可以看到core_hook()函數獲取到三個參數之後會將前兩個參數拼接,組成一個字符串,然後調用call_user_func_array()回調函數調用這個字符串所表示的函數,回調函數主要將第一個參數當成函數名,第二個參數當成要調用函數的參數,然後調用該函數。此處回調的函數是從前一個函數拼接的,獲取到的主題爲default,但是拼接後的回調函數名不存在,所以返回false,然後使用common當成主題名繼續嘗試回調:common_hook_themes_apply函數存在,執行回調函數。
在這裏插入圖片描述
0x04
回調函數成功,接下來就要跟進到回調函數的位置。我們從緩衝區獲取的輸出已經變成了回調函數的參數。
在這裏插入圖片描述
在此處將$content變量的內容相應的添加,然後傳遞參數,調用tpl_apply()函數:
在這裏插入圖片描述
這個函數會根據你訪問的不同模塊探測是否在文件夾下面會存在對應的html文件,如果沒有的話就應用一個公共的,之後又將html文件路徑當成參數和其他變量一起傳遞給_tpl_apply()函數:
在這裏插入圖片描述

返回值是$t對象的getCompiled()方法返回值,進入Tpl類審計getCompiled()函數:
_compiled是個私有變量:
在這裏插入圖片描述
通過getCompiled()函數返回,
在這裏插入圖片描述
那麼之後就要查看這個私有變量的值是如何獲取的:可以返回上一步看到先執行了compile函數,查看這個函數邏輯:
在這裏插入圖片描述
調用了_compile函數。
在這裏插入圖片描述
關於_compile函數,可以看到雖然對傳進去的數據存在過濾,但是並沒有對危險的函數等等進行過濾。
在這裏插入圖片描述
之後將數據寫入緩存文件:
在這裏插入圖片描述
可以看到緩存文件的數據就是我們在sendfromdfile文件輸出的內容:
在這裏插入圖片描述
最後通過文件包含的形式,獲取到緩存文件的內容,還是通過緩衝區的方式傳遞給返回值,最後清空緩衝區。然後回到main.php中,打印輸出。而此時,輸出的其實是一段html代碼,但是其中包含了用戶可控的各種輸入,然後造成了漏洞的產生。
如果是這個亞子的話其實所有的用戶輸入都沒有進行過濾,那麼就存在多種利用方法了。

0x05
這個流程簡化一下就是下面這個亞子的:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章