class TIEOutputBot(Bot): def init(self): if DxlClient is None: raise ValueError( "Could not import 'dxlclient'. Please install it.") self.config = DxlClientConfig.create_dxl_config_from_file( self.parameters.dxl_config_file) self.dxlclient = DxlClient(self.config) def process(self): event = self.receive_message() payload = json.dumps(event) self.dxlclient.connect() tie_client = TieClient(self.dxlclient) tie_client.set_file_reputation( TrustLevel.MOST_LIKELY_MALICIOUS, { HashType.SHA256: event.get("malware.hash.sha256"), HashType.SHA1: event.get("malware.hash.sha1"), HashType.MD5: event.get("malware.hash.md5") }, filename=event.get("malware.name"), comment=self.parameters.comment) self.dxlclient.disconnect() self.logger.info("Event successfully sent.") self.acknowledge_message()
class EventPublisher(DxlPublisherInterface): def __init__(self): self.client = None def connect(self, config_file="./dxlclient.config"): if self.isConnected(): raise DxlJythonException( 1100, "Already connected to the OpenDXL broker") try: logger.info("Reading configuration file from '%s'", config_file) config = DxlClientConfig.create_dxl_config_from_file(config_file) # Initialize DXL client using our configuration self.client = DxlClient(config) # Connect to DXL Broker self.client.connect() return except Exception as e: logger.info("Exception: " + e.message) raise DxlJythonException( 1000, "Unable to establish a connection with the DXL broker") def sendMessage(self, topic="/dsa/dxl/test/event2", message="Default message"): if not self.isConnected(): raise DxlJythonException(1200, "Not connected to a OpenDXL broker") try: event = Event(topic) # Encode string payload as UTF-8 event.payload = message.encode() # Send event on DXL logger.info("Sending '" + message + "' to '" + topic + "'") self.client.send_event(event) return "Event successfully posted to topic '%s'" % topic except Exception as e: logger.info("Exception: " + e.message) raise DxlJythonException( 1010, "Unable to communicate with a DXL broker") def disconnect(self): if not self.isConnected(): return self.client.disconnect() def isConnected(self): if self.client is None: return False return self.client.connected
class DXLBroker(object): class MyEventCallback(EventCallback): def __init__(self, broker): EventCallback.__init__(self) self.broker = broker def on_event(self, event): self.broker.logger.threaddebug( f"{self.broker.device.name}: Message {event.message_id} ({event.message_type}), received: {event.destination_topic}, payload: {event.payload}" ) indigo.activePlugin.processReceivedMessage(self.broker.device.id, event.destination_topic, event.payload) def __init__(self, device): self.logger = logging.getLogger("Plugin.DXLBroker") self.deviceID = device.id address = device.pluginProps.get(u'address', "") port = device.pluginProps.get(u'port', "") ca_bundle = indigo.server.getInstallFolderPath( ) + '/' + device.pluginProps.get(u'ca_bundle', "") cert_file = indigo.server.getInstallFolderPath( ) + '/' + device.pluginProps.get(u'cert_file', "") private_key = indigo.server.getInstallFolderPath( ) + '/' + device.pluginProps.get(u'private_key', "") self.logger.debug( f"{device.name}: Broker __init__ address = {address}, ca_bundle = {ca_bundle}, cert_file = {cert_file}, private_key = {private_key}" ) device.updateStateOnServer(key="status", value="Not Connected") device.updateStateImageOnServer(indigo.kStateImageSel.SensorOff) # Create the client configuration broker = Broker.parse(f"ssl://{address}:{port}") config = DxlClientConfig(broker_ca_bundle=ca_bundle, cert_file=cert_file, private_key=private_key, brokers=[broker]) # Create the DXL client self.dxl_client = DxlClient(config) # Connect to the fabric self.dxl_client.connect() device.updateStateOnServer(key="status", value="Connected") device.updateStateImageOnServer(indigo.kStateImageSel.SensorOn) subs = device.pluginProps.get(u'subscriptions', None) if subs: for topic in subs: self.dxl_client.add_event_callback(topic, self.MyEventCallback(self)) self.logger.info(u"{}: Subscribing to: {}".format( device.name, topic)) def disconnect(self): device = indigo.devices[self.deviceID] self.dxl_client.disconnect() self.dxl_client.destroy() device.updateStateOnServer(key="status", value="Not Connected") device.updateStateImageOnServer(indigo.kStateImageSel.SensorOff) def publish(self, topic, payload=None, qos=0, retain=False): event = Event(topic) event.payload = payload self.dxl_client.send_event(event) def subscribe(self, topic): device = indigo.devices[self.deviceID] self.logger.info(f"{device.name}: Subscribing to: {topic}") self.dxl_client.add_event_callback(topic, self.MyEventCallback(self)) def unsubscribe(self, topic): device = indigo.devices[self.deviceID] self.logger.info(f"{device.name}: Unsubscribing from: {topic}") self.dxl_client.unsubscribe(topic)
class EventSender: TRUST_LEVEL = { 'NOT_SET': '0', 'KNOWN_MALICIOUS': '1', 'MOST_LIKELY_MALICIOUS': '15', 'MIGHT_BE_MALICIOUS': '30', 'UNKNOWN': '50', 'MIGHT_BE_TRUSTED': '70', 'MOST_LIKELY_TRUSTED': '85', 'KNOWN_TRUSTED': '99', 'KNOWN_TRUSTED_INSTALLER': '100' } broker_ca_bundle = tempfile.NamedTemporaryFile().name cert_file = tempfile.NamedTemporaryFile().name private_key = tempfile.NamedTemporaryFile().name def __init__(self, params: Dict): with open(self.broker_ca_bundle, "w") as text_file: text_file.write(params['broker_ca_bundle']) with open(self.cert_file, "w") as text_file: text_file.write(params['cert_file']) with open(self.private_key, "w") as text_file: text_file.write(params['private_key']) if 'broker_urls' in params: self.broker_urls = params['broker_urls'].split(',') self.push_ip_topic = params.get('push_ip_topic') self.push_url_topic = params.get('push_url_topic') self.push_domain_topic = params.get('push_domain_topic') self.push_hash_topic = params.get('push_hash_topic') self.client = DxlClient(self.get_client_config()) self.client.connect() def __del__(self): self.client.disconnect() def push_ip(self, ip, trust_level, topic): if not is_ip_valid(ip): raise ValueError(f'argument ip {ip} is not a valid IP') trust_level_key = self.TRUST_LEVEL[trust_level] if topic: self.push_ip_topic = topic self.send_event(self.push_ip_topic, f'ip:{ip};trust_level:{trust_level_key}') return f'Successfully pushed ip {ip} with trust level {trust_level}' def push_url(self, url, trust_level, topic): trust_level_key = self.TRUST_LEVEL[trust_level] if topic: self.push_url_topic = topic self.send_event(self.push_url_topic, f'url:{url};trust_level:{trust_level_key}') return f'Successfully pushed url {url} with trust level {trust_level}' def push_domain(self, domain, trust_level, topic): trust_level_key = self.TRUST_LEVEL[trust_level] if topic: self.push_domain_topic = topic self.send_event(self.push_domain_topic, f'domain:{domain};trust_level:{trust_level_key}') return f'Successfully pushed domain {domain} with trust level {trust_level}' def push_hash(self, hash_obj, trust_level, topic): trust_level_key = self.TRUST_LEVEL[trust_level] if topic: self.push_ip_topic = topic self.send_event(self.push_hash_topic, f'hash:{hash_obj};trust_level:{trust_level_key}') return f'Successfully pushed hash {hash_obj} with trust level {trust_level}' def get_client_config(self): config = DxlClientConfig( broker_ca_bundle=self.broker_ca_bundle, cert_file=self.cert_file, private_key=self.private_key, brokers=[Broker.parse(url) for url in self.broker_urls]) config.connect_retries = CONNECT_RETRIES config.reconnect_delay = RECONNECT_DELAY config.reconnect_delay_max = RECONNECT_DELAY_MAX return config def send_event(self, topic, payload): if not topic: raise Exception( f'Error in {demisto.command()} topic field is required') event = Event(topic) event.payload = str(payload).encode() self.client.send_event(event) def send_event_wrapper(self, topic, payload): self.send_event(topic, payload) return 'Successfully sent event'
class ServiceRequester(DxlRequesterInterface): def __init__(self): self.client = None def connect(self, config_file="./dxlclient.config"): if self.isConnected(): raise DxlJythonException(1100, "Already connected to the OpenDXL broker") try: logger.info("Reading configuration file from '%s'", config_file) config = DxlClientConfig.create_dxl_config_from_file(config_file) # Initialize DXL client using our configuration self.client = DxlClient(config) # Connect to DXL Broker self.client.connect() return except Exception as e: logger.info("Exception: " + e.message) raise DxlJythonException(1000, "Unable to establish a connection with the DXL broker") def sendMessage(self, topic="/dsa/dxl/test/event2", message="Default message"): if not self.isConnected(): raise DxlJythonException(1200, "Not connected to a OpenDXL broker") try: request = Request(topic) # Encode string payload as UTF-8 request.payload = message.encode() # Send Synchronous Request with default timeout and wait for Response logger.info("Requesting '" + message + "' from '" + topic + "'") response = self.client.sync_request(request) dxl_message = JavaDxlMessage() dxl_message.setMessageVersion(response.version) dxl_message.setMessageId(response.message_id) dxl_message.setClientId(response.source_client_id) dxl_message.setBrokerId(response.source_broker_id) dxl_message.setMessageType(response.message_type) dxl_message.setBrokerIdList(response.broker_ids) dxl_message.setClientIdList(response.client_ids) dxl_message.setRequestMessageId(response.request_message_id) # Check that the Response is not an Error Response, then extract if response.message_type != Message.MESSAGE_TYPE_ERROR: dxl_message.setServiceId(response.service_id) dxl_message.setPayload(response.payload.decode()) else: dxl_message.setErrorCode(response.error_code) dxl_message.setErrorMessage(response.error_message) return dxl_message except Exception as e: logger.info("Exception: " + e.message) raise DxlJythonException(1010, "Unable to communicate with a DXL broker") def disconnect(self): if not self.isConnected(): return self.client.disconnect() def isConnected(self): if self.client is None: return False; return self.client.connected