|
这个漏洞不需要权限,可以直接注入,如果权限允许是可以直接写shell的,至少也是可以延时注入的。 一、引发问题的地方 // ranzhi/lib/dao/dao.class.php
public function orderBy($order)
{
if(strpos($order, 'convert(') !== false)
{
if($this->inCondition and !$this->conditionIsTrue) return $this;
$order = str_replace(array('|', '', '_'), ' ', $order);
var_dump($order);
$this->sql .= ' ' . DAO::ORDERBY . " $order";
return $this;
}
else
{
return parent::orderBy($order);
}
}
上面是禅道、然之、蝉知这几套系统的orderBy函数,其中你会发现$order并没有经过PDO:quote()等函数过滤,因此导致此问题 二、利用点 // ranzhi/app/cash/block/control.php
public function printTradeBlock()
{
/*代码省略*/
$this->view->trades = $this->dao->select('*')->from(TABLE_TRADE)
->where('1=1')
->beginIF($this->params->type != 'all')->andWhere('type')->eq($this->params->type)->fi()
->beginIF(!empty($denyCategories))->andWhere('category')->notin($denyCategories)
->beginIF(!$expensePriv)->andWhere('type')->ne('out')->fi()
->orderBy($this->params->orderBy)
->limit($this->params->num)
->fetchAll('id');
$this->view->currencySign = $this->loadModel('common', 'sys')->getCurrencySign();
$this->view->depositorList = $this->loadModel('depositor', 'cash')->getPairs();
$this->display();
}
public function printReportBlock()
{
$this->processParams();
$currentYear = date('Y');
$currentMonth = date('m');
$datas = $this->loadModel('trade', 'cash')->getChartData($this->params->type, $currentYear, $currentMonth, $this->params->groupBy, $this->params->currency);
$datas = $this->loadModel('report', 'sys')->computePercent($datas);
$this->view->datas = $datas;
$this->view->type = $this->params->type;
$this->view->groupBy = $this->params->groupBy;
$this->view->currentYear = $currentYear;
$this->view->currentMonth = $currentMonth;
$this->display();
public function processParams()
{
$params = $this->get->param;
$this->params = json_decode(base64_decode($params));
$this->view->sso = base64_decode($this->get->sso);
$this->view->code = $this->get->blockid;
}
printReportBlock与printTradeBlock这个地方的参数是经过base64_decode然后json_decode得到的,而且都调用了orderBy函数。并且这两个方法是不需要登录就可以访问的,系统采用isOpenMethod函数判断是否可以公开访问,可以看到block模块是可以访问的。 // ranzhi/app/sys/common/model.php
public function isOpenMethod($module, $method)
{
if($module == 'user' and strpos(',login|logout|deny|control', $method)) return true;
if($module == 'api' and $method == 'getsessionid') return true;
if($module == 'misc' and $method == 'ping') return true;
if($module == 'misc' and $method == 'ignorenotice') return true;
if($module == 'action' and $method == 'read') return true;
if($module == 'block') return true; // 这里
if($module == 'notice') return true;
if($module == 'sso' and strpos(',auth|check|gettodolist', $method)) return true;
if($module == 'attend' and strpos(',signin|signout', $method)) return true;
if($module == 'refund' and $method == 'createtrade') return true;
if($this->loadModel('user')->isLogon() and stripos($method, 'ajax') !== false) return true;
return false;
}
三、利用方式 可以用延时注入、或者利用SQL语句直接写shell。
最后的payload如下:
|