Skip to main content

Classes to support representation of the CASE Cyber Ontology

Project description

CASE Mapping Python

About the purpose and origins of this tool

INSPECTr Logo EU Flag



This tool allows the user to create a .json formatted CASE Bundle and add entities from the CASE and UCO ontologies. Work on it begun in 2020 as part of the INSPECTr project which received funding from the European Union’s Horizon 2020 research and innovation programme, under grant agreement No 833276. It was created for the internal purposes of the project and originally named CASE Builder. It was developed by Ray Genoe, Cormac Doherty, and Robert Dowdall of UCD - Centre for Cybersecurity and Cybercrime Investigation and Panos Protopapas of Inlecom Innovation. Throughout the development process Fabrizio Turchi of CNR aided the development by raising issues relating to (i) the creation of new CASE/UCO entities and (ii) changes that would make the tool more "CASE compliant".

Usage

In a nutshell, in order to create a CASE file you need to:

  • Create Facets describing all the information you'd like to record (Device Facets to describe devices, Email Address Facets to describe email addresses, etc.).
  • Append Facets to Objects that "enclose" them. The type of object depends on the facet; e.g, a Device Facet should be enclosed by an Observable Object. More than one Facet can be enclosed by the same object. For example, an Investigative Action Object can enclose both a Device Facet and an Action Facet (describing an investigative action performed on the device).
  • Append Objects to a CASE Bundle.

Codebase Structure

The central part of the codebase is located inside base.py that contains two classes (FacetEntity, ObjectEntity) and a helper function:

  • FacetEntity is the class that all ontology classes are inheriting from either directly (in the case of facet-classes) or through ObjectEntity (in the case of object-classes). FacetEntity includes all the type checking (e.g., that int types are provided where integers are expected according to the ontology) as well as error handling when incorrect data-types are passed.
  • ObjectEntity inherits FacetEntity and adds an @id value (random generated uuid4 string) to all classes inheriting from it. It also provides methods to append facet-classes to an object-class.
  • All classes included within all modules in the case and uco folders inherit from either of these two classes, depending on whether these are facets or objects.

Moreover, all modules within the case and uco folders include a directory variable; a dictionary returning a class object when provided with the class's type (the classes @type value). The directory.py module then aggregates all these variables and can be imported by the user and used when they require to create classes based on their type.

Example Usage

All instructions below follow the CASE bundle creation example provided in example.py which can be run via python3 example.py. Note that at any point in the example printing an object will return the object's contents (as a pretty-printed dictionary).

Import the package. This will provide access to the uco and case libraries where all object classses are located. The naming of all UCO and CASE classes follows that found in the equivalent ontologies, e.g., the Bundle class found in uco-core of the UCO ontology, is provided at uco.core.Bundle in the builder.

from case_mapping import *

Generate a CASE Bundle by calling on the Bundle object from uco.core, adding an (optional) uco_core_name. Also create an empty array where the investigative items will be appended at.

bundle = uco.core.Bundle(uco_core_name="A Deepthought Case File")

investigation_items = []

To report an observable (a device in this example) create an Observable Object (cyber_item1) and a Device Facet (device1) and append the facet to the object. Finally, add the observable (and appended facet) to the bundle.

cyber_item1 = uco.observable.ObservableObject()
device1 = uco.observable.FacetDevice(manufacturer="Canon", model="PowerShot SX540")
cyber_item1.append_facets(device1)
bundle.append_to_uco_object(cyber_item1)

To report the existence, contents, and related metadata of a paricular file in the Bundle, create an observable and append it to the array of investigation_items. Create a File Facet, a Content Data Facet, a Raster Picture Facet, and an EXIF Data Facet, and append all to the observable. Finally, add the observable to the bundle.

cyber_item2 = uco.observable.ObservableObject()
investigation_items.append(cyber_item2)  # NOTE: Appending whole object not just id
file1 = uco.observable.FacetFile(file_system_type="EXT4", file_name="IMG_0123.jpg", file_path="/sdcard/ImG_0123.jpg",
                                 file_extension="jpg", size_bytes=35002)
file_content1 = uco.observable.FacetContentData(byte_order="BigEndian", magic_number="/9j/ww==",
                                                mime_type="image/jpg", size_bytes=35000,
                                                data_payload="<base 64 encoded data of the file>",
                                                hash_method="SHA256",
                                                hash_value="6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b")
file_raster1 = uco.observable.FacetRasterPicture(picture_type="jpg", picture_height=12345, picture_width=12346, bits_per_pixel=2)
exif = {"Make": "Canon", "Model": "Powershot"}
file_exif1 = uco.observable.FacetEXIF(**exif)
cyber_item2.append_facets(file1, file_content1, file_raster1, file_exif1)
bundle.append_to_uco_object(cyber_item2)

To report an investigative action performed on a particular observable (a device in this example), create an Investigation Action and as before, append it to the investigation items. Append to the investigative action an Action Reference Facet and a Device Facet.

inv_act = case.investigation.InvestigativeAction(name="annotated", end_time="2010-01-15T18:59:43.25Z", start_time="2010-01-15T17:59:43.25Z")
investigation_items.append(inv_act)  # NOTE: Appending whole object not just id
action_ref = uco.action.FacetActionReferences(performer="Dave", instrument="DiskAnalysisTool", environment="Lab", location="Dublin")
device2 = uco.observable.FacetDevice(device_type="iphone", manufacturer="apple", model="6XS", serial="77")
inv_act.append_facets(action_ref, device2)
bundle.append_to_uco_object(inv_act)

To report the relationship between two observables, create a Cyber Relationship betweemn them and add it to the Bundle.

