前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Centreon v19.04远程执行代码漏洞

Centreon v19.04远程执行代码漏洞

作者头像
洛米唯熊
发布2019-07-22 15:05:12
1.1K0
发布2019-07-22 15:05:12
举报
文章被收录于专栏:洛米唯熊

0x00简介:

Centreon是一个免费的开源基础设施监控软件,Centreon允许系统管理员从集中式Web应用程序监控其基础设施,Centreon已成为欧洲企业监控的头号开源解决方案。

Centreon作为nagios的分布式监控管理平台,其功能之强大,打造了centreon在IT监控方面强势地位,它的底层使用nagios监控软件,nagios通过ndoutil模块将监控数据写入数据库,centreon读取该数据并即时的展现监控信息,通过centreon可以简单地管理和配置所有nagios,因此,完全可以使用centreon轻易的搭建企业级分布式IT基础运维监控系统。

0x01:漏洞利用

利用nagios_bin参数中的任意命令在为轮询器设置新配置或更新配置时触发,攻击者可以控制一些参数,这些参数传递给DB-Func.php第506行的updateServer函数,此函数应该更新一些值并将它们添加到数据库中,因此我们可以从配置页面控制一个名为nagion_bin的用户输入并将我们的恶意代码注入其中,此参数在第551行中处理,此参数将从数据库中调用并传递给在generateFiles.php文件中的shell_exec函数行,所以我们稍后可以调用generateFiles.php来触发有效负载。

在分析Centreon代码的过程中,寻找RCE因为发现了许多处理操作系统命令的功能,所以我开始使用我编写的一个非常简单的python脚本列出所有不安全的函数。

初始结果包含大量使用“shell_exec,popen,system”函数的函数,经过一些分析后,注意到在include / configuration / configGenerate / xml / generateFiles.php 行中名为printDebug的函数中存在潜在的RCE。

generateFiles.php第189行代码起

