Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.kodekutters.neo4j.ObservablesMaker.scala Maven / Gradle / Ivy
package com.kodekutters.neo4j
import java.util.UUID
import com.kodekutters.stix._
import com.typesafe.scalalogging.Logger
import org.neo4j.graphdb.Label.label
import org.neo4j.graphdb.{Node, RelationshipType}
/**
* make the Observables nodes and relations for the ObservedData SDO
*/
class ObservablesMaker(neoService: Neo4jDbService) {
// convenience implicit transformation from a string to a RelationshipType
implicit def string2relationshipType(x: String): RelationshipType = RelationshipType.withName(x)
val support = new MakerSupport(neoService)
val extensionsMaker = new ExtensionsMaker(neoService)
/**
* create the Observables nodes and relations for the parent ObservedData SDO node
*
* @param sourceNode the parent ObservedData SDO node
* @param objects the Observables
* @param obsIds the Observables ids
*/
def create(sourceNode: Node, objects: Map[String, Observable], obsIds: Map[String, String])(implicit logger: Logger) = {
// create the observable nodes and relations for each Observable
for ((k, obs) <- objects) {
// create the extensions ids
val ext_ids: Map[String, String] = (for (s <- obs.extensions.getOrElse(Map.empty).keySet) yield s -> UUID.randomUUID().toString).toMap
// create the observable node
val nodeOpt = neoService.transaction {
val theNode = neoService.graphDB.createNode(label(support.asCleanLabel(obs.`type`)))
theNode.addLabel(label("Observable"))
theNode.setProperty("type", obs.`type`)
theNode.setProperty("observable_id", obsIds(k))
theNode.setProperty("extensions", ext_ids.values.toArray)
theNode.setProperty("custom", support.asJsonString(obs.custom))
theNode
}
nodeOpt match {
case Some(node) =>
// create the Extension nodes and relations to this observable
extensionsMaker.create(node, obs.extensions, ext_ids)
// specify the observable attributes
specify(node, obs)
// create the relation to the parent node
neoService.transaction {
sourceNode.createRelationshipTo(node, "HAS_OBSERVABLE")
}.getOrElse(logger.error("could not process HAS_OBSERVABLE relation"))
case None => logger.error("could not create node Observable")
}
}
}
private def specify(node: Node, observable: Observable)(implicit logger: Logger) = {
// add the specific attributes to the observable node
observable match {
case x: Artifact =>
// create the hashes ids
val hashes_ids: Map[String, String] = (for (s <- x.hashes.getOrElse(Map.empty).keySet) yield s -> UUID.randomUUID().toString).toMap
neoService.transaction {
node.setProperty("mime_type", x.mime_type.getOrElse(""))
node.setProperty("payload_bin", x.payload_bin.getOrElse(""))
node.setProperty("url", x.url.getOrElse(""))
node.setProperty("hashes", hashes_ids.values.toArray)
}
// create the hashes objects and embedded relations
support.createHashes(node, x.hashes, hashes_ids)
case x: AutonomousSystem =>
neoService.transaction {
node.setProperty("number", x.number)
node.setProperty("name", x.name.getOrElse(""))
node.setProperty("rir", x.rir.getOrElse(""))
}
case x: Directory =>
neoService.transaction {
node.setProperty("path", x.path)
node.setProperty("path_enc", x.path_enc.getOrElse(""))
node.setProperty("created", x.created.getOrElse("").toString)
node.setProperty("modified", x.modified.getOrElse("").toString)
node.setProperty("accessed", x.accessed.getOrElse("").toString)
node.setProperty("contains_refs", x.contains_refs.getOrElse(List.empty).toArray)
}
case x: DomainName =>
neoService.transaction {
node.setProperty("value", x.value)
node.setProperty("resolves_to_refs", x.resolves_to_refs.getOrElse(List.empty).toArray)
}
case x: EmailAddress =>
neoService.transaction {
node.setProperty("display_name", x.display_name.getOrElse(""))
node.setProperty("belongs_to_ref", x.belongs_to_ref.getOrElse(""))
}
case x: EmailMessage =>
val headers_ids: Map[String, String] = (for (s <- x.additional_header_fields.getOrElse(Map.empty).keySet) yield s -> UUID.randomUUID().toString).toMap
neoService.transaction {
node.setProperty("is_multipart", x.is_multipart)
// todo body_multipart: Option[List[EmailMimeType]]
node.setProperty("body", x.body.getOrElse(""))
node.setProperty("date", x.date.getOrElse("").toString)
node.setProperty("content_type", x.content_type.getOrElse(""))
node.setProperty("from_ref", x.from_ref.getOrElse(""))
node.setProperty("sender_ref", x.sender_ref.getOrElse(""))
node.setProperty("to_refs", x.to_refs.getOrElse(List.empty).toArray)
node.setProperty("cc_refs", x.cc_refs.getOrElse(List.empty).toArray)
node.setProperty("bcc_refs", x.bcc_refs.getOrElse(List.empty).toArray)
node.setProperty("subject", x.subject.getOrElse(""))
node.setProperty("received_lines", x.received_lines.getOrElse(List.empty).toArray)
node.setProperty("additional_header_fields", headers_ids.values.toArray)
node.setProperty("raw_email_ref", x.raw_email_ref.getOrElse(""))
}
createHeaders(node, x.additional_header_fields, headers_ids)
case x: File =>
val hashes_ids: Map[String, String] = (for (s <- x.hashes.getOrElse(Map.empty).keySet) yield s -> UUID.randomUUID().toString).toMap
neoService.transaction {
node.setProperty("size", x.size.getOrElse(0))
node.setProperty("name", x.name.getOrElse(""))
node.setProperty("name_enc", x.name_enc.getOrElse(""))
node.setProperty("magic_number_hex", x.magic_number_hex.getOrElse(""))
node.setProperty("mime_type", x.mime_type.getOrElse(""))
node.setProperty("created", x.created.getOrElse("").toString)
node.setProperty("modified", x.modified.getOrElse("").toString)
node.setProperty("accessed", x.accessed.getOrElse("").toString)
node.setProperty("parent_directory_ref", x.parent_directory_ref.getOrElse(""))
node.setProperty("is_encrypted", x.is_encrypted.getOrElse(false))
node.setProperty("encryption_algorithm", x.encryption_algorithm.getOrElse(""))
node.setProperty("decryption_key", x.decryption_key.getOrElse(""))
node.setProperty("contains_refs", x.contains_refs.getOrElse(List.empty).toArray)
node.setProperty("content_ref", x.content_ref.getOrElse(""))
node.setProperty("hashes", hashes_ids.values.toArray)
}
support.createHashes(node, x.hashes, hashes_ids)
case x: IPv4Address =>
neoService.transaction {
node.setProperty("value", x.value)
node.setProperty("resolves_to_refs", x.resolves_to_refs.getOrElse(List.empty).toArray)
node.setProperty("belongs_to_refs", x.belongs_to_refs.getOrElse(List.empty).toArray)
}
case x: IPv6Address =>
neoService.transaction {
node.setProperty("value", x.value)
node.setProperty("resolves_to_refs", x.resolves_to_refs.getOrElse(List.empty).toArray)
node.setProperty("belongs_to_refs", x.belongs_to_refs.getOrElse(List.empty).toArray)
}
case x: MACAddress =>
neoService.transaction {
node.setProperty("value", x.value)
}
case x: Mutex =>
neoService.transaction {
node.setProperty("name", x.name)
}
case x: NetworkTraffic =>
val ipfix_ids: Map[String, String] = (for (s <- x.ipfix.getOrElse(Map.empty).keySet) yield s -> UUID.randomUUID().toString).toMap
neoService.transaction {
node.setProperty("start", x.start.getOrElse("").toString)
node.setProperty("end", x.end.getOrElse("").toString)
node.setProperty("is_active", x.is_active.getOrElse(false))
node.setProperty("src_ref", x.src_ref.getOrElse(""))
node.setProperty("dst_ref", x.dst_ref.getOrElse(""))
node.setProperty("src_port", x.src_port.getOrElse(0)) // todo <--- not correct
node.setProperty("dst_port", x.dst_port.getOrElse(0)) // todo <--- not correct
node.setProperty("protocols", x.protocols.getOrElse(List.empty).toArray)
node.setProperty("src_byte_count", x.src_byte_count.getOrElse(0))
node.setProperty("dst_byte_count", x.dst_byte_count.getOrElse(0))
node.setProperty("src_packets", x.src_packets.getOrElse(0))
node.setProperty("dst_packets", x.dst_packets.getOrElse(0))
node.setProperty("ipfix", ipfix_ids.values.toArray)
node.setProperty("src_payload_ref", x.src_payload_ref.getOrElse(""))
node.setProperty("dst_payload_ref", x.dst_payload_ref.getOrElse(""))
node.setProperty("encapsulates_refs", x.encapsulates_refs.getOrElse(List.empty).toArray)
node.setProperty("encapsulated_by_ref", x.encapsulated_by_ref.getOrElse(""))
}
createIpfix(node, x.ipfix, ipfix_ids)
case x: Process =>
val env_ids: Map[String, String] = (for (s <- x.environment_variables.getOrElse(Map.empty).keySet) yield s -> UUID.randomUUID().toString).toMap
neoService.transaction {
node.setProperty("is_hidden", x.is_hidden.getOrElse(false).toString)
node.setProperty("pid", x.pid.getOrElse(0)) // todo <-- not correct
node.setProperty("name", x.name.getOrElse(""))
node.setProperty("created", x.created.getOrElse("").toString)
node.setProperty("cwd", x.cwd.getOrElse(""))
node.setProperty("arguments", x.arguments.getOrElse(List.empty).toArray)
node.setProperty("command_line", x.cwd.getOrElse(""))
node.setProperty("environment_variables", env_ids.values.toArray)
node.setProperty("opened_connection_refs", x.opened_connection_refs.getOrElse(List.empty).toArray)
node.setProperty("creator_user_ref", x.creator_user_ref.getOrElse(""))
node.setProperty("binary_ref", x.binary_ref.getOrElse(""))
node.setProperty("parent_ref", x.parent_ref.getOrElse(""))
node.setProperty("child_refs", x.child_refs.getOrElse(List.empty).toArray)
}
createEnv(node, x.environment_variables, env_ids)
case x: Software =>
neoService.transaction {
node.setProperty("name", x.name)
node.setProperty("cpe", x.cpe.getOrElse(""))
node.setProperty("languages", x.languages.getOrElse(List.empty).toArray)
node.setProperty("vendor", x.vendor.getOrElse(""))
node.setProperty("version", x.version.getOrElse(""))
}
case x: URL =>
neoService.transaction {
node.setProperty("value", x.value)
}
case x: UserAccount =>
neoService.transaction {
node.setProperty("user_id", x.user_id)
node.setProperty("account_login", x.account_login.getOrElse(""))
node.setProperty("account_type", x.account_type.getOrElse(""))
node.setProperty("display_name", x.display_name.getOrElse(""))
node.setProperty("is_service_account", x.is_service_account.getOrElse(false))
node.setProperty("is_privileged", x.is_privileged.getOrElse(false))
node.setProperty("can_escalate_privs", x.can_escalate_privs.getOrElse(false))
node.setProperty("is_disabled", x.is_disabled.getOrElse(false))
node.setProperty("account_created", x.account_created.getOrElse("").toString)
node.setProperty("account_expires", x.account_expires.getOrElse("").toString)
node.setProperty("password_last_changed", x.password_last_changed.getOrElse("").toString)
node.setProperty("account_first_login", x.account_first_login.getOrElse("").toString)
node.setProperty("account_last_login", x.account_last_login.getOrElse("").toString)
}
case x: WindowsRegistryKey =>
neoService.transaction {
node.setProperty("key", x.key)
// todo values Option[List[WindowsRegistryValueType]]
node.setProperty("modified", x.modified.getOrElse("").toString)
node.setProperty("creator_user_ref", x.creator_user_ref.getOrElse(""))
node.setProperty("number_of_subkeys", x.number_of_subkeys.getOrElse(0))
}
case x: X509Certificate =>
val hashes_ids: Map[String, String] = (for (s <- x.hashes.getOrElse(Map.empty).keySet) yield s -> UUID.randomUUID().toString).toMap
neoService.transaction {
node.setProperty("is_self_signed", x.is_self_signed.getOrElse(false))
node.setProperty("version", x.version.getOrElse(""))
node.setProperty("serial_number", x.serial_number.getOrElse(""))
node.setProperty("signature_algorithm", x.signature_algorithm.getOrElse(""))
node.setProperty("issuer", x.issuer.getOrElse(""))
node.setProperty("validity_not_before", x.validity_not_before.getOrElse("").toString)
node.setProperty("validity_not_after", x.validity_not_after.getOrElse("").toString)
node.setProperty("subject", x.subject.getOrElse(""))
node.setProperty("subject_public_key_algorithm", x.subject_public_key_algorithm.getOrElse(""))
node.setProperty("subject_public_key_modulus", x.subject_public_key_modulus.getOrElse(""))
node.setProperty("subject_public_key_exponent", x.subject_public_key_exponent.getOrElse(0))
node.setProperty("hashes", hashes_ids.values.toArray)
// todo x509_v3_extensions: Option[X509V3ExtenstionsType]
}
support.createHashes(node, x.hashes, hashes_ids)
case _ =>
}
}
private def createEnv(sourceNode: Node, envOpt: Option[Map[String, String]], ids: Map[String, String])(implicit logger: Logger) = {
envOpt.foreach(env =>
for ((k, obs) <- env) {
val nodeOpt = neoService.transaction {
val theNode = neoService.graphDB.createNode(label("environment_variables"))
theNode.setProperty("environment_variables_id", ids(k))
theNode.setProperty(k, obs)
theNode
}
nodeOpt.foreach(node => {
neoService.transaction {
sourceNode.createRelationshipTo(node, "HAS_ENVIRONMENT_VARIABLE")
}.getOrElse(logger.error("could not process HAS_ENVIRONMENT_VARIABLE relation"))
})
}
)
}
private def createHeaders(sourceNode: Node, headersOpt: Option[Map[String, String]], ids: Map[String, String])(implicit logger: Logger) = {
headersOpt.foreach(headers =>
for ((k, obs) <- headers) {
val nodeOpt = neoService.transaction {
val theNode = neoService.graphDB.createNode(label("additional_header_fields"))
theNode.setProperty("additional_header_fields_id", ids(k))
theNode.setProperty(k, obs)
theNode
}
nodeOpt.foreach(node => {
neoService.transaction {
sourceNode.createRelationshipTo(node, "HAS_ADDITIONAL_HEADER_FIELD")
}.getOrElse(logger.error("could not process HAS_ADDITIONAL_HEADER_FIELD relation"))
})
}
)
}
private def createIpfix(sourceNode: Node, ipfixOpt: Option[Map[String, Either[Int, String]]], ids: Map[String, String])(implicit logger: Logger) = {
ipfixOpt.foreach(ipfix =>
for ((k, obs) <- ipfix) {
// either a int or string
val theValue = obs match {
case Right(x) => x
case Left(x) => x
}
val nodeOpt = neoService.transaction {
val theNode = neoService.graphDB.createNode(label(support.asCleanLabel("ipfix")))
theNode.setProperty("ipfix_id", ids(k))
theNode.setProperty(k, theValue)
theNode
}
nodeOpt.foreach(node => {
neoService.transaction {
sourceNode.createRelationshipTo(node, "HAS_IPFIX")
}.getOrElse(logger.error("could not process HAS_IPFIX relation"))
})
}
)
}
}