cyber_rel1 = uco.observable.CyberRelationship(source=cyber_item1,  # created previously in the example
                                              target=cyber_item2,  # created previously in the example
                                              kind_of_relationship="Contained_Within")
path_rel1 = uco.observable.FacetPathRelation(path="/sdcard/IMG_0123.jpg")
cyber_rel1.append_facets(path_rel1)
bundle.append_to_uco_object(cyber_rel1)

For each e-mail account that must be reported, first create an observable appending to it an Email Address Facet. Then, Then create a second observable appending to it an Email Account Facet, where when creating the latter you indicate the initial "Email Address" observable as an email_address.

email_address_object_1 = uco.observable.ObservableObject()
email_address_1 = uco.observable.FacetEmailAddress(email_address_value="test@test.com", display_name="George Test")
email_address_object_1.append_facets(email_address_1)

email_account_object_1 = uco.observable.ObservableObject()
account_1 = uco.observable.FacetEmailAccount(email_address=email_address_object_1)
email_account_object_1.append_facets(account_1)
bundle.append_to_uco_object(email_account_object_1)

To report an e-mail message, append an Email Message Facet to an observable, and append the latter to the Bundle.

cyber_item3 = uco.observable.ObservableObject()
email_msg = uco.observable.FacetEmailMessage(msg_to=[email_address_object_1, email_address_object_2],
                                             msg_from=email_address_object_1,
                                             subject="Revenge our father",
                                             body="To me, too, grant this boon-dark death to "
                                                  "deal unto Aegisthus, and to 'scape my doom.",
                                             received_time="2017-06-21T13:44:23.40Z",
                                             sent_time="2017-06-21T13:44:22.19Z",
                                             message_id="CAKBqNfyKo+ZXtkz6DUjWpvHy6"
                                                        "O82jTbkNA@mail.gmail.com")
cyber_item3.append_facets(email_msg)
bundle.append_to_uco_object(cyber_item3)

A phone number (or sms account) can be reported by appending a Phone Account Facet to an observable.

phone_account_object = uco.observable.ObservableObject()
phone_account1 = uco.observable.FacetPhoneAccount(phone_number="0035397876543")
phone_account_object.append_facets(phone_account1)
bundle.append_to_uco_object(phone_account_object)

An sms message can be reported by appending to an observable a Message Facet where the sender and receiver(s) of the sms message are reported by passing the observable objects holding the corresponding phone accounts as msg_to and msg_from properties; similarly, the application property must be filled with an observable object holding an Application Facet.

cyber_item4 = uco.observable.ObservableObject()
application_cyber_item = uco.observable.ObservableObject()
sms_application = uco.observable.FacetApplication(app_name="WhatsApp")
application_cyber_item.append_facets(sms_application)
sms_msg = uco.observable.FacetMessage(msg_to=[phone_account_object, phone_account_object2],
                                      msg_from=phone_account_object,
                                      message_text="A wedded wife, she slays her lord, "
                                                   "Helped by another hand!",
                                      sent_time="2017-06-20T09:34:42.12Z",
                                      application=application_cyber_item)
cyber_item4.append_facets(sms_msg)
bundle.append_to_uco_object(cyber_item4)

Reporting the identity of a person is done by first creating an Identity Object and appending to it a Simple Name Facet, and (if known) a Birthday Information Facet.

identity = uco.identity.Identity()
identity_name = uco.identity.FacetSimpleName(given_name="Forename", family_name="Family-name")
identity_birth = uco.identity.FacetBirthInformation(birthdate="01-01-1988")
identity.append_facets(identity_birth, identity_name)
bundle.append_to_uco_object(identity)

To report a location, create a Location Object and append to it a Location Facet.

location1 = uco.location.Location()
lat_long = uco.location.FacetLocation(latitude=61.185055, longitude=9.468836)
location1.append_facets(lat_long)
bundle.append_to_uco_object(location1)

Finally, an Investigation Object is being created where the investigation actions performed are being reported throught the core_objects parameter.

investigation = case.investigation.CaseInvestigation(focus="Transfer of Illicit Materials",
                                                     name="Crime A",
                                                     description="Inquiry into the transfer of illicit materials and "
                                                                 "the devices used to do so",
                                                     core_objects=investigation_items)
bundle.append_to_uco_object(investigation)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

case_mapping-0.1.0.tar.gz (38.3 kB view details)

Uploaded Source

Built Distribution

case_mapping-0.1.0-py3-none-any.whl (40.3 kB view details)

Uploaded Python 3

File details

Details for the file case_mapping-0.1.0.tar.gz.

File metadata

  • Download URL: case_mapping-0.1.0.tar.gz
  • Upload date:
  • Size: 38.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.0 CPython/3.12.4

File hashes

Hashes for case_mapping-0.1.0.tar.gz
Algorithm Hash digest
SHA256 72e5e946bf991ab2e9fdd41c067338f837b2dfa95a063f0d5cd1202c8bd41323
MD5 8846d678d5532083742d2e3127ce6b98
BLAKE2b-256 d1460445204a236ac09343663a59f452fe032d0823512e1b1d22217e7b47a71f

See more details on using hashes here.

File details

Details for the file case_mapping-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: case_mapping-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 40.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.0 CPython/3.12.4

File hashes

Hashes for case_mapping-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9921513a2d9b9cf0636a254fcc0b523741e01574f9ba76fd6748860b6004ee32
MD5 5c79ea10db6a3e72c7d9353ca7ef4379
BLAKE2b-256 657a8230ec19170793026ef52229ef0676ee2c093e68752c2cdd0acb4291826f

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page