Example #1
0
def allow(target, actuator, modifier):

	cybox_address_obs = Observable.from_json(json.dumps(target["specifiers"]))
	address = str(cybox_address_obs.object_.properties.address_value)

	result_message = {}

	if "specifiers" in actuator:
	
		# Handling for specific devices - lookup on name or id
		if "name" in actuator["specifiers"]:

			actuator = Actuator.objects.get(name=actuator["specifiers"]["name"])
			result_message[actuator.name] = allow_address(address,actuator)

		elif "id" in actuator["specifiers"]:

			actuator = Actuator.objects.get(pk=actuator["specifiers"]["id"])
			result_message[actuator.name] = allow_address(address,actuator)

	else:
		
		for actuator in Actuator.objects.filter(openc2_type="network-ips"):

			result_message[actuator.name] = allow_address(address,actuator)

	if "respond-to" in modifier:
		if "command-ref" in modifier:
			ref=modifier["command-ref"]
		else:			
			ref=None

		respond_message(make_response_message(ref, "simple", {"address":address,"result":result_message}), modifier["respond-to"])
	
	return True
Example #2
0
def scan(target, actuator, modifier):

    cybox_address_obs = Observable.from_json(json.dumps(target["specifiers"]))
    address = str(cybox_address_obs.object_.properties.address_value)

    result = icmp_ping(address)

    if "respond-to" in modifier:
        if "command-ref" in modifier:
            ref = modifier["command-ref"]
        else:
            ref = None

        respond_message(
            make_response_message(ref, "simple", {
                "address": address,
                "ping": result
            }), modifier["respond-to"])

    return True
Example #3
0
def locate(target, actuator, modifier):

	cybox_address_obs = Observable.from_json(json.dumps(target["specifiers"]))

	address = str(cybox_address_obs.object_.properties.address_value)

	if is_public(address):

		country = geo_lookup(address)
		print country
		# Handle response
		if country and "respond-to" in modifier:

			if "command-ref" in modifier:
				ref = modifier["command-ref"]
			else:
				ref = None

			respond_message(make_response_message(ref, "simple", {"country":country}),modifier["respond-to"])

	return True
Example #4
0
def notify(target, actuator, modifier):

    cybox_address_obs = Observable.from_json(json.dumps(target["specifiers"]))
    send_from = str(cybox_address_obs.object_.properties.from_.address_value)
    # send_to only sends to the first email address
    send_to = str(cybox_address_obs.object_.properties.to[0])
    subject = str(cybox_address_obs.object_.properties.subject)
    message = str(cybox_address_obs.object_.properties.raw_body)

    result = send_mail(send_from, send_to, subject, message)

    if "respond-to" in modifier:
        if "command-ref" in modifier:
            ref = modifier["command-ref"]
        else:
            ref = None

        respond_message(
            make_response_message(ref, "simple", {
                "subject": subject,
                "sent": result
            }), modifier["respond-to"])

    return True
Example #5
0
	def dispatch(self,message,user):

		"""
			Name: dispatch
			Desc: 	Dispatch is called by the main /openc2/ api view. It actions which downstream host
					to send a received command to. It creates the job locally so it can be tracker
					and re-dresses the respond-to feilds so it can intercept command success/fail on
					downstream relays/actuators.
		"""

		logger.debug("Dispatcher called")
		capable_handlers = []

		# Check action / target type
		if message["action"] == 'query' and message["target"]["type"] == 'openc2:openc2':
			return HttpResponse(self.capabilities(),status=200)

		# If the message is a down stream response
		if message["action"].lower() == "response":

			response.response(message["target"], message.get("actuator"), message.get("modifiers"))
			return HttpResponse(status=200)

		# This is an action destined for a downstream host
		message['action'] = message['action'].lower()

		# Work out which downstreams are capable of this action
		capable = False

		if "specifiers" in message["actuator"]:

			# If the end user is targetting a specific actuator
			if "id" in message["actuator"]["specifiers"]:

				capable = Capability.objects.filter(actuator=message["actuator"]["type"],action=message["action"],requires__identifier=message["target"]["type"],remote_id=message["actuator"]["specifiers"]["id"],active=True)

			elif "name" in message["actuator"]["specifiers"]:

				capable = Capability.objects.filter(actuator=message["actuator"]["type"],action=message["action"],requires__identifier=message["target"]["type"],remote_name=message["actuator"]["specifiers"]["name"],active=True)

		else:

			capable = Capability.objects.filter(actuator=message["actuator"]["type"],action=message["action"],requires__identifier=message["target"]["type"],active=True)


		if capable:

			# Someone is capable of dealing with this message

			# Odds of the target being in our database is low - so will make a new one anyway
			# TODO: Expand this to handle other types (Network Connection)

			# False / Object
			target = False

			# Address Handling
			if message["target"]["type"] == "cybox:AddressObjectType":

				cybox_address_obs = Observable.from_json(json.dumps(message["target"]["specifiers"]))
				address = str(cybox_address_obs.object_.properties.address_value)
				target = Target(name="Auto Target - %s" % address,
								cybox_type=CybOXType.objects.get(identifier=message["target"]["type"]),
								raw_message=json.dumps(message["target"]["specifiers"]))
				logger.info("Target %s Created" % address)
				target.save()

			elif message["target"]["type"] == "cybox:NetworkConnectionObjectType":
				
				# TODO: Handler
				pass

			# If we have been able to assign a valid target
			if target:

				for capability in capable:

					new_job = Job(capability=capability,
							  target=target,
							  raw_message="Pending",
							  status=JobStatus.objects.get(status="Pending"),
							  created_by = user)
					
					new_job.save()

					command = {
						"action": capability.action, 
						"actuator": {
							"specifiers": {
								"id":capability.remote_id,
								"name":capability.remote_name,
							}, 
							"type": capability.actuator
						}, 
						"modifiers": {
								"respond-to": getattr(settings, "OPENC2_RESPONSE_URL", None)
						}, 
						"target": {
							"specifiers": json.loads(target.raw_message), 
							"type": capability.requires.identifier
						}
					}

					command["modifiers"]["command-ref"] = new_job.id

					logger.info("Job Created - Command - %s" % (json.dumps(command)))

					# Handle upstream respond to - send the copy back to us and pass it on to an upstream
					if "respond-to" in message["modifiers"]:

						new_job.upstream_respond_to = message["modifiers"]["respond-to"]
						new_job.upstream_command_ref = message["modifiers"]["command-ref"]

					new_job.raw_message = json.dumps(command,sort_keys=True,indent=4).replace("\t", u'\xa0\xa0\xa0\xa0\xa0')
					new_job.save()

					return HttpResponse(status=200)
			else:

				logger.error("Failed to identify target")
				return HttpResponse(status=501)
		else:

			return HttpResponse(status=501)