【漏洞练习-Day10】FengCms 1.32与Simple-Log1.6网站重装漏洞

开始练习【红日团队】的PHP-Audit-Labs 代码审计 Day10
链接:https://github.com/hongriSec/PHP-Audit-Labs
感兴趣的同学可以去练习练习
预备知识:
内容题目均来自 PHP SECURITY CALENDAR 2017
Day 10 - Anticipation代码如下:

extract($_POST);

function goAway() {
  error_log("Hacking attempt.");
  header('Location: /error/');
}

if (!isset($pi) || !is_numeric($pi)) {
  goAway();
}

if (!assert("(int)$pi == 3")) {
  echo "This is not pi.";
} else {
  echo "This might be pi.";
}

漏洞解析 :
这道题目实际上讲的是当检测到攻击时,虽然有相应的防御操作,但是程序未立即停止退出,导致程序继续执行的问题。程序在第一行处 使用 extract函数,将POST请求的数据全都注册成变量。

extract () 函数:

(PHP 4, PHP 5, PHP 7)

功能:

extract() 函数从数组中将变量导入到当前的符号表。

定义:
extract(array,extract_rules,prefix)
说明:
参数 描述
array 必需。规定要使用的数组。
extract_rules 可选。extract() 函数将检查每个键名是否为合法的变量名,同时也检查和符号表中已存在的变量名是否冲突。对不合法和冲突的键名的处理将根据此参数决定。
prefix 可选。如果 extract_rules 参数的值是 EXTR_PREFIX_SAME、EXTR_PREFIX_ALL、 EXTR_PREFIX_INVALID 或 EXTR_PREFIX_IF_EXISTS,则 prefix 是必需的。

范例:

在这里插入图片描述
结果:

$a = Original; $b = Dog; $c = Horse; 
$dup_a = Cat

这样我们就可以控制 第8行处的pi 变量。

if (!isset($pi) || !is_numeric($pi)) {

程序对pi变量进行简单的验证,如果不是数字或者没有设置 pi变量,程序就会执行 goAway方法,即记录错误信息并直接重定向到 /error/页面。看来程序员这里是对非法的操作进行了一定的处理。但是关键在于,程序在处理完之后,没有立即退出,这样程序又会按照流程执行下去,也就到了第12行assert语句。

if (!assert("(int)$pi == 3")) {

由于前面pi变量可以被用户控制,所以在这一行存在远程代码执行漏洞

例如我们的payload为:pi=phpinfo() (这里为POST传递数据),然后程序就会执行这个 phpinfo 函数。当然,你在浏览器端可能看不到 phpinfo 的页面,而是像下面这样的图片:

在这里插入图片描述
在这里插入图片描述
为了方便大家理解,红日团队的大佬录制了debug程序的过程:点这里

实际上,这种案例在真实环境下还不少。例如有些CMS通过检查是否存在install.lock文件,从而判断程序是否安装过。如果安装过,就直接将用户重定向到网站首页,却忘记直接退出程序,导致网站重装漏洞的发生。下面我们来看两个真实的案例。

实例分析:

  • FengCms 1.32 网站重装漏洞

本次实例分析,我们选取的是 FengCms 1.32 。

漏洞POC 本站提供安全工具、程序(方法)可能带有攻击性,仅供安全研究与教学之用,风险自负!

漏洞分析:

对于一个已经安装好的 FengCms ,当用户再次访问 install/index.php 时,就会导致网站重装。我们来具体看下程序的逻辑:
现在正常页面:
在这里插入图片描述
install/index.php(25-135行)
在这里插入图片描述
我们可以看到,如果是第一次安装网站,程序会在 upload目录下(27行)生成一个 INSTALL 文件,用于表示该网站已经安装过(对应上图 25-28行 代码)。当我们再次访问该文件时,程序会先判断upload目录下是否有INSTALL文件。如果存在,则弹窗提示你先删除 INSTALL 文件才能进行网站重装(对应上图 1-4行 代码)。但是这里注意了,网站在弹出告警信息后,并没有退出,而是继续执行,所以我们在不删除 INSTALL 文件的情况下,仍可以重装网站

比较有趣的是,原本网站网站安装成功后,程序会自动删除upload目录下的所有文件,来防止攻击者重装网站,然而这段代码却在注释当中,具体原因不得而知。

/****
    case '6': //删除安装目录

		if(rmdirs(ROOT_PATH.'/install') or rmdir(ROOT_PATH.'/install')){

			  echo '<script type="text/javascript">alert("删除成功!");close();</script>';
			  exit();

		}else{
			  echo '<script type="text/javascript">alert("删除失败,请手工删除网站根目录下install目录!");close();</script>';
			  exit();
		}

	break;
***/

漏洞利用:

漏洞利用就极其简单了 ,我们直接访问 install/index.php 页面,无视弹出来的警告:

在这里插入图片描述
在这里插入图片描述

  • Simple-Log1.6网站重装漏洞

漏洞分析:

我们再来看 Simple-Log1.6网站重装的例子。其install\index.php 文件中,对网站安装成功的处理有问题,其代码是在下图 17-20行 ,程序只是用 header 函数将其重定向到网站首页,然而程序还是会继续执行下去。
在这里插入图片描述
而且程序的安装逻辑其实是有问题的,安装步骤由 $setup变量控制,而 $setup变量可以被用户完全控制(如上图 第10行 代码),攻击者完全可以控制网站的安装步骤。

漏洞利用:

Simple-Log 的重装利用:
http://10.211.55.2:100/Simple-Log1.6/upload/install/index.php
在这里插入图片描述
host=localhost&dbname=day9&dbuser=root&dbpass=root&dbprefix=&admin_user=admin&admin_pass=123456&blogname=admin&blogdesc=&setup=finish&button=%E5%BC%80%E5%A7%8B%E5%AE%89%E8%A3%85

修复建议:

实际上,要修复这一类型的漏洞,我们只要在正确的地方退出程序即可。拿这次的例题举例,我们只需要在检查到非法操作的时候,直接添加退出函数,即可避免漏洞发生。例如使用 dieexit等函数都是可以的,具体修复代码如下:
在这里插入图片描述

结语

再次感谢【红日团队】

发布了35 篇原创文章 · 获赞 19 · 访问量 5191

猜你喜欢

转载自blog.csdn.net/zhangpen130/article/details/104008350