function printDebug($xml, $tabs){ global $pearDB, $ret, $centreon, $nagiosCFGPath; $DBRESULT_Servers = $pearDB->query("SELECT `nagios_bin` FROM `nagios_server` " . "WHERE `localhost` = '1' ORDER BY ns_activate DESC LIMIT 1"); $nagios_bin = $DBRESULT_Servers->fetch(); $DBRESULT_Servers->closeCursor(); $msg_debug = array(); $tab_server = array(); foreach ($tabs as $tab) { if (isset($ret["host"]) && ($ret["host"] == 0 || in_array($tab['id'], $ret["host"]))) { $tab_server[$tab["id"]] = array( "id" => $tab["id"], "name" => $tab["name"], "localhost" => $tab["localhost"] ); } } foreach ($tab_server as $host) { $stdout = shell_exec( $nagios_bin["nagios_bin"] . " -v " . $nagiosCFGPath . $host["id"] . "/centengine.DEBUG 2>&1" );

正如我们在第211行中看到的那样,我们将一些变量传递给shell_exec函数而不进行消毒,变量$ nagios_bin [“nagios_bin”]在从数据库调用后传递给函数,我们可以在第193,194行看到已经进行了查询以提取一些信息,其中一个是$ nagios_bin [“nagios_bin”]变量。

现在我们需要知道如何控制这个值以及如何触发printDebug函数以执行我们的有效负载。

如果我们看看include / configuration / configServers / DB-Func.php 第#550行,我们可以看到该文件处理更新数据库中的某些值,其中一个是超出目标“nagios_bin”而不进行过滤,如下所示:

DB-Func.php第506行代码起

function updateServer(int $id, $data): void{ global $pearDB, $centreon; if ($data["localhost"]["localhost"] == 1) { $pearDB->query("UPDATE `nagios_server` SET `localhost` = '0'"); } if ($data["is_default"]["is_default"] == 1) { $pearDB->query("UPDATE `nagios_server` SET `is_default` = '0'"); } $rq = "UPDATE `nagios_server` SET "; isset($data["name"]) && $data["name"] != null ? $rq .= "name = '" . htmlentities($data["name"], ENT_QUOTES, "UTF-8") . "', " : $rq .= "name = NULL, "; isset($data["localhost"]["localhost"]) && $data["localhost"]["localhost"] != null ? $rq .= "localhost = '" . htmlentities($data["localhost"]["localhost"], ENT_QUOTES, "UTF-8") . "', " : $rq .= "localhost = NULL, "; isset($data["ns_ip_address"]) && $data["ns_ip_address"] != null ? $rq .= "ns_ip_address = '" . htmlentities(trim($data["ns_ip_address"]), ENT_QUOTES, "UTF-8") . "', " : $rq .= "ns_ip_address = NULL, "; isset($data["ssh_port"]) && $data["ssh_port"] != null ? $rq .= "ssh_port = '" . htmlentities(trim($data["ssh_port"]), ENT_QUOTES, "UTF-8") . "', " : $rq .= "ssh_port = '22', "; isset($data["init_system"]) && $data["init_system"] != null ? $rq .= "init_system = '" . htmlentities(trim($data["init_system"]), ENT_QUOTES, "UTF-8") . "', " : $rq .= "init_system = NULL, "; isset($data["init_script"]) && $data["init_script"] != null ? $rq .= "init_script = '" . htmlentities(trim($data["init_script"]), ENT_QUOTES, "UTF-8") . "', " : $rq .= "init_script = NULL, "; isset($data["init_script_centreontrapd"]) && $data["init_script_centreontrapd"] != null ? $rq .= "init_script_centreontrapd = '" . htmlentities( trim($data["init_script_centreontrapd"]), ENT_QUOTES, "UTF-8" ) . "', " : $rq .= "init_script_centreontrapd = NULL, "; isset($data["snmp_trapd_path_conf"]) && $data["snmp_trapd_path_conf"] != null ? $rq .= "snmp_trapd_path_conf = '" . htmlentities( trim($data["snmp_trapd_path_conf"]), ENT_QUOTES, "UTF-8" ) . "', " : $rq .= "snmp_trapd_path_conf = NULL, "; isset($data["nagios_bin"]) && $data["nagios_bin"] != null ? $rq .= "nagios_bin = '" . htmlentities(trim($data["nagios_bin"]), ENT_QUOTES, "UTF-8") . "', " : $rq .= "nagios_bin = NULL, ";

我们可以看到它只是使用htmlentities过滤数据,这意味着我们可以毫无问题地注入系统命令,理论上我们可以得到一个shell!

当然我们不能插入由htmlentites过滤的字符,但我们仍然执行在线程序来获取shell。

此函数的输入由位于include / configuration / configServers / formServers.php中的另一个名为formServers.php的 文件处理,调用此函数并传递表单提交数据的行是#300行,如下所示:

代码语言:javascript
复制
if ($form->validate()) {
    $nagiosObj = $form->getElement('id');
    if ($form->getSubmitValue("submitA")) {
       
        insertServerInDB($form->getSubmitValues());
    } elseif ($form->getSubmitValue("submitC")) {
        updateServer(
            (int) $nagiosObj->getValue(),
            $form->getSubmitValues()
        );
    }
    $o = null;
    $valid = true;
}

getSubmitValues()函数处理通过更新配置表单发送的POST请求。

为了更好地理解代码,我使用burp通过播放请求来实现这一点,并了解如何处理所需的值。

在burp中,我们可以在提交后看到以下请求:

正如我们所看到的那样,请求包含我们想要控制的nagion_bin,为了调试目的,我将编辑文件generateFiles.php以回显nagion_bin的值,以确保我们插入正确的值从数据库插入和调用,结果如下:

发送请求后,我们将获得以下信息:

证明是对的!我们打印出了测试路径值!所以我们只需要注入一个命令来执行它,但首先让我们找到正确的格式来注入我们的有效负载,回到generateFiles.php上的第212行,我们可以发现我们的命令是插入到第一行的意味着我们可以直接插入它并使用#注释掉行的其余部分,最终的有效载荷应该只是“command#”。

让我们尝试注入命令id#,看看会发生什么!

好极了!我们执行了命令!

利用写作

在确认RCE之后,我想在python中编写一个漏洞利用代码来自动化开发过程,并通过一次单击给你一个shell,漏洞利用写作阶段对我来说非常有趣,这里是完整的漏洞利用代码:

代码语言:javascript
复制
https://gist.github.com/mhaskar/c4255f6cf45b19b8a852c780f50576da

应用程序使用令牌处理每个请求以防止CSRF,因此我必须使用BeautifulSoup来处理此问题,以便在发送请求之前读取CSRF令牌,这是一个很好的部分!

运行漏洞利用后,我们弹出了一个shell!

本文翻译来自:https://shells.systems/centreon-v19-04-remote-code-execution-cve-2019-13024/

想了解更多 欢迎关注

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 洛米唯熊 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 利用写作
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档