在审计某CMS代码时,发现后台存在一处比较有意思的远程代码执行漏洞,这里跟大家分享下

漏洞分析

漏洞触发点位于下图代码段中

18198d7bef3600f760c2119c30c64ecc.png

见上图803行处,存在一处fwrite方法:

程序会将修改日志$log变量中的值保存到’/integrate_’ . $_SESSION[‘code’] .’_log.php’文件中

接下来看一下$log变量是如何拼接的:

$log变量是由如下一个或多个变量控制:$del_list、$rename_list以及$ignore_list

当这个三个变量存在时,则将其值拼接到$log变量中

这里着重看一下$ignore_list变量,分析代码可以发现,$ignore_list变量由下述代码中赋值得来

7683d7c5d4d1ca08b5e70174a93087fc.png

由上图代码可见$ignore_list变量由数据库中users表user_name数据组成。其实$ignore_list就是users表中flag等于4的所有user_name字段组成的列表

1b91284972c1113a79c2bf1fd70956e0.png

见上图,当请求中act参数值为sync时,并且当users表中存在flag=4的行时,触发此处$ignore_list赋值操作,将users表中flag等于4的所有行的user_name字段值插入$ignore_list列表

当$ignore_list列表非空时,触发同样在此if分支(请求中act参数值为sync的这个分支)中的漏洞点

0f0f4dc686ff9a92c9ba427a796015d6.png

上图红框处,$ignore_list列表中的用户名被取出,用来拼接$log变量,随后$log变量被写入’/integrate_’. $_SESSION[‘code’] . ‘_log.php’文件中

程序并未对会员用户名进行严格过滤,导致可以写入含有payload的用户名,例如

15d30f7d208c53a7ca582868cd4f5a9f.png

当我们将含有恶意payload用户名的用户flag设置为4时,通过访问

http://127.0.0.1/admin/integrate.php?act=sync

即可将含有payload用户名写入’/integrate_’ . $_SESSION[‘code’] . ‘_log.php’文件中

接下来分析下被插入payload文件的位置与名字

f05035aa16c4c659585e1e1a4602a72c.png

可见上图,这个文件位置很好定位,位于ROOT_PATH . DATA_DIR路径,即为data文件夹中。

关于文件名,中间存在一个$_SESSION[‘code’]变量,此处变量是可以设置的,但是如果我们不进行特殊设置的化,这个变量默认是空,因此我们并不需要额外的设置这个变量,默认让它为空就可以了,这样以来被插入后门的文件就变成

data/integrate__log.php

接下来分析下,如何使users中我们构造的恶意用户flag为4

默认情况下,会员用户flag为0,当会员整合功能被使用时,其他应用商城的会员被整合合并到这个cms时,当存在一些问题需要忽略这个用户时,flag才会被设置为4

如果使用这种方法,则需要攻击者自行搭建一个此cms允许合并数据的商城程序,在这个商城程序中构造一个会员,当使用会员合并功能时,使之出现问题,从而使得被合并的会员flag为4

利用会员整合功能修改flag值是一种途径,然而有一种更简便的方法。此cms程序后台存在可以管理数据库的功能,我们可以通过这个功能直接把用户名为”<?php phpinfo(); /*”的这条数据中flag字段设置为”4”,见下图

57a266774442cac19e1940f78a19be59.png

这样一来,当访问

http://127.0.0.1/admin/integrate.php?act=sync

时,该数据将会被取出,含有payload的用户名将会被写入日志文件中

ed203b9ab0d60983b3d416c61895714d.png

a87d9a0b26820ed3f67e5344a693c9f0.png

文件被访问时,payload执行

d2a929fbdeef3fa6abb0ec4db4d46af1.png