源码安装漏洞

一般在PHP源码程序都有一个初始安装的功能,如果相关代码没有对参数进行严禁的过滤,可能会导致攻击者访问安装页面(install.php)、或者构造数据包,对网站进行重新安装,从而危害网站安全,甚至直接拿到服务器权限。

安装页面可能产生的漏洞

无验证功能,任意重装覆盖
$_GET['step']跳过限制步骤
变量覆盖导致重装
判断 lock 后跳转无exit
解析 install.php.bak 漏洞
其他特定功能绕过漏洞

步骤2:代码审计

由于是审计安装相关的代码,我们打开install目录下的install.php文件,进行分析。

因篇幅问题,本文只截取其中相对重要的代码进行分析。

在其2~5行,代码如下:

if ( file_exists($_SERVER["DOCUMENT_ROOT"].'/sys/install.lock') )
{
 header( "Location: ../index.php" );
}

大意为:如果sys目录下存在install.lock,则跳转到index.php首页,如果不存在,则执行下面的安装程序代码。

因为在网页程序安装成功后,系统会在sys目录下生成install.lock文件,这样就避免了无验证功能,任意覆盖安装

但我们也明显发现了一处漏洞,在跳转首页后,没有用到exit对进程进行结束,就有可能导致重装漏洞。

我们继续往下看,在其116~148行附近,代码如下:


 mysql_query( "CREATE DATABASE $dbname", $con ) or die ( mysql_error() );



 $str_tmp="<?php\\\\r\\\\n";
 $str_end="?>";
 $str_tmp.="\r\n";
 $str_tmp.="error_reporting(0);\r\n";
 $str_tmp.="\r\n";
 $str_tmp.="if (!file_exists(\$_SERVER[\"DOCUMENT_ROOT\"].'/sys/install.lock')){\r\n\theader(\"Location: /install/install.php\");\r\nexit;\r\n}\r\n";
 $str_tmp.="\r\n";
 $str_tmp.="include_once('../sys/lib.php');\r\n";
 $str_tmp.="\r\n";
 $str_tmp.="\$host=\"$dbhost\"; \r\n";
 $str_tmp.="\$username=\"$dbuser\"; \r\n";
 $str_tmp.="\$password=\"$dbpass\"; \r\n";
 $str_tmp.="\$database=\"$dbname\"; \r\n";
 $str_tmp.="\r\n";
 $str_tmp.="\$conn = mysql_connect(\$host,\$username,\$password);\r\n";
 $str_tmp.="mysql_query('set names utf8',\$conn);\r\n";
 $str_tmp.="mysql_select_db(\$database, \$conn) or die(mysql_error());\r\n";
 $str_tmp.="if (!\$conn)\r\n";
 $str_tmp.="{\r\n";
 $str_tmp.="\tdie('Could not connect: ' . mysql_error());\r\n";
 $str_tmp.="\texit;\r\n";
 $str_tmp.="}\r\n";
 $str_tmp.="\r\n";
 $str_tmp.="session_start();\r\n";
 $str_tmp.="\r\n";
 $str_tmp.=$str_end;



 $fp=fopen( "../sys/config.php", "w" );
 fwrite( $fp, $str_tmp );
 fclose( $fp );

我们分为三段来看,

第一段:系统执行了创建数据库名的命令。 第二段:系统的配置信息。 第三段:将配置信息写入config.php文件。

因为数据库名称是由我们控制的,可以自定义输入,并且系统将我们输入的数据库名写入到了配置文件:config.php,而且在我们阅读的过程中,没有看到任何过滤函数。

也就可以尝试在数据库名称后构造语句,尝试插入恶意语句或者其他代码。 在config.php中,就可以直接执行我们插入的语句。

我们现在查看config.php文件。

<?php

error_reporting(0);

if (!file_exists($_SERVER["DOCUMENT_ROOT"].'/sys/install.lock')){
 header("Location: /install/install.php");
    exit;
}

include_once($_SERVER["DOCUMENT_ROOT"].'/sys/lib.php');

$host="localhost"; 
$username="root"; 
$password="root"; 
$database="vauditdemo"; --------

$conn = mysql_connect($host,$username,$password);
mysql_query('set names utf8',$conn);
mysql_select_db($database, $conn) or die(mysql_error());
if (!$conn)
{
 die('Could not connect: ' . mysql_error());
 exit;
}

session_start();

?>



在其第15行是接收数据库名的地方,我们所构造的语句当然也就在这里执行,但是构造的语法一定要符合逻辑与规范,否则网站就会出现报错。

我们可以尝试这样构造:

本来的语句是这样的:

$database="vauditdemo"; 

我们可以这样构造:

$database="pocabc; -- -"; phpinfo();//";

其中pocabc是要创建数据库的名称,这个可以随意命名,使用-- -注销掉后面的SQL语句,并使用";闭合掉原始的内容,最后再使用//注释掉后面的";

这样即成功将phpinfo()插入到数据库名中,又不影响正常SQL语句的执行。
漏洞修复

在install.php中后添加exit即可,如图:

Alt text

可以看到,加上exit后,再次提交则显示302转移信息,这样一来就修复了漏洞

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值