1# Copyright (c) 2013-2017 CORE Security Technologies 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# Protocol Client Base Class definition 8# 9# Author: 10# Alberto Solino (@agsolino) 11# 12# Description: 13# Defines a base class for all clients + loads all available modules 14# 15# ToDo: 16# 17import os, sys, pkg_resources 18from impacket import LOG 19 20PROTOCOL_CLIENTS = {} 21 22# Base class for Protocol Clients for different protocols (SMB, MSSQL, etc) 23# Besides using this base class you need to define one global variable when 24# writing a plugin for protocol clients: 25# PROTOCOL_CLIENT_CLASS = "<name of the class for the plugin>" 26# PLUGIN_NAME must be the protocol name that will be matched later with the relay targets (e.g. SMB, LDAP, etc) 27class ProtocolClient: 28 PLUGIN_NAME = 'PROTOCOL' 29 def __init__(self, serverConfig, target, targetPort, extendedSecurity=True): 30 self.serverConfig = serverConfig 31 self.targetHost = target.hostname 32 # A default target port is specified by the subclass 33 if target.port is not None: 34 # We override it by the one specified in the target 35 self.targetPort = target.port 36 else: 37 self.targetPort = targetPort 38 self.target = target 39 self.extendedSecurity = extendedSecurity 40 self.session = None 41 self.sessionData = {} 42 43 def initConnection(self): 44 raise RuntimeError('Virtual Function') 45 46 def killConnection(self): 47 raise RuntimeError('Virtual Function') 48 49 def sendNegotiate(self, negotiateMessage): 50 # Charged of sending the type 1 NTLM Message 51 raise RuntimeError('Virtual Function') 52 53 def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 54 # Charged of sending the type 3 NTLM Message to the Target 55 raise RuntimeError('Virtual Function') 56 57 def sendStandardSecurityAuth(self, sessionSetupData): 58 # Handle the situation When FLAGS2_EXTENDED_SECURITY is not set 59 raise RuntimeError('Virtual Function') 60 61 def getSession(self): 62 # Should return the active session for the relayed connection 63 raise RuntimeError('Virtual Function') 64 65 def getSessionData(self): 66 # Should return any extra data that could be useful for the SOCKS proxy to work (e.g. some of the 67 # answers from the original server) 68 return self.sessionData 69 70 def getStandardSecurityChallenge(self): 71 # Should return the Challenge returned by the server when Extended Security is not set 72 # This should only happen with against old Servers. By default we return None 73 return None 74 75 def keepAlive(self): 76 # Charged of keeping connection alive 77 raise RuntimeError('Virtual Function') 78 79for file in pkg_resources.resource_listdir('impacket.examples.ntlmrelayx', 'clients'): 80 if file.find('__') >=0 or os.path.splitext(file)[1] == '.pyc': 81 continue 82 __import__(__package__ + '.' + os.path.splitext(file)[0]) 83 module = sys.modules[__package__ + '.' + os.path.splitext(file)[0]] 84 try: 85 pluginClasses = set() 86 try: 87 if hasattr(module,'PROTOCOL_CLIENT_CLASSES'): 88 for pluginClass in module.PROTOCOL_CLIENT_CLASSES: 89 pluginClasses.add(getattr(module, pluginClass)) 90 else: 91 pluginClasses.add(getattr(module, getattr(module, 'PROTOCOL_CLIENT_CLASS'))) 92 except Exception, e: 93 LOG.debug(e) 94 pass 95 96 for pluginClass in pluginClasses: 97 LOG.info('Protocol Client %s loaded..' % pluginClass.PLUGIN_NAME) 98 PROTOCOL_CLIENTS[pluginClass.PLUGIN_NAME] = pluginClass 99 except Exception, e: 100 LOG.debug(str(e)) 101 102