代码审计入门-重装漏洞

前言

本菜最近在学代码审计,就想着把学习的东西一步步记录下来,也就有了此文。 在代码审计的时候,安装源码是第一步,所以,我们首先就会对安装文件进行审计,以此来发现重装漏洞。

原理

当我们管理者在安装完系统之后,如果没有对安装文件进行一个加锁或者删除,就有可能被攻击者进行利用。

危害

  • 重装系统到登录后台getshell
  • 重装系统在安装选项处插入payload getshell

分类

大致有这几种

  • 安装完之后,不加锁或者删除(完全没过滤)
  • 进行了加锁,但是代码没exit(没exit,继续执行后面的代码)
  • 安装文件按照步骤进行执行,step1进行了加锁,step2没进行加锁,直接执行step2
  • 可以GET,POST,COOKIE 任意提交一个变量名$insLockfile,给其赋空值,覆盖掉$insLockfile,从而让file_exists为false就不会退出(变量覆盖)

实际利用

我们根据前面这几种分类来进行一个学习。

完全没过滤

这里我们用S-cms来演示下。首先进入到它的安装文件 avatar 我们可以看到,这里以get请求来传step和action,如果action的值为savepath,就会把你cookie中的密码以txt的方法发送给你。继续往下看。 avatar 如果我们没传参,就会跳转到首页。继续看代码 步骤一 同意按照协议 avatar 步骤二 环境检测 avatar 步骤三 填写安装信息 avatar 步骤4 安装成功 avatar 可以看到,整个代码都没有类似于加锁或者删除文件的操作。所以我们可以直接访问http://www.scms.com/install/index.php?step1 来进行重装操作

代码没exit

可能代码中进行了加锁操作,但是没exit。这里以fengcms来进行演示。 这是install的一个结构 avatar step下的文件是安装步骤,每个步骤被分成了一个文件。data.php是数据连接文件。install.php是功能实现文件。install.sql是数据文件。 我们打开index.php avatar 这里首先会判断upload下有没有install这个文件,如果有,就会弹框,提示系统已安装,如果没有,就继续往下执行代码。但是这里我们可以看到,这里代码并没有退出执行的操作,所以弹完框之后,还是会执行下面的代码,也就是安装操作。后门的step都是功能实现代码了,没有任何lock等操作,所以这里我们可以直接访问这个/install/index.php 进行重装操作

有加锁,有exit,直接执行step

这种情况也适用于有加锁,有exit,step1有加锁有exit,直接执行step2。 这里我们以HuCart建站系统来进行演示。 首先看下install的目录结构 avatar 可以看到,这里还是以每个步骤一个文件来进行安装操作的。打开index.php avatar 首先会判断是否有hucart.com.install.lock.php这个文件,如果有就执行already.php。而already.php的功能是提示我们删除hucart.com.install.lock.php。然后退出这个这个if判断,else也就不执行了。可以看到,else下面是包含的step文件,也就是独立的step文件。因为里面没有加锁退出等操作,所以我们不访问/install/index.php ,而是访问/install/step1.php,来进行绕过重装操作。

变量覆盖导致系统重装

变量覆盖漏洞这里不详细说,后面会另外写一篇文章详细说。这里我们用frcms来进行演示。首先查看index.php avatar 来看几行关键代码。

$insLockfile = dirname(__FILE__).'/install_lock.txt';

把锁文件赋值给变量insLockfile。

if(file_exists($insLockfile)){
	exit(" 程序已运行安装,如果你确定要重新安装,请先从FTP中删除 install/install_lock.txt!");
}

然后进行一个判断,如果这个路径存在这个文件,即弹框程序已经安装。 这里看上去已经毫无办法。因为有锁文件,step的代码还是写在index.php里面的。 继续看一行代码。

foreach(Array('_GET','_POST','_COOKIE') as $_request){
	foreach($$_request as $_k => $_v) ${$_k} = _runmagicquotes($_v);
}

什么意思呢,就是说用户以get、post、cookie传过来的值,都会被定义。这里就有思路了,我们传一个insLockfile变量,值为服务器不存在的文件(为了简单省事,也可以直接传入数字)。这样insLockfile这个变量已经被我们重新定义了,因为为false,所以不会执行{}里面的操作,继续执行下面的代码。 所以我们可以post /install/index.php?insLockfile=1,post数据改为step里的数据包即可进行重装。

后记

写的很浅。文章里演示的cms,我这里都打包了。链接:https://pan.baidu.com/share/init?surl=bFrba6eGCibYDshDxMXKBQ 提取码 087m