class Pipes(Thread): def __init__(self, transport, pipe, permissions, share=None): Thread.__init__(self) self.server = 0 self.transport = transport self.credentials = transport.get_credentials() self.tid = 0 self.fid = 0 self.share = share self.port = transport.get_dport() self.pipe = pipe self.permissions = permissions self.daemon = True def connectPipe(self): try: lock.acquire() global dialect #self.server = SMBConnection('*SMBSERVER', self.transport.get_smb_connection().getRemoteHost(), sess_port = self.port, preferredDialect = SMB_DIALECT) self.server = SMBConnection(self.transport.get_smb_connection().getRemoteName(), self.transport.get_smb_connection().getRemoteHost(), sess_port=self.port, preferredDialect=dialect) user, passwd, domain, lm, nt, aesKey, TGT, TGS = self.credentials if self.transport.get_kerberos() is True: print(self.transport) userCert, certPass = self.transport.get_certificate() self.server.kerberosCertificateLogin(userCert, certPass) #self.server.kerberosLogin(user, passwd, domain, lm, nt, aesKey, kdcHost=self.transport.get_kdcHost(), TGT=TGT, TGS=TGS) else: 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: import traceback traceback.print_exc() print("Something wen't wrong connecting the pipes(%s), try again" % self.__class__)
class SMBTransport(DCERPCTransport): """Implementation of ncacn_np protocol sequence""" # changed from original impacket def __init__(self, remoteName, dstport=445, filename='', username='', password='', domain='', lmhash='', nthash='', aesKey='', TGT=None, TGS=None, remote_host='', smb_connection=0, doKerberos=False, kdcHost=None, userCert=None, certPass=None): DCERPCTransport.__init__(self, remoteName, dstport) self.__socket = None self.__tid = 0 self.__filename = filename self.__handle = 0 self.__pending_recv = 0 if username != '': self.set_credentials(username, password, domain, lmhash, nthash, aesKey, TGT, TGS) # changed from original impacket else: self.set_certificate(userCert, certPass) self._doKerberos = doKerberos self._kdcHost = kdcHost if remote_host != '': self.setRemoteHost(remote_host) if smb_connection == 0: self.__existing_smb = False else: self.__existing_smb = True self.set_credentials(*smb_connection.getCredentials()) self.__prefDialect = None self.__smb_connection = smb_connection def preferred_dialect(self, dialect): self.__prefDialect = dialect def setup_smb_connection(self): if not self.__smb_connection: self.__smb_connection = SMBConnection( self.getRemoteName(), self.getRemoteHost(), sess_port=self.get_dport(), preferredDialect=self.__prefDialect) if self._strict_hostname_validation: self.__smb_connection.setHostnameValidation( self._strict_hostname_validation, self._validation_allow_absent, self._accepted_hostname) def connect(self): # Check if we have a smb connection already setup if self.__smb_connection == 0: self.setup_smb_connection() if self._doKerberos is False: self.__smb_connection.login(self._username, self._password, self._domain, self._lmhash, self._nthash) # changed from original impacket elif self._username is not '': self.__smb_connection.kerberosLogin(self._username, self._password, self._domain, self._lmhash, self._nthash, self._aesKey, kdcHost=self._kdcHost, TGT=self._TGT, TGS=self._TGS) # changed from original impacket else: self.__smb_connection.kerberosCertificateLogin( self._userCert, self._certPass) self.__tid = self.__smb_connection.connectTree('IPC$') self.__handle = self.__smb_connection.openFile(self.__tid, self.__filename) self.__socket = self.__smb_connection.getSMBServer().get_socket() return 1 def disconnect(self): self.__smb_connection.disconnectTree(self.__tid) # If we created the SMB connection, we close it, otherwise # that's up for the caller if self.__existing_smb is False: self.__smb_connection.logoff() self.__smb_connection.close() self.__smb_connection = 0 def send(self, data, forceWriteAndx=0, forceRecv=0): if self._max_send_frag: offset = 0 while 1: toSend = data[offset:offset + self._max_send_frag] if not toSend: break self.__smb_connection.writeFile(self.__tid, self.__handle, toSend, offset=offset) offset += len(toSend) else: self.__smb_connection.writeFile(self.__tid, self.__handle, data) if forceRecv: self.__pending_recv += 1 def recv(self, forceRecv=0, count=0): if self._max_send_frag or self.__pending_recv: # _max_send_frag is checked because it's the same condition we checked # to decide whether to use write_andx() or send_trans() in send() above. if self.__pending_recv: self.__pending_recv -= 1 return self.__smb_connection.readFile( self.__tid, self.__handle, bytesToRead=self._max_recv_frag) else: return self.__smb_connection.readFile(self.__tid, self.__handle) def get_smb_connection(self): return self.__smb_connection def set_smb_connection(self, smb_connection): self.__smb_connection = smb_connection self.set_credentials(*smb_connection.getCredentials()) self.__existing_smb = True def get_smb_server(self): # Raw Access to the SMBServer (whatever type it is) return self.__smb_connection.getSMBServer() def get_socket(self): return self.__socket def doesSupportNTLMv2(self): return self.__smb_connection.doesSupportNTLMv2()
class RemoteShell(cmd.Cmd): def __init__(self, server, port, credentials, tid, fid, share, transport): cmd.Cmd.__init__(self, False) self.prompt = '\x08' self.server = server self.transferClient = None self.tid = tid self.fid = fid self.credentials = credentials self.share = share self.port = port self.transport = transport self.intro = '[!] Press help for extra shell commands' def connect_transferClient(self): #self.transferClient = SMBConnection('*SMBSERVER', self.server.getRemoteHost(), sess_port = self.port, preferredDialect = SMB_DIALECT) self.transferClient = SMBConnection('*SMBSERVER', self.server.getRemoteHost(), sess_port=self.port, preferredDialect=dialect) user, passwd, domain, lm, nt, aesKey, TGT, TGS = self.credentials if self.transport.get_kerberos() is True: self.transferClient.kerberosLogin(user, passwd, domain, lm, nt, aesKey, kdcHost=self.transport.get_kdcHost(), TGT=TGT, TGS=TGS) else: self.transferClient.login(user, passwd, domain, lm, nt) def do_help(self, line): print(""" lcd {path} - changes the current local directory to {path} exit - terminates the server process (and this session) put {src_file, dst_path} - uploads a local file to the dst_path RELATIVE to the connected share (%s) get {file} - downloads pathname RELATIVE to the connected share (%s) to the current local dir ! {cmd} - executes a local shell cmd """ % (self.share, self.share)) self.send_data('\r\n', False) def do_shell(self, s): os.system(s) self.send_data('\r\n') def do_get(self, src_path): try: if self.transferClient is None: self.connect_transferClient() import ntpath filename = ntpath.basename(src_path) fh = open(filename,'wb') print("Downloading %s\\%s" % (self.share, src_path)) self.transferClient.getFile(self.share, src_path, fh.write) fh.close() except Exception as e: print(str(e)) pass self.send_data('\r\n') def do_put(self, s): try: if self.transferClient is None: self.connect_transferClient() params = s.split(' ') if len(params) > 1: src_path = params[0] dst_path = params[1] elif len(params) == 1: src_path = params[0] dst_path = '/' src_file = os.path.basename(src_path) fh = open(src_path, 'rb') f = dst_path + '/' + src_file pathname = f.replace('/','\\') print("Uploading %s to %s\\%s" % (src_file, self.share, dst_path)) if PY3: self.transferClient.putFile(self.share, pathname, fh.read) else: self.transferClient.putFile(self.share, pathname.decode(sys.stdin.encoding), fh.read) fh.close() except Exception as e: print(str(e)) pass self.send_data('\r\n') def do_lcd(self, s): if s == '': print(os.getcwd()) else: os.chdir(s) self.send_data('\r\n') def emptyline(self): self.send_data('\r\n') return def default(self, line): if PY3: self.send_data(line.encode('cp437')+b'\r\n') else: self.send_data(line.decode(sys.stdin.encoding).encode('cp437')+'\r\n') def send_data(self, data, hideOutput = True): if hideOutput is True: global LastDataSent LastDataSent = data else: LastDataSent = '' self.server.writeFile(self.tid, self.fid, data)