锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

PHP代码审计3—系统重装漏洞

时间:2022-11-01 06:00:00 二极管pk25f

文章目录

      • 一、前言
      • 二、ZZCMS 2020 重新安装漏洞与复现
        • 1、漏洞分析
        • 2、漏洞复现
      • 三、盾灵V.10系统重新安装漏洞
        • 1、漏洞分析
        • 2、漏洞复现

一、前言

1.系统重新安装漏洞类型

  • 安装文件自动删除

    安装普通系统后,会生成一个lock判断是否安装文件,如果系统自动删除该文件,则会导致系统重新安装的漏洞。 
  • 无安装结果验证

    这种情况是不删除的.lock不会生成文件.lock安装文件。 
  • 可绕过安装检测

    在这种情况下,在安装过程中,系统安装检测是一个单独的页面,302跳转到安装。 在这种情况下,我们可以直接get要求安装页面以绕过检测。 
  • 变量覆盖导致重装

    可以使用GET或者POST等方式提交一个变量名$lockFile,并给它赋空值,覆盖它$lockFile,从而让file_existe()判断结果为false,绕过安装文件检测。 
  • 判断lock文件后,无exit

    判断它是否存在lock文件,如果lock文件存在时会跳转到某个页面,但跳转后没有exit检测程序。 
  • 存在分析漏洞

    将在安装完成后进行install.php重命名为install.php.bak,但是由于Apache分析漏洞:如果不能识别最后一个后缀,就会向上分析,然后变成php了,然后结合安装时的变量覆盖又成重装了。 

2.近期漏洞列表

  • CNVD-2020-58513: ZZCMS 2020版系统重装漏洞
  • CNVD-2020-33196:盾灵1.0系统重新安装漏洞
  • CNVD-2020-31454:Heybbs微社区install.php重新安装文件漏洞
  • CNVD-2020-0229:100系统重装漏洞
  • CNVD-2019-43815:s-cms企业建站系统重新安装漏洞
  • CNVD-2018-05690:hpyun人才系统4.5版本重装漏洞

二、ZZCMS 2020 重新安装漏洞与复现

1、漏洞分析

首先,我们可以看到漏洞代码:install/index.php。

在代码的第11行,有一个$step变量,变量值,由客户端传输。

6:include '../inc/config.php'; 7:include 'conn.php'; 8if($_POST) extract($_POST, EXTR_SKIP);///直接将数组中的键名注册为变量。就像把键名注册成变量一样$_POST[ai]直接注册$ai。 9:if($_GET) extract($_GET, EXTR_SKIP); 10:$submit = isset($_POST['submit']) ? true : false; 11:$step = isset($_POST['step']) ? $_POST['step'] : 1;

在此处使用了一个三元操作符来进行判断,如果没有传入step参数的话,就会默认赋值为1。

也就是说,在初始访问index.php的时候,会默认赋值$step=1。

接下来我们再把视线放到第50行:

