代码审计从0到1:Centreon One-click To RCE – 作者:知道创宇404实验室

前言

代码审计的思路往往是多种多样的,可以通过历史漏洞获取思路、黑盒审计快速确定可疑点,本文则侧重于白盒审计思路,对 Centreon V20.04[1] 的审计过程进行一次复盘记录,文中提及的漏洞均已提交官方并修复。

概述

Centreon(Merethis Centreon)是法国 Centreon 公司的一套开源的系统监控工具。该产品主要提供对网络、系统和应用程序等资源的监控功能。

网站基本结构

源代码目录组成

1598430635.png!small

centreon/www/网站根目录

1598430639.png!small

centreon/www/include/核心目录结构

1598430649.png!small

概述一下

  • centreon/www/index.php 是网站的入口文件,会先进行登录认证,未登录的话跳转进入登录页,登录成功后进入后台

  • centreon/www/main.php 与 centreon/www/main.get.php,对应 PC 端与移动端的路由功能,根据不同的参数,可以加载到后台不同的功能页面,在实际调试的过程,发现使用 main.php 加载对应的功能页时,最终会调用 main.get.php,所以路由部分直接看 main.get.php 即可

  • entreon/www/include/目录包含核心功能代码、公共类。其中有些功能代码可以直接通过路径访问,有些则需要通过 main.get.php 页面进行路由访问

  • centreon/www/api/目录下的 index.php 是另一处路由功能,可以实例化 centreon/www/api/class/*.class.php、centreon/www/modules/、centreon/www/widgets/*/webServices/rest/*.class.php、centreon/src/中的类并调用指定方法

在审计代码的时候,有两个要关注点:

  • 重点审查 centreon/www/include/和 centreon/www/api/class/两个目录,因为这些目录下的功能点可以通过 centreon/www/main.php 或 centreon/www/api/index.php 路由访问

  • 重点寻找绕过登录认证或者越权的方式,否则后台漏洞难以利用

代码分析

如下简要分析 centreon/www/目录下的部分脚本

index.php

index.php 会进行登录认证,检查是否定义$_SESSION[“centreon”] 变量,这个值在管理员登录后设置。程序登录有两种方式,使用账密或者 token,相关逻辑在/centreon/www/include/core/login/processLogin.php 中。不止 index.php,centreon/www/include/下大部分功能页都会检查 session,没有登录就无法访问

main.get.php

这是主要的路由功能,程序开头对数据进行过滤。$_GET 数组使用 fiter_var() 过滤处理,编码特殊字符,有效地防御了一些 XSS,比如可控变量在引号中的情况,无法进行标签闭合,无法逃逸单引号

1598430655.png!small

1598431213.png!small

对_POST 中的指定参数,进行过滤处理,对数据类型进行限制,对特殊字符进行编码

1598430660.png!small

最终_POST 数组赋值到$inputs 数组中

1598430673.png!small

全局过滤数据后,程序引入公共类文件和功能代码

1598430677.png!small

99 行 session 取出,认证是否登录

1598430681.png!small

通过登录认证后,程序会查询数据库,获取 page 与 url 的映射关系,程序通过 p 参数找到对应的 url,进行路由,映射关系如下

1598430687.png!small

接着 248 行 include_once $url,引入 centreon/www/include/下对应的脚本

1598430692.png!small

这里将 page 与 url 映射关系存储到本地,方便后续查询

1598430696.png!small

api/index.php

这是另外一个路由功能

1598431174.png!small

同样需要验证登录,104 行$_SERVER[‘HTTP_CENTREON_AUTH_TOKEN’] 可以在请求头中伪造,但是并不能绕过登录,可以跟进查看 CentreonWebService::router 方法

在\api\class\webService.class.php,其中 action 参数可控

1598431141.png!small

311 行判断 isService 是否为 true,如果是,dependencyInjector[‘centreon.webservice’]->get(object)

1598430791.png!small

313 行 centreon.webservice 属性值如下,对应的是 centreon/src 目录下的类

1598430783.png!small

$webServicePaths 变量包含以下类路径

1598430815.png!small

接着 346 行检查类中是否存在对应方法,在 374 行处调用,但是在 350~369 进行了第二次登录认证,所以之前$_SERVER[‘HTTP_CENTREON_AUTH_TOKEN’] 伪造并没能绕过登录

1598430822.png!small

过滤处理

除了 main.get.php 开头的全局过滤操作,程序的其他过滤都是相对较分散的,对于 SQL 注入的话,程序的很多查询都使用了 PDO 进行参数化查询,对于 PDO 中一些直接拼接的参数,则单独调用某些函数进行过滤处理。比如下边这里进行数据库更新操作时,updateOption() 会进行 query 操作,$ret[“nagios_path_img”] 可控,但是这里调用 escape() 函数进行转义

1598430826.png!small

路径限制

不通过路由功能,直接访问对应路径的功能代码,大部分是不被允许的,比如直接访问 generateFiles.php 页面

1598430830.png!small

可以看到 39 行检查 oreon 参数,这就是为什么要通过 main.get.php 去访问某些功能点。当然有一些漏网之鱼,比如 rename.php 页面,这里只是检查 session 是否存在,在登录状态下,可以通过路径直接访问该页面。

1598430835.png!small

One-click To RCE

XSS

在上一节的最后,为什么要纠结通过路径访问还是路由访问呢?因为通过 main.get.php 中的路由访问的话,会经过全局过滤处理,直接通过路径访问则没有,这样就有了产生漏洞的可能,通过这个思路可以找到一个 XSS 漏洞,在 rename.php 中程序将攻击者可控的内容直接打印输出,并且没有进行编码处理,缺乏 Httponly 与 CSP 等的攻击缓存机制,当管理员点击精心构造的链接时,将触发 XSS 执行任意 js 代码,导致 cookie 泄露。

漏洞分析

漏洞入口

centreon/include/home/customViews/rename.php1598430868.png!small

前边也提到,46 行验证 session 是否存在,所以受害者只要处于登录状态即可,59 行 echo 直接打印_REQUEST) 返回的值,rename 函数中对 params[‘newName’],因为直接通过路径访问,没有经过任何过滤处理

1598430893.png!small

所以 elementId 控制为 title_1(任意数字), 设置 newName 为 script 标签即可

1598430897.png!small

授权 RCE

程序在使用 perl 脚本处理 mib 文件时,没有对反引号的内容进行正确的过滤处理,攻击者利用 XSS 窃取的凭证登录后,可上传恶意文件导致远程代码执行,即 One_click to RCE

漏洞分析

可以顺着 CVE-2020-12688[2] 的思路,全局搜索”shell_exec(“关键字符串,formMibs.php 调用了该函数

1598430907.png!small

查看源码,38 行执行了 shell_exec(command 从 form),打印$form 方便调试

1598430913.png!small

之前记录的 page 与 url 的映射关系现在就可以派上用场了,设置 page 为 61703,通过 main.php 或 main.get.php 可以路由到 formMibs.php,也就是下边的文件上传功能

1598430914.png!small

调试发现 formMibs.php 中 31 行的 manufacturerId 可以通过上传数据包中 mnftr 字段修改,但是被 filter_var() 处理,只能为整数

1598431086.png!small

虽然缓存文件名是不可控的,但是上传的 mib 文件内容可控,shell_exec() 中执行的命令实际为(”xxx.mib”代表缓存文件名)

/usr/share/centreon/bin/centFillTrapDB -f 'xxx.mib' -m 3 --severity=info 2>&1

centFillTrapDB 是一个 perl 脚本,代码在/bin/centFillTrapDB 中,用 use 引入 centFillTrapDB 模块

1598430948.png!small

use 命令寻找的路径默认在 @INC 下,但不知道具体在哪里,可以全局搜索一下

1598430955.png!small

最后在 usr/share/perl5/vendor_perl/centreon 下找到 script 目录,有我们想要的文件

1598430958.png!small

把 centFillTrapDB 模块拉出来静态看一下,发现存在命令执行且内容可控的位置,实际调试发现最终分支是进入 541 行,540 行和 543 行是我添加的调试代码

1598430964.png!small

在 perl 中反引号内可以执行系统命令,534 行 trap_lookup 可控,对于 mib 文件来说,{IFS} 代替

1598430966.png!small

为了方便构造 mib 文件,打印出反引号中的命令,并在服务器 shell 中进行测试

1598430970.png!small

构造/tmp/1.mib 文件

1598430977.png!small

命令行执行

centFillTrapDB -f '/tmp/1.mib' -m 3 --severity=info 2>&1

可以清晰的看到 command,并且执行了 curl 命令

1598430982.png!small

修改 mib 文件中的命令,在浏览器上传进行测试,成功执行 whoami 并回显

1598430986.png!small

审计总结

文本主要分享了一些白盒审计思路,但就像之前所说的,审计的思路往往是多种多样的,以下是个人的小小总结:

  • 分析历史漏洞,在复现和调试的过程中,可以比较快的了解这个框架的结构,也可以从历史漏洞中获取思路,举一反三

  • 黑盒审计,开启抓包工具,测试可疑的功能点并观察数据包,这样可以加快对网站路由的熟悉,也可以快速的验证一些思路,排除一些可能性,仍然存疑的功能点可以在白盒审计时进一步确认;

  • 白盒审计,入口脚本,路由方式,核心配置,常用功能模块和数据验证过滤操作,这些都是要留意的,当然最主要还是看入口,路由和数据过滤验证的部分;其他的如核心配置,常用功能模块,可以按需查看,大概了解了网站架构就可以开始看对应的功能代码了,看的时候可以分两个角度:一个就是从刚才黑盒测试遗留的可疑点入手,断点功能代码,审查是否存在漏洞;另一个就是从敏感关键字入手,全局搜索,溯源追踪。

  • 注重不同漏洞的组合攻击,无论是这次的 Centreon One_click to RCE 漏洞,还是通达 OA 任意删除认证文件导致的未授权 RCE、PHPCMS V9 authkey 泄露导致的未授权 RCE,打的都是一套组合拳,在漏洞挖掘的过程可以多加关注

参考链接

[1] Centreon V20.04

https://github.com/centreon/centreon/releases/tag/20.04.0

[2] CVE-2020-12688漏洞公开细节

https://github.com/TheCyberGeek/Centreon-20.04

作者:huha@知道创宇404实验室
时间:2020年8月26日

原文链接:https://paper.seebug.org/1313/

来源:freebuf.com 2020-08-26 16:42:48 by: 知道创宇404实验室

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论