Empirecms7.5 Audit

EmpireCMS7.5 Audit

结构

解压下载的EmpireCMS压缩包之后,所有的代码都存储在upload文件夹中,打开文件夹其中很多以单词命名的目录。我认为如果对一个CMS进行整体的审计,需要弄清楚基本的结构才能着手开始。

d 附件和数据库存放目录(data)

d/file 附近存放目录

d/js js调用及生成目录

d/txt 文本内容目录

e 系统文件存放目录,存放如、后台登陆系统、系统核心部分、在线支付安装目录、新闻模块、评论等这是整个系统的心脏目录。

html 自定义的内容页面存放目录

images 系统默认模板图片存放目录

s 专题目录

search 搜索页面目录

skin 模板及图片存放目录

index.html 首页

e/class/connect.php 数据库参数配置文件

e/member/cp/ 前台会员控制面板地址

任意代码执行

1

首先阅读代码中的CMS安装流程。在doc/install.html文件中有说明,安装目录为/e/install

打开安装目录下的index.php,大致看一下应该是在web端安装CMS的控制页面。通常在这里可能会存在例如重新安装的漏洞,也可能会存在校验不足导致的恶意字符拼接入数据库。

e/install/index.php文件开头存在代码形成了安装锁

第657行中获取用户输入设置为表名前缀

![](/Users/ama666/Library/Application Support/typora-user-images/image-20190830212358361.png)

获取用户输入存入变量mydbtbpre,追踪该变量

/e/install/data/fun.phpDoRunQuery函数中使用含有用户输入的变量mydbtbpre替换字符串`phome_,拼接入sql变量。

e/install/data/fun.php文件中有一个名为DoRunQuery的函数

在函数开头用含有用户输入的变量mydbtbpre替换了默认表头phome_,并将此存入了sql变量中。我们看到后面程序使用正则表达式将用户输入的表头+表名匹配出来并在前端显示,此处可以用来做验证。在本函数中用户输入未经过滤直接拼接进入数据库。跟踪次函数

还是这个文件,在第592行执行了次函数,其中的参数正是用户输入的表头

接下来追踪变量从用户输入到存储进入数据库的过程,真正的过程应该是从后向前,但是为了理解方便,我用从前向后的方式描述变量的传递。

  • 首先在/e/install/index.php文件中通过用户输入框的形式获取用户输入并存入变量mydbtbpre,用户提交后存入_POST数组中。
  • 接下来调用统一文件下的SetDb函数将_POST数组作为参数设置数据库。
  • /e/install/data/fun.php文件中定义了SetDb函数,该函数将变量mydbtbpre作为参数调用了函数DoRunQuery
  • DoRunQuery将未经过滤的变量变量mydbtbpre替换默认的表头拼接入sql查询语句中并执行创建数据表语句。

2

在文件/e/admin/ebak/ChangeTable.php中。第247行,使用短标签的形式将数组r中的Number字段的内容复制给了tablename数组。

数组内的内容直接显示在了前端,其实也可以是一个XSS漏洞

在文件第294行调用了DoEbak函数进行备份,将带有恶意代码的数据库表进行备份,导致了任意代码执行,可以直接拦截请求将tbname参数之改为你想要执行的代码。

3

在文件/e/admin/db/DoSql.php第143行开始的函数是为了执行后台的执行SQL语句功能。首先使用如下sql命令

1
select sqltext from {$dbtbpre}enewssql where id='$id'

将要执行的sql语句存入变量r中。接下来没有对语句进行任何的过滤直接作为参数传递给了DoRunQuery函数。前面已经分析过,此函数内也是没有任何的过滤语句,仅仅使用了RepSqlTbpre函数替换了表名前缀之后,将要执行的SQL语句赋值给变量query后传参。

在文件的第189行执行了ExecSql函数

只需要在执行SQL语句功能的输入框内输入任何想执行的代码就可以了

但是一定注意要符合SQL语句的格式,否则会报错无法执行。

XSS

1

在文件/e/admin/openpage/AdminPage.php文件中使用hRepPostStr函数过滤了leftfile、mainfile和title变量

跟踪这一函数,/e/class/connect.php文件中

继续调用ehtmlaspcialchars函数对内容进行过滤。

次函数的实质就是调用htmlspecialchars函数处理字符串。

回到hRepPostStr函数,在将上图中的字符进行转义之后,调用CkPostStrChar函数,检查结尾是否含有”:\\“,最后调用AddAddData函数使用addslashes函数继续为字符产转义。

至此,程序只是对有限的特殊字符进行了过滤,甚至不包含括号。在此文件的第81行将变量leftfile在iframe的src标签中输出,因此可以简单的使用javascript伪协议进行弹窗。