50:switch($step) { 
        
51:	case '1'://协议
52:		include 'step_'.$step.'.php';
53:		break;
54:	case '2'://环境
55:		$pass = true;
56:		$PHP_VERSION = PHP_VERSION;
57:		if(version_compare($PHP_VERSION, '4.3.0', '<')) { 
        
58:			$php_pass = $pass = false;
59:		} else { 
        
60:			$php_pass = true;
61:		}

在此处,使用了一个switch语句来判断$step,当$setp=1时,就会包含step_1.php文件,该文件的作用就是通过检测install.lock文件来判断我们的系统是否已经安装。其代码如下:

if(file_exists("install.lock")){ 
        
	echo "
安装向导已运行安装过,如需重安装,请删除 /install/install.lock 文件
"
; }

而当step为2或其他是,就会进入系统安装步骤,所以,当我们抓包修改$step的值为2或者3之后,就会直接进入系统安装步骤,从而绕过了系统安装检测。

2、漏洞复现

如下图,是我们已经安装了的系统:
在这里插入图片描述

我们访问/install/index.php,然后使用burpsuite抓包,构造step=2,并修改传参方式为POST方式提交,成功绕过系统安装检测,进入系统安装步骤:

三、盾灵V.10系统重装漏洞

注: 盾灵系统包含了公众号推广系统、新闻发布系统、信息分享系统等,此次用作代码审计的是盾灵的公众号推广系统。

1、漏洞分析

首先我们先访问your-IP/install/index.php,效果如下,提供了两个检测步骤,一个是数据库连接检测,一个是文件写入权限检测。

然后我们把目光放到/install/index.php文件。里面主要是一些JS代码,使用了jqurey的ajax请求来发送数据到后端接口上。可以看到,在第36行到第42行,是使用了ajax请求发送数据库信息到mysql.php。

36:     $.post("mysql.php",
37{ 
        
38:      mysqlip:mysqlip,
39:      mysqlusername:mysqlusername,
40:      mysqluserpass:mysqluserpass,
41:      mysqldb:mysqldb
42},

然后我们顺着思路,再看看mysql.php文件,发现该文件的作用就是检测我们的数据库能否正常连接。


error_reporting(0);
header("Content-type: text/html; charset=utf-8");
$ip = $_POST['mysqlip'];
$username = $_POST['mysqlusername'];
$userpass = $_POST['mysqluserpass'];
$db = $_POST['mysqldb'];
$ok1 = mysql_connect($ip,$username,$userpass)or die("数据库连接错误,请检查账号或密码是否有误!");
$ok2 = mysql_select_db($db)or die("无法找到数据库,请检查数据库名称是否填写正确");
if($ok1 or $ok2){ 
        
    echo "ok";
}
?>

然后我们顺着思路,再来看看第二步的文件读写权限检测,在/install/index.php文件中,同样使用了ajax来请求后端接口,但是请求的文件是is_writable.php,并且出入了file参数为config.php.

$("#install_2").click(function(){ 
        
    $.post("is_writable.php",{ 
        
        file:'config.php'
}

然后发现if_writeable.php判断文件是否具有读写权限的方式就是通过is_writable()函数来判断config.php文件是否可写。

isset($_POST['file'])?$file = $_POST['file']:$file="config.php";
$is = is_writable($file);

当着两个检测项都检测成功后,就会弹出立即安装系统的选项。

而该选型的执行结果就是通过ajax发送连接数据库相关的参数到后端“steup.php文件”。

 $.post("setup.php",
    { 
        
      mysqlip:mysqlip,
      mysqlusername:mysqlusername,
      mysqluserpass:mysqluserpass,
      mysqldb:mysqldb
    },

在setup.php中,先是获取了连接数据库的各个参数,然后再次检测了数据库是否可以连接。如果数据库连接检测结果为OK,则会创建config.php文件。并且插入管理员的账号和密码,这里的密码是通过MD5加密了的,但是在安装成功后,会提示admin账户的密码是英文键盘第一行,所以也算是一个密码硬编码漏洞。

而在第29行,我们看到,它将/install目录下的index.php文件重命名为了index.lock文件。

16if($ok){ 
        
17$mysqlconfig = $ip.'@dunling@'.$username.'@dunling@'.$userpass.'@dunling@'.$db;
18$config_t = file_get_contents("mysql_config.dll");
19$config_a = array("@server@","@mysqlname@","@mysqlpass@","@mysqldb@");
20$config_b = array($ip,$username,$userpass,$db);:
21$mysqlconfig = str_replace($config_a,$config_b,$config_t);
22$fileok = file_put_contents("../config.php",$mysqlconfig);:
23if($fileok){ 
        
24echo "installok";
25$adminsql = "INSERT INTO `dunling_admin` VALUES ('1', 'admin', '90b9aa7e25f80cf4f64e990b78a9fc5ebd6cecad')";
26$configsql = "INSERT INTO `dunling_config` VALUES ('1', '盾灵微信加粉联盟系统', 'www.dunling.com', '1.00', '5000.00', '2.00', '10', '0.20', '0.00', '0','25')";
27mysql_query($configsql,$ok1);
28mysql_query($adminsql,$ok1);
29rename("index.php","index.lock");:
30}else{ 
        
31echo "installno";
32}

但是通过前面的分析,我们知道,安装系统实际上是在setup.php文件中进行的,但是该文件并没有被删除或者重命名,也就是说,如果我们直接构造数据库连接参数请求setup.php的话,就会绕过前面的数据库检测和文件权限检测,直接重新安装系统。

但是有一个值得注意的地方就是,在我们构造数据库连接参数的时候,相关参数是并不知道的,所以只能依靠社工或者其他的一些手段来获取,这在利用难度上还是相当大的。

2、漏洞复现

注: 杠刚刚提到,正常情况我们是不知道数据库连接参数的,但是这里我们模拟已经获取了相关参数进行实验。

首先我们看到,已经安装好的页面是下面这个样子的:

然后我们请求/install/setup.php文件,并使用burpsuite进行抓包,修改请求方式为POST,并设置传输数据为数据库相关参数,发送请求,可以看到安装成功的提示。


最后总结一下,作为目前被发现的时间上相对较近的两个系统重装漏洞,可见他们的漏洞逻辑都是由于安装和检测在不同的页面导致的安装检测可绕过的情形。可见这确实是系统安装检测中常见的问题,对于像我这种新入门的想要挖掘此类漏洞的可以多试试这种思路。

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章