├── .DS_Store
├── .gitmodules
├── .gitignore
├── .github
└── workflows
│ └── cicd.yml
├── json
├── EVENT_RECORD_CASE_1.0.0.json
├── FILE_CASE_1.0.0.json
├── DEVICE_CASE_1.0.0.json
├── URL_HISTORY_CASE_1.0.0.json
├── CELL_SITE_CASE_1.0.0.json
├── Call_CASE_1.0.0.json
├── WIRELESS_NETWORK_CASE_1.0.0.json
├── EMAIL_MESSAGE_CASE_1.0.0.json
├── URL_HISTORY_MULTI_ITEMS_CASE_1.0.0.json
├── Message_CASE_1.0.0.json
└── ACTION_CASE_1.0.0.json
├── drafting.ttl
├── README.md
├── parserDebug.py
├── UFEDdebug.py
├── LICENSE
└── UFED_case_generator.py
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/casework/CASE-Implementation-UFED-XML/HEAD/.DS_Store
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "dependencies"]
2 | path = dependencies
3 | url = https://github.com/casework/CASE-Mapping-Python
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__/*
2 | _*
3 | *zip
4 | *err
5 | *wp?
6 | .DS_Stor*
7 | venv/*
8 | .github/workflows/*
9 | Makefile
10 |
--------------------------------------------------------------------------------
/.github/workflows/cicd.yml:
--------------------------------------------------------------------------------
1 | name: Continuous Integration
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | - develop
8 | pull_request:
9 | branches:
10 | - main
11 | - develop
12 |
13 | jobs:
14 | build:
15 | runs-on: ubuntu-latest
16 |
17 | steps:
18 | # Checkout the repository for processing
19 | - name: Checkout Repository
20 | uses: actions/checkout@v3
21 |
22 | # Test the output files to confirm they're both conformant to the CASE Ontology
23 | - name: CASE Validation
24 | uses: kchason/case-validation-action@v2.9.0
25 | with:
26 | case-path: ./json/
27 | case-version: "case-1.3.0"
28 |
--------------------------------------------------------------------------------
/json/EVENT_RECORD_CASE_1.0.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": {
3 | "kb": "http://example.org/kb/",
4 | "drafting": "http://example.org/ontology/drafting/",
5 | "co": "http://purl.org/co/",
6 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
7 | "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
8 | "uco-identity": "https://ontology.unifiedcyberontology.org/uco/identity/",
9 | "uco-location": "https://ontology.unifiedcyberontology.org/uco/location/",
10 | "uco-role": "https://ontology.unifiedcyberontology.org/uco/role/",
11 | "uco-action": "https://ontology.unifiedcyberontology.org/uco/action/",
12 | "uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
13 | "uco-types": "https://ontology.unifiedcyberontology.org/uco/types/",
14 | "uco-tool": "https://ontology.unifiedcyberontology.org/uco/tool/",
15 | "case-investigation": "https://ontology.caseontology.org/case/investigation/",
16 | "xsd": "http://www.w3.org/2001/XMLSchema#"
17 | },
18 | "uco-core:object": [
19 | {
20 | "@id": "kb:fe688202-4b21-48d2-b07d-170e14971935",
21 | "@type": "uco-observable:ObservableObject",
22 | "uco-core:hasFacet": [
23 | {
24 | "@id": "kb:a45c81a7-9afc-482d-9d37-a2b55ddb570d",
25 | "@type": "uco-observable:EventRecordFacet",
26 | "uco-observable:eventType": "PowerEvent",
27 | "uco-observable:eventRecordText": "Power on",
28 | "uco-observable:observableCreatedTime": {
29 | "@type": "xsd:dateTime",
30 | "@value": "2021-05-18T11:31:46+00:00"
31 | }
32 | }
33 | ]
34 | }
35 | ]
36 | }
--------------------------------------------------------------------------------
/drafting.ttl:
--------------------------------------------------------------------------------
1 | # imports: https://ontology.unifiedcyberontology.org/uco/action/1.0.0
2 | # imports: https://ontology.unifiedcyberontology.org/uco/configuration/1.0.0
3 | # imports: https://ontology.unifiedcyberontology.org/uco/core/1.0.0
4 | # imports: https://ontology.unifiedcyberontology.org/uco/identity/1.0.0
5 | # imports: https://ontology.unifiedcyberontology.org/uco/location/1.0.0
6 | # imports: https://ontology.unifiedcyberontology.org/uco/types/1.0.0
7 | # imports: https://ontology.unifiedcyberontology.org/uco/vocabulary/1.0.0
8 |
9 | @prefix action: .
10 | @prefix co: .
11 | @prefix configuration: .
12 | @prefix core: .
13 | @prefix identity: .
14 | @prefix location: .
15 | @prefix observable: .
16 | @prefix drafting: .
17 | @prefix owl: .
18 | @prefix rdf: .
19 | @prefix rdfs: .
20 | @prefix sh: .
21 | @prefix types: .
22 | @prefix vocabulary: .
23 | @prefix xsd: .
24 |
25 |
26 | a owl:Ontology ;
27 | rdfs:label "drafting"@en ;
28 | owl:imports
29 | action:1.0.0 ,
30 | configuration:1.0.0 ,
31 | core:1.0.0 ,
32 | identity:1.0.0 ,
33 | location:1.0.0 ,
34 | types:1.0.0 ,
35 | vocabulary:1.0.0
36 | ;
37 | owl:ontologyIRI ;
38 | owl:versionIRI drafting:1.0.0 ;
39 | .
40 |
41 | drafting:SearchedItemFacet
42 | a
43 | owl:Class ,
44 | sh:NodeShape
45 | ;
46 | rdfs:subClassOf core:Facet ;
47 | rdfs:label "SearchedItemFacet"@en ;
48 | rdfs:comment "A searched item facet is a grouping of characteristics unique to the strings searched by using a web browse."@en ;
49 | sh:property
50 | [
51 | sh:datatype xsd:string ;
52 | sh:maxCount "1"^^xsd:integer ;
53 | sh:nodeKind sh:Literal ;
54 | sh:path observable:searchValue ;
55 | ] ,
56 | [
57 | sh:datatype xsd:string ;
58 | sh:maxCount "1"^^xsd:integer ;
59 | sh:nodeKind sh:Literal ;
60 | sh:path observable:searchResult ;
61 | ] ,
62 | [
63 | sh:datatype xsd:dateTime ;
64 | sh:maxCount "1"^^xsd:integer ;
65 | sh:nodeKind sh:Literal ;
66 | sh:path observable:searchLaunchedTime ;
67 | ]
68 | ;
69 | sh:targetClass drafting:SearchedItemFacet ;
70 | .
71 |
--------------------------------------------------------------------------------
/json/FILE_CASE_1.0.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": {
3 | "kb": "http://example.org/kb/",
4 | "acme": "http://custompb.acme.org/core#",
5 | "drafting": "http://example.org/ontology/drafting/",
6 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
7 | "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
8 | "uco-identity": "https://ontology.unifiedcyberontology.org/uco/identity/",
9 | "uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
10 | "uco-types": "https://ontology.unifiedcyberontology.org/uco/types/",
11 | "uco-vocabulary": "https://ontology.unifiedcyberontology.org/uco/vocabulary/",
12 | "xsd": "http://www.w3.org/2001/XMLSchema#"
13 | },
14 | "uco-core:object": [
15 | {
16 | "@id": "kb:5e350cd9-3e48-4f8a-82f1-26e394e0780f",
17 | "@type": "uco-observable:ObservableObject",
18 | "uco-core:tag": "Uncategorized",
19 | "uco-core:hasFacet": [
20 | {
21 | "@id": "kb:0be208ff-034c-4529-b004-39b8426393b4",
22 | "@type": "uco-observable:FileFacet",
23 | "uco-observable:fileName": "Apple_iPhone X (A1901).zip",
24 | "uco-observable:filePath": "Apple_iPhone X (A1901).zip",
25 | "drafting:fileLocalPath": "files/Ucategorized/Apple_iPhone X (A1901).zip",
26 | "uco-observable:extension": ".zip",
27 | "uco-observable:accessedTime": {
28 | "@type": "xsd:dateTime",
29 | "@value": "1900-01-01T08:00:00+00:00"
30 | },
31 | "uco-observable:observableCreatedTime": {
32 | "@type": "xsd:dateTime",
33 | "@value": "1900-01-01T08:00:00+00:00"
34 | },
35 | "uco-observable:modifiedTime": {
36 | "@type": "xsd:dateTime",
37 | "@value": "1900-01-01T08:00:00+00:00"
38 | },
39 | "uco-observable:sizeInBytes": {
40 | "@type": "xsd:integer",
41 | "@value": 16965760332
42 | }
43 | },
44 | {
45 | "@id": "kb:097bc2b2-45e4-453a-a208-aeab7e77da99",
46 | "@type": "uco-observable:ContentDataFacet",
47 | "uco-observable:hash": [
48 | {
49 | "@id":"f1bfa603-2214-4d52-87b2-0afe244851de",
50 | "@type": "uco-types:Hash",
51 | "uco-types:hashMethod": {
52 | "@type": "uco-vocabulary:HashNameVocab",
53 | "@value": "SHA256"
54 | },
55 | "uco-types:hashValue": {
56 | "@type": "xsd:hexBinary",
57 | "@value": "4758982E5B94DF45F4400558608928F1A866104CB20A17BCB513D9B682644E484758982E5B94DF45F4400558608928F1A866104CB20A17BCB513D9B682644E48"
58 | }
59 | }
60 | ]
61 | }
62 | ]
63 | }
64 |
65 | ]
66 | }
--------------------------------------------------------------------------------
/json/DEVICE_CASE_1.0.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": {
3 | "kb": "http://example.org/kb/",
4 | "drafting": "http://example.org/ontology/drafting/",
5 | "co": "http://purl.org/co/",
6 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
7 | "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
8 | "uco-identity": "https://ontology.unifiedcyberontology.org/uco/identity/",
9 | "uco-location": "https://ontology.unifiedcyberontology.org/uco/location/",
10 | "uco-role": "https://ontology.unifiedcyberontology.org/uco/role/",
11 | "uco-action": "https://ontology.unifiedcyberontology.org/uco/action/",
12 | "uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
13 | "uco-types": "https://ontology.unifiedcyberontology.org/uco/types/",
14 | "uco-tool": "https://ontology.unifiedcyberontology.org/uco/tool/",
15 | "case-investigation": "https://ontology.caseontology.org/case/investigation/",
16 | "xsd": "http://www.w3.org/2001/XMLSchema#"
17 | },
18 | "uco-core:object": [
19 | {
20 | "@id": "kb:cbd39ad4-ab25-452d-b03e-10364c7fd40e",
21 | "@type": "uco-observable:ObservableObject",
22 | "rdfs:comment": "version: CASE 1.0.0",
23 | "rdfs:comment": "description: Device example complied with UCO/CASE 1.0.0"
24 | },
25 | {
26 | "@id": "kb:e4912cd1-abc3-4ad4-9d73-f54379752e02",
27 | "@type": "uco-observable:ObservableObject",
28 | "uco-core:hasFacet": [
29 | {
30 | "@id": "kb:22f9f968-e829-4a22-89fc-751feff9d0b0",
31 | "@type": "uco-observable:DeviceFacet",
32 | "uco-observable:deviceType": "Mobile phone",
33 | "uco-observable:model": "iPhone X",
34 | "uco-observable:serialNumber": "HW095687Y2022"
35 | },
36 | {
37 | "@id": "kb:1d4e9269-ad19-4fe4-8055-377301bdefde",
38 | "@type": "uco-observable:MobileDeviceFacet",
39 | "uco-observable:IMSI": "310260249043715",
40 | "uco-observable:ICCID": "8901260243790437158",
41 | "uco-observable:IMEI": "359405082912450",
42 | "uco-observable:MSISDN": "3383725981"
43 | },
44 | {
45 | "@id": "kb:6bd89154-b501-4fd8-a750-58d39e4a51e7",
46 | "@type": "uco-observable:OperatingSystemFacet",
47 | "uco-observable:displayName": "iOS",
48 | "uco-observable:manufacturer":
49 | {
50 | "@id": "kb:73952c43-8df5-4fa3-888c-f0f00d2eab8f"
51 | },
52 | "uco-observable:version": "14.6"
53 | },
54 | {
55 | "@id": "kb:75be1e84-348e-4d19-85d3-a1e23eed77cc",
56 | "@type": "uco-observable:BluetoothAddressFacet",
57 | "uco-observable:displayName": "Good hook",
58 | "uco-observable:addressValue": "D4:A3:3D:B5:F4:6C"
59 | },
60 | {
61 | "@id": "kb:a265c5ed-95c2-46e9-af91-4b73023f918b",
62 | "@type": "uco-observable:WifiAddressFacet",
63 | "uco-observable:addressValue": "D4:A3:3D:B5:F4:48"
64 | }
65 | ]
66 | },
67 | {
68 | "@id": "kb:73952c43-8df5-4fa3-888c-f0f00d2eab8f",
69 | "@type": "uco-identity:Identity",
70 | "uco-core:description": "Huawei UK"
71 | }
72 | ]
73 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## XML SAX parser for UFED/Cellebrite.
2 |
3 | [](https://github.com/casework/CASE-Implementation-UFED-XML/actions/workflows/cicd.yml)
4 | 
5 |
6 | The parser extracts some digital traces (Cyber items) from XML reports generated by UFED Physical Analyser (version 7.x) and convert them into UCO/CASE as JSON-LD files.
7 | =======
8 | The parser extracts the most relevat digital traces (cyber items) from XML reports generated by UFED Physical Analyser (version 7.x) and convert them into UCO/CASE as JSON-LD files.
9 |
10 | The UFED parser is able to process any report, regardless their size, it has been developed using **Python, version 3.x** and based on **SAX** (Simple API for XML).
11 |
12 | The UFED parser is composed of two different modules:
13 |
14 | * parser_UFEDtoCASE (XML parser program)
15 | * UFEDtoJSON.py (data converter into CASE-JSON-LD files)
16 |
17 | and it uses the **Case-Mapping-Python** (github.com/casework/CASE-Mapping-Python) repository as submodule, located in the folder
18 |
19 | * dependencies/CASE_Mapping_Python
20 |
21 | The CASE-Mapping-Python library is also part of the PyPI and can be used as a package.
22 |
23 |
24 | ## Requirements
25 | The tool has been developed in Python version 3.x and here are some required modules:
26 |
27 | * xml.sax (SAX classes)
28 | * argparse (args input management)
29 | * os (operating system utilities)
30 | * codecs (UTF-8 and other codec management)
31 | * re (regular expressions management)
32 | * uuid (global unique identifier management)
33 | * datetime
34 | * timeit
35 | * time
36 | * json
37 |
38 | ## Usage
39 |
40 | ```js
41 | > *parser_UFEDtoCASE.py [-h]*
42 | > *-r INFILEXML*
43 | > *-o OUTPUT_CASE_JSON*
44 | ```
45 | where:
46 |
47 | ```js
48 | * -h, --help (show the help message and exit)
49 | * -r | --report INFILEXML (the UFED XML report to be converted into CASE, compulsary)
50 | * -o | --output OUTPUT_CASE_JSON (CASE-JSON-LD file to be generated, compulsory)
51 | ```
52 |
53 | ## Mobile Forensic Data set
54 | The UFED parser has been developed and tested relying on a huge collection of mobile forensic dataset. This is composed of images made available on the Computer Forensic Reference Data Sets (CFReDS) Project and also on those provided by Cellebrite within he Catch The Flag annual competition.
55 |
56 | ## CASE representation: JSON-LD files
57 | All the XML reports have been processed to generate the corresponding CASE representation of the following Cyber items:
58 |
59 | * Calendar
60 | * Call
61 | * Cell Site
62 | * Chat (Whatsapp, Skype, etc.)
63 | * Contact
64 | * Cookie
65 | * Device Connectivity (Bluetooth connections)
66 | * Device Event
67 | * Email
68 | * File
69 | * Installed Application
70 | * Instant Message
71 | * Location (related to the Device)
72 | * Social Media Activity (drafting namespace)
73 | * SMS
74 | * URL History
75 | * Web Bookmarks
76 | * Wifi Connection
77 | * Chain of Evidence (represented as a relationship between the Artifact and the File/Db from which it was extracted)
78 | * Context
79 | * Device info
80 | * Tool
81 | * Performer
82 | * Provenance Record
83 | * Investigative Acquisition
84 | * Investigative Extraction
85 |
86 | ## XML reports
87 |
88 | The repo also includes the XMLreports folder containing examples of reports from Cellebrite UFED PA.
89 |
90 | ## Drafting TTL
91 |
92 | The drafting.ttl file describing the additional ontology classes based on the drafting namespace
93 |
94 | ## Development status
95 |
96 | This repository follows [CASE community guidance on describing development status](https://caseontology.org/resources/github_policies.html#development-statuses), by adherence to noted support requirements.
97 |
98 | The status of this repository is:
99 |
100 | 4 - Beta
101 |
--------------------------------------------------------------------------------
/json/URL_HISTORY_CASE_1.0.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": {
3 | "kb": "http://example.org/kb/",
4 | "drafting": "http://example.org/ontology/drafting/",
5 | "co": "http://purl.org/co/",
6 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
7 | "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
8 | "uco-identity": "https://ontology.unifiedcyberontology.org/uco/identity/",
9 | "uco-location": "https://ontology.unifiedcyberontology.org/uco/location/",
10 | "uco-role": "https://ontology.unifiedcyberontology.org/uco/role/",
11 | "uco-action": "https://ontology.unifiedcyberontology.org/uco/action/",
12 | "uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
13 | "uco-types": "https://ontology.unifiedcyberontology.org/uco/types/",
14 | "uco-tool": "https://ontology.unifiedcyberontology.org/uco/tool/",
15 | "case-investigation": "https://ontology.caseontology.org/case/investigation/",
16 | "xsd": "http://www.w3.org/2001/XMLSchema#"
17 | },
18 | "uco-core:object": [
19 | {
20 | "@id": "kb:5d96df90-d9e1-423c-b8db-c2327812ab38",
21 | "@type": "uco-observable:ObservableObject",
22 | "uco-core:hasFacet": [
23 | {
24 | "@id": "kb:1723ed9c-2d8e-415c-8cf6-31599c49df79",
25 | "@type": "uco-observable:ApplicationFacet",
26 | "uco-observable:applicationIdentifier": "Safari Apple",
27 | "uco-observable:version": "15.23.45"
28 | }
29 | ]
30 | },
31 | {
32 | "@id": "kb:39ff4987-8ae5-47e3-8369-dbd0d5f79398",
33 | "@type": "uco-observable:ObservableObject",
34 | "rdfs:comment": "@type=uco-observable:URLHistory",
35 | "uco-core:hasFacet": [
36 | {
37 | "@id": "kb:a455b867-957e-4fce-a0ad-1af9c6fa4edb",
38 | "@type": "uco-observable:URLHistoryFacet",
39 | "uco-observable:browserInformation": {
40 | "@id": "kb:5d96df90-d9e1-423c-b8db-c2327812ab38"
41 | },
42 | "uco-observable:urlHistoryEntry": [
43 | {
44 | "@id": "kb:193a7fc6-5f15-4b3c-8763-f1dc3c9bfd14",
45 | "@type": "uco-observable:URLHistoryEntry",
46 | "uco-observable:firstVisit": {
47 | "@type": "xsd:dateTime",
48 | "@value": "2017-01-25T02:20:22.00Z"
49 | },
50 | "uco-observable:lastVisit": {
51 | "@type": "xsd:dateTime",
52 | "@value": "2017-01-25T02:20:22.00Z"
53 | },
54 | "uco-observable:expirationTime": null,
55 | "rdfs:comment": "TODO: Was uco-observable:browserUserProfile meant to be an object property?",
56 | "drafting:browserUserProfileAccount": {
57 | "@id": "kb:profile-account-857c7f17-2f6b-4618-aeca-50d79fa69b97"
58 | },
59 | "uco-observable:url": {
60 | "@id": "kb:b7906534-0483-4cf4-979c-5351916602ed"
61 | },
62 | "uco-observable:referrerUrl": null,
63 | "uco-observable:pageTitle": "Where can you find baby owls for sale? Are owls legal to keep as pets? - Quora",
64 | "uco-observable:visitCount": 2,
65 | "uco-observable:manuallyEnteredCount": {
66 | "@type": "xsd:nonNegativeInteger",
67 | "@value": 0
68 | },
69 | "uco-observable:keywordSearchTerm": "Baby owl shops"
70 | }
71 | ]
72 | }
73 | ]
74 | },
75 | {
76 | "@id": "kb:b7906534-0483-4cf4-979c-5351916602ed",
77 | "@type": "uco-observable:URL",
78 | "uco-core:hasFacet": [
79 | {
80 | "@id": "kb:f2618636-aec3-459e-bda7-eeedfbeac3c0",
81 | "@type": "uco-observable:URLFacet",
82 | "uco-observable:fullValue": "https://www.quora.com/Where-can-you-find-baby-owls-for-sale-Are-owls-legal-to-keep-as-pets"
83 | }
84 | ]
85 | }
86 | ]
87 | }
88 |
--------------------------------------------------------------------------------
/json/CELL_SITE_CASE_1.0.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": {
3 | "kb": "http://example.org/kb/",
4 | "acme": "http://custompb.acme.org/core#",
5 | "drafting": "http://example.org/ontology/drafting/",
6 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
7 | "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
8 | "uco-identity": "https://ontology.unifiedcyberontology.org/uco/identity/",
9 | "uco-location": "https://ontology.unifiedcyberontology.org/uco/location/",
10 | "uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
11 | "uco-types": "https://ontology.unifiedcyberontology.org/uco/types/",
12 | "uco-vocabulary": "https://ontology.unifiedcyberontology.org/uco/vocabulary/",
13 | "xsd": "http://www.w3.org/2001/XMLSchema#"
14 | },
15 | "uco-core:object": [
16 | {
17 | "@id": "kb:dc9b8413-f681-4bc6-a66e-b70a7ecde4d4",
18 | "@type": "uco-observable:ObservableObject",
19 | "rdfs:comment": "@type=uco-observable:CellSite",
20 | "uco-core:hasFacet": [
21 | {
22 | "@id": "kb:fcfa96c3-3824-4132-a156-8ac857800c05",
23 | "@type": "uco-observable:CellSiteFacet",
24 | "uco-observable:cellSiteType": "GSM",
25 | "uco-observable:cellSiteCountryCode": "228",
26 | "uco-observable:cellSiteNetworkCode": "2",
27 | "uco-observable:cellSiteLocationAreaCode": "22100",
28 | "uco-observable:cellSiteIdentifier": "29220952"
29 | },
30 | {
31 | "@id": "kb:749dc5c5-f3f2-4e9b-b53c-89bfaf177d76",
32 | "@type": "uco-observable:AntennaFacet",
33 | "uco-observable:azimuth": {
34 | "@type": "xsd:decimal",
35 | "@value": "45"
36 | },
37 | "uco-observable:elevation": {
38 | "@type": "xsd:decimal",
39 | "@value": "5"
40 | },
41 | "uco-observable:skew": {
42 | "@type": "xsd:decimal",
43 | "@value": "10"
44 | },
45 | "uco-observable:horizontalBeamWidth": {
46 | "@type": "xsd:decimal",
47 | "@value": "110"
48 | },
49 | "uco-observable:signalStrength": {
50 | "@type": "xsd:decimal",
51 | "@value": "20"
52 | },
53 | "uco-observable:antennaHeight": {
54 | "@type": "xsd:decimal",
55 | "@value": "25"
56 | }
57 | }
58 | ]
59 | },
60 | {
61 | "@id": "kb:f2e90997-16c9-4822-be30-fa4f36553768",
62 | "@type": "uco-observable:ObservableObject",
63 | "uco-core:hasFacet": [
64 | {
65 | "@id": "kb:e7540964-bca0-4dbe-a886-fdd2115d6aed",
66 | "@type": "uco-location:LatLongCoordinatesFacet",
67 | "uco-location:latitude": {
68 | "@type": "xsd:decimal",
69 | "@value": "40.05659866"
70 | },
71 | "uco-location:longitude": {
72 | "@type": "xsd:decimal",
73 | "@value": "-75.67047119"
74 | }
75 | }
76 | ]
77 | },
78 |
79 | {
80 | "@id": "kb:cdf48c35-c65d-41e4-843b-720f1ad24ab3",
81 | "@type": "uco-observable:ObservableRelationship",
82 | "uco-observable:startTime": {
83 | "@type": "xsd:dateTime",
84 | "@value": "2018-06-12T09:10:11Z"
85 | },
86 | "uco-observable:endTime": {
87 | "@type": "xsd:dateTime",
88 | "@value": "2018-06-12T15:36:39Z"
89 | },
90 | "uco-core:source": {
91 | "@id": "kb:dc9b8413-f681-4bc6-a66e-b70a7ecde4d4"
92 | },
93 | "uco-core:target": {
94 | "@id": "kb:f2e90997-16c9-4822-be30-fa4f36553768"
95 | },
96 | "uco-core:kindOfRelationship": "Located_At",
97 | "uco-core:isDirectional": {
98 | "@type": "xsd:boolean",
99 | "@value": true
100 | }
101 | }
102 |
103 | ]
104 | }
105 |
--------------------------------------------------------------------------------
/json/Call_CASE_1.0.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": {
3 | "kb": "http://example.org/kb/",
4 | "drafting": "http://example.org/ontology/drafting/",
5 | "co": "http://purl.org/co/",
6 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
7 | "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
8 | "uco-identity": "https://ontology.unifiedcyberontology.org/uco/identity/",
9 | "uco-location": "https://ontology.unifiedcyberontology.org/uco/location/",
10 | "uco-role": "https://ontology.unifiedcyberontology.org/uco/role/",
11 | "uco-action": "https://ontology.unifiedcyberontology.org/uco/action/",
12 | "uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
13 | "uco-types": "https://ontology.unifiedcyberontology.org/uco/types/",
14 | "uco-tool": "https://ontology.unifiedcyberontology.org/uco/tool/",
15 | "case-investigation": "https://ontology.caseontology.org/case/investigation/",
16 | "xsd": "http://www.w3.org/2001/XMLSchema#"
17 | },
18 | "uco-core:object": [
19 | {
20 | "@id": "kb:0d191a90-7f5f-4df7-9cc3-3b5024e66983",
21 | "@type": "uco-observable:ObservableObject",
22 | "uco-core:name": "Native application",
23 | "uco-core:hasFacet": [
24 | {
25 | "@id": "kb:f35ce51a-cb45-49ca-83d1-546cedd73b21",
26 | "@type": "uco-observable:ApplicationFacet",
27 | "uco-observable:applicationIdentifier": "Native"
28 | }
29 | ]
30 | },
31 | {
32 | "@id": "kb:d4d81ef9-9598-4e29-aaf6-297c47315269",
33 | "@type": "uco-observable:ObservableObject",
34 | "uco-core:hasFacet": [
35 | {
36 | "@id": "4cb32da0-4d54-49c6-9de7-961135c86578",
37 | "@type": "uco-observable:AccountFacet",
38 | "uco-observable:accountIdentifier": "Rose Noomur",
39 | "uco-observable:isActive": {
40 | "@type": "xsd:boolean",
41 | "@value": true
42 | }
43 | },
44 | {
45 | "@id": "d25ecc35-74ea-4c82-b7e3-4e082a7c6e54",
46 | "@type": "uco-observable:PhoneAccountFacet",
47 | "uco-observable:phoneNumber": "+19734468551"
48 | }
49 | ]
50 | },
51 | {
52 | "@id": "kb:e91445f8-406b-4ade-bd12-ec9ecdce5810",
53 | "@type": "uco-observable:ObservableObject",
54 | "uco-core:hasFacet": [
55 | {
56 | "@id": "fdf3e4cf-8d9b-4959-97f1-3506e5132ac9",
57 | "@type": "uco-observable:AccountFacet",
58 | "uco-observable:accountIdentifier": "Jane Malone",
59 | "uco-observable:isActive": {
60 | "@type": "xsd:boolean",
61 | "@value": true
62 | }
63 | },
64 | {
65 | "@id": "b9f40fda-b69f-48c6-9efd-d1c3858bbb26",
66 | "@type": "uco-observable:PhoneAccountFacet",
67 | "uco-observable:phoneNumber": "+19732941683/19732941683",
68 | "uco-observable:displayName": "Jane M."
69 | }
70 | ]
71 | },
72 | {
73 | "@id": "kb:238070ba-b740-4aa9-89af-4f52d0efc1a0",
74 | "@type": "uco-observable:ObservableObject",
75 | "uco-core:hasFacet": [
76 | {
77 | "@id": "kb:a8bdd70b-3d5d-4196-8f27-45ff429fbc6f",
78 | "@type": "uco-observable:CallFacet",
79 | "uco-observable:callType": "incoming",
80 | "uco-observable:allocationStatus": "Intact",
81 | "uco-observable:duration": {
82 | "@type": "xsd:integer",
83 | "@value": "0"
84 | },
85 | "uco-observable:startTime": {
86 | "@type": "xsd:dateTime",
87 | "@value": "2022-01-19T21:38:19.023000+00:00"
88 | },
89 | "uco-observable:application": {
90 | "@id": "kb:0d191a90-7f5f-4df7-9cc3-3b5024e66983"
91 | },
92 | "uco-observable:from": {
93 | "@id": "kb:d4d81ef9-9598-4e29-aaf6-297c47315269"
94 | },
95 | "uco-observable:to": {
96 | "@id": "kb:e91445f8-406b-4ade-bd12-ec9ecdce5810"
97 | }
98 | }
99 | ]
100 | }
101 | ]
102 | }
--------------------------------------------------------------------------------
/json/WIRELESS_NETWORK_CASE_1.0.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": {
3 | "kb": "http://example.org/kb/",
4 | "drafting": "http://example.org/ontology/drafting/",
5 | "co": "http://purl.org/co/",
6 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
7 | "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
8 | "uco-identity": "https://ontology.unifiedcyberontology.org/uco/identity/",
9 | "uco-location": "https://ontology.unifiedcyberontology.org/uco/location/",
10 | "uco-role": "https://ontology.unifiedcyberontology.org/uco/role/",
11 | "uco-action": "https://ontology.unifiedcyberontology.org/uco/action/",
12 | "uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
13 | "uco-types": "https://ontology.unifiedcyberontology.org/uco/types/",
14 | "uco-tool": "https://ontology.unifiedcyberontology.org/uco/tool/",
15 | "case-investigation": "https://ontology.caseontology.org/case/investigation/",
16 | "xsd": "http://www.w3.org/2001/XMLSchema#"
17 | },
18 | "uco-core:object": [
19 | {
20 | "@id": "kb:e4912cd1-abc3-4ad4-9d73-f54379752e02",
21 | "@type": "uco-observable:ObservableObject",
22 | "uco-core:hasFacet": [
23 | {
24 | "@id": "kb:22f9f968-e829-4a22-89fc-751feff9d0b0",
25 | "@type": "uco-observable:DeviceFacet",
26 | "uco-observable:deviceType": "Mobile phone",
27 | "uco-observable:model": "iPhone X",
28 | "uco-observable:serialNumber": "HW095687Y2022"
29 | },
30 | {
31 | "@id": "kb:1d4e9269-ad19-4fe4-8055-377301bdefde",
32 | "@type": "uco-observable:MobileDeviceFacet",
33 | "uco-observable:IMSI": "310260249043715",
34 | "uco-observable:ICCID": "8901260243790437158",
35 | "uco-observable:IMEI": "359405082912450",
36 | "uco-observable:MSISDN": "3383725981"
37 | }
38 | ]
39 | },
40 | {
41 | "@id": "kb:37445ac8-7fd9-4ab4-ba82-231eba274480",
42 | "@type": "uco-observable:ObservableObject",
43 | "uco-core:hasFacet": [
44 | {
45 | "@id": "kb:b4cfbacd-050c-4b01-8a12-284aae1a6ccb",
46 | "@type": "uco-location:LatLongCoordinatesFacet",
47 | "uco-location:latitude": {
48 | "@type": "xsd:decimal",
49 | "@value": "40.05659866"
50 | },
51 | "uco-location:longitude": {
52 | "@type": "xsd:decimal",
53 | "@value": "-75.67047119"
54 | },
55 | "uco-location:altitude": {
56 | "@type": "xsd:decimal",
57 | "@value": "0.0"
58 | }
59 | }
60 | ]
61 | },
62 | {
63 | "@id": "kb:c64804f4-bd52-4194-8409-08018386374f",
64 | "@type": "uco-observable:ObservableObject",
65 | "uco-core:hasFacet": [
66 | {
67 | "@id": "kb:bc1d7cec-bea9-4ccf-8f72-457728aa42d2",
68 | "@type": "uco-observable:WirelessNetworkConnectionFacet",
69 | "uco-observable:ssid": "78:BC:1A:36:25:E0"
70 | }
71 | ]
72 | },
73 | {
74 | "@id": "kb:701b2190-5d5a-4786-bc0c-e6e0bf1dbd65",
75 | "@type": "uco-observable:ObservableRelationship",
76 | "uco-core:isDirectional": {
77 | "@type": "xsd:boolean",
78 | "@value": true
79 | },
80 | "uco-core:kindOfRelationship": "Mapped_Into",
81 | "uco-core:source": {
82 | "@id": "kb:c64804f4-bd52-4194-8409-08018386374f"
83 | },
84 | "uco-core:target": {
85 | "@id": "kb:37445ac8-7fd9-4ab4-ba82-231eba274480"
86 | }
87 | },
88 | {
89 | "@id": "kb:d00d2e24-684f-4d8e-9563-3b92a85c2dea",
90 | "@type": "uco-observable:ObservableRelationship",
91 | "uco-core:isDirectional": {
92 | "@type": "xsd:boolean",
93 | "@value": true
94 | },
95 | "uco-core:kindOfRelationship": "Connected_To",
96 | "uco-observable:startTime": {
97 | "@type": "xsd:dateTime",
98 | "@value": "2021-07-29T13:42:11+00:00"
99 | },
100 | "uco-observable:endTime": {
101 | "@type": "xsd:dateTime",
102 | "@value": "2021-07-29T17:55:19+00:00"
103 | },
104 | "uco-core:source": {
105 | "@id": "kb:e4912cd1-abc3-4ad4-9d73-f54379752e02"
106 | },
107 | "uco-core:target": {
108 | "@id": "kb:c64804f4-bd52-4194-8409-08018386374f"
109 | }
110 | }
111 | ]
112 | }
--------------------------------------------------------------------------------
/json/EMAIL_MESSAGE_CASE_1.0.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": {
3 | "kb": "http://example.org/kb/",
4 | "drafting": "http://example.org/ontology/drafting/",
5 | "co": "http://purl.org/co/",
6 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
7 | "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
8 | "uco-identity": "https://ontology.unifiedcyberontology.org/uco/identity/",
9 | "uco-location": "https://ontology.unifiedcyberontology.org/uco/location/",
10 | "uco-role": "https://ontology.unifiedcyberontology.org/uco/role/",
11 | "uco-action": "https://ontology.unifiedcyberontology.org/uco/action/",
12 | "uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
13 | "uco-types": "https://ontology.unifiedcyberontology.org/uco/types/",
14 | "uco-tool": "https://ontology.unifiedcyberontology.org/uco/tool/",
15 | "case-investigation": "https://ontology.caseontology.org/case/investigation/",
16 | "xsd": "http://www.w3.org/2001/XMLSchema#"
17 | },
18 | "uco-core:object": [
19 |
20 | {
21 | "@id": "kb:b35a22bb-4724-456d-9d5e-cb10bac9939d",
22 | "@type": "uco-observable:ObservableObject",
23 | "uco-core:hasFacet": [
24 | {
25 | "@id": "kb:9822afd7-c7c3-4d36-84b4-65e2f33e9f9a",
26 | "@type": "uco-observable:EmailAddressFacet",
27 | "uco-observable:addressValue": "tornadobeth@gmail.com"
28 | }
29 | ]
30 | },
31 | {
32 | "@id": "kb:0e9ee8e2-a3ae-4034-ad6e-9faf2d74be4f",
33 | "@type": "uco-observable:ObservableObject",
34 | "uco-core:hasFacet": [
35 | {
36 | "@id": "kb:171e2ad5-4487-4c49-b5b3-fce438264222",
37 | "@type": "uco-observable:EmailAddressFacet",
38 | "uco-observable:addressValue": "sofia.karppi@supo.fi"
39 | }
40 | ]
41 | },
42 | {
43 | "@id": "kb:4da63ae2-4dde-46ed-902b-707fba9c4ec6",
44 | "@type": "uco-observable:ObservableObject",
45 | "uco-core:hasFacet": [
46 | {
47 | "@id": "22099976-cf95-412f-aa81-73019ee6e5cb",
48 | "@type": "uco-observable:AccountFacet",
49 | "uco-observable:isActive": {
50 | "@type": "xsd:boolean",
51 | "@value": true
52 | },
53 | "uco-observable:accountIdentifier": "Sofia K."
54 | },
55 | {
56 | "@id": "kb:abefde69-763c-421f-ab98-68ec712c3240",
57 | "@type": "uco-observable:EmailAccountFacet",
58 | "uco-observable:emailAddress": {
59 | "@id": "kb:0e9ee8e2-a3ae-4034-ad6e-9faf2d74be4f"
60 | }
61 | }
62 | ]
63 | },
64 | {
65 | "@id": "kb:29ec4e5c-79b4-470b-89b0-05f4e4d7438f",
66 | "@type": "uco-observable:ObservableObject",
67 | "uco-core:hasFacet": [
68 | {
69 | "@id": "kb:7727e140-c0cf-4d58-8b1f-fe6872b928fd",
70 | "@type": "uco-observable:AccountFacet",
71 | "uco-observable:isActive": {
72 | "@type": "xsd:boolean",
73 | "@value": true
74 | },
75 | "uco-observable:accountIdentifier": "Beth T."
76 | },
77 | {
78 | "@id": "kb:b93c1c72-f83f-45a3-b08e-3e56f370c26c",
79 | "@type": "uco-observable:EmailAccountFacet",
80 | "uco-observable:emailAddress": {
81 | "@id": "kb:b35a22bb-4724-456d-9d5e-cb10bac9939d"
82 | }
83 | }
84 | ]
85 | },
86 | {
87 | "@id": "kb:86c4539e-6bd2-4f73-aa44-00debcd57326",
88 | "@type": "uco-observable:ObservableObject",
89 | "uco-core:hasFacet": [
90 | {
91 | "@id": "kb:a4f1bc5a-9250-442f-b2c0-508cf226809c",
92 | "@type": "uco-observable:EmailMessageFacet",
93 | "uco-observable:subject": "Helena Willamo clues.",
94 | "uco-observable:body": "Dear Friends, Nice to hearing from you! Thank you for the invitation. I’ll answer to you asap.",
95 | "uco-observable:allocationStatus": "Intact",
96 | "uco-observable:sentTime": {
97 | "@type": "xsd:dateTime",
98 | "@value": "2021-02-25T14:55:51+00:00"
99 | },
100 | "uco-observable:from": {
101 | "@id": "kb:4da63ae2-4dde-46ed-902b-707fba9c4ec6"
102 | },
103 | "uco-observable:to": [
104 | {
105 | "@id": "kb:29ec4e5c-79b4-470b-89b0-05f4e4d7438f"
106 | }
107 | ],
108 | "uco-observable:cc": [],
109 | "uco-observable:bcc": []
110 | }
111 | ]
112 | }
113 | ]
114 | }
--------------------------------------------------------------------------------
/json/URL_HISTORY_MULTI_ITEMS_CASE_1.0.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": {
3 | "kb": "http://example.org/kb/",
4 | "drafting": "http://example.org/ontology/drafting/",
5 | "co": "http://purl.org/co/",
6 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
7 | "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
8 | "uco-identity": "https://ontology.unifiedcyberontology.org/uco/identity/",
9 | "uco-location": "https://ontology.unifiedcyberontology.org/uco/location/",
10 | "uco-role": "https://ontology.unifiedcyberontology.org/uco/role/",
11 | "uco-action": "https://ontology.unifiedcyberontology.org/uco/action/",
12 | "uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
13 | "uco-types": "https://ontology.unifiedcyberontology.org/uco/types/",
14 | "uco-tool": "https://ontology.unifiedcyberontology.org/uco/tool/",
15 | "case-investigation": "https://ontology.caseontology.org/case/investigation/",
16 | "xsd": "http://www.w3.org/2001/XMLSchema#"
17 | },
18 | "uco-core:object": [
19 | {
20 | "@id": "kb:5d96df90-d9e1-423c-b8db-c2327812ab38",
21 | "@type": "uco-observable:ObservableObject",
22 | "uco-core:hasFacet": [
23 | {
24 | "@id": "kb:1723ed9c-2d8e-415c-8cf6-31599c49df79",
25 | "@type": "uco-observable:ApplicationFacet",
26 | "uco-observable:applicationIdentifier": "Safari Apple",
27 | "uco-observable:version": "15.23.45"
28 | }
29 | ]
30 | },
31 | {
32 | "@id": "kb:39ff4987-8ae5-47e3-8369-dbd0d5f79398",
33 | "@type": "uco-observable:ObservableObject",
34 | "rdfs:comment": "@type=uco-observable:URLHistory",
35 | "uco-core:hasFacet": [
36 | {
37 | "@id": "kb:a455b867-957e-4fce-a0ad-1af9c6fa4edb",
38 | "@type": "uco-observable:URLHistoryFacet",
39 | "uco-observable:browserInformation": {
40 | "@id": "kb:5d96df90-d9e1-423c-b8db-c2327812ab38"
41 | },
42 | "uco-observable:urlHistoryEntry": [
43 | {
44 | "@id": "kb:193a7fc6-5f15-4b3c-8763-f1dc3c9bfd14",
45 | "@type": "uco-observable:URLHistoryEntry",
46 | "uco-observable:firstVisit": {
47 | "@type": "xsd:dateTime",
48 | "@value": "2017-01-25T02:20:22.00Z"
49 | },
50 | "uco-observable:lastVisit": {
51 | "@type": "xsd:dateTime",
52 | "@value": "2017-01-25T02:20:22.00Z"
53 | },
54 | "uco-observable:expirationTime": null,
55 | "uco-observable:url": {
56 | "@id": "kb:b7906534-0483-4cf4-979c-5351916602ed"
57 | },
58 | "uco-observable:pageTitle": "Where can you find baby owls for sale? Are owls legal to keep as pets? - Quora",
59 | "uco-observable:visitCount": 2,
60 | "uco-observable:manuallyEnteredCount": {
61 | "@type": "xsd:nonNegativeInteger",
62 | "@value": 0
63 | },
64 | "uco-observable:keywordSearchTerm": "Baby owl shops"
65 | },
66 | {
67 | "@id": "kb:f3d8a186-3863-42f9-b4f9-05cfdec34c75",
68 | "@type": "uco-observable:URLHistoryEntry",
69 | "uco-observable:firstVisit": {
70 | "@type": "xsd:dateTime",
71 | "@value": "2022-02-22T02:20:22.00Z"
72 | },
73 | "uco-observable:lastVisit": {
74 | "@type": "xsd:dateTime",
75 | "@value": "2022-05-18T02:20:22.00Z"
76 | },
77 | "uco-observable:expirationTime": null,
78 | "uco-observable:url": {
79 | "@id": "kb:b88d66e8-3fae-4e15-879b-1e068240d2a0"
80 | },
81 | "uco-observable:pageTitle": "Otter AI plans",
82 | "uco-observable:visitCount": 12,
83 | "uco-observable:manuallyEnteredCount": {
84 | "@type": "xsd:nonNegativeInteger",
85 | "@value": 0
86 | },
87 | "uco-observable:keywordSearchTerm": "From mp3 to text"
88 | }
89 | ]
90 | }
91 | ]
92 | },
93 | {
94 | "@id": "kb:b7906534-0483-4cf4-979c-5351916602ed",
95 | "@type": "uco-observable:URL",
96 | "uco-core:hasFacet": [
97 | {
98 | "@id": "kb:f2618636-aec3-459e-bda7-eeedfbeac3c0",
99 | "@type": "uco-observable:URLFacet",
100 | "uco-observable:fullValue": "https://www.quora.com/Where-can-you-find-baby-owls-for-sale-Are-owls-legal-to-keep-as-pets"
101 | }
102 | ]
103 | },
104 | {
105 | "@id": "kb:b88d66e8-3fae-4e15-879b-1e068240d2a0",
106 | "@type": "uco-observable:URL",
107 | "uco-core:hasFacet": [
108 | {
109 | "@id": "kb:12c098ec-0466-47b3-a3ba-5addc7778083",
110 | "@type": "uco-observable:URLFacet",
111 | "uco-observable:fullValue": "https://otter.ai/setting/plan"
112 | }
113 | ]
114 | }
115 | ]
116 | }
117 |
--------------------------------------------------------------------------------
/json/Message_CASE_1.0.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": {
3 | "kb": "http://example.org/kb/",
4 | "drafting": "http://example.org/ontology/drafting/",
5 | "co": "http://purl.org/co/",
6 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
7 | "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
8 | "uco-identity": "https://ontology.unifiedcyberontology.org/uco/identity/",
9 | "uco-location": "https://ontology.unifiedcyberontology.org/uco/location/",
10 | "uco-role": "https://ontology.unifiedcyberontology.org/uco/role/",
11 | "uco-action": "https://ontology.unifiedcyberontology.org/uco/action/",
12 | "uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
13 | "uco-types": "https://ontology.unifiedcyberontology.org/uco/types/",
14 | "uco-tool": "https://ontology.unifiedcyberontology.org/uco/tool/",
15 | "case-investigation": "https://ontology.caseontology.org/case/investigation/",
16 | "xsd": "http://www.w3.org/2001/XMLSchema#"
17 | },
18 | "uco-core:object": [
19 | {
20 | "@id": "kb:5340d5ad-0fe1-463c-a461-f211e64edfd4",
21 | "@type": "uco-observable:ObservableObject",
22 | "uco-core:hasFacet": [
23 | {
24 | "@id": "kb:1723ed9c-2d8e-415c-8cf6-31599c49df79",
25 | "@type": "uco-observable:ApplicationFacet",
26 | "uco-observable:applicationIdentifier": "com.whatsapp",
27 | "uco-observable:version": "1.23.45"
28 | }
29 | ]
30 | },
31 | {
32 | "@id": "kb:a5931c7e-fc1e-4def-a618-fc31d9ae4cc7",
33 | "@type": "uco-observable:ApplicationAccount",
34 | "uco-core:hasFacet": [
35 | {
36 | "@id": "kb:0279d259-3195-418b-b5bc-ac3d7b8dbf66",
37 | "@type": "uco-observable:AccountFacet",
38 | "uco-observable:accountIdentifier": "393369402190@s.whatsapp.net"
39 | },
40 | {
41 | "@id": "kb:6a4fc272-4ca3-4da3-93d0-0711ca3e85d6",
42 | "@type": "uco-observable:ApplicationAccountFacet",
43 | "uco-observable:application": {
44 | "@id": "kb:5340d5ad-0fe1-463c-a461-f211e64edfd4"
45 | }
46 | },
47 | {
48 | "@id": "kb:0d2ac063-7bed-4525-be4c-7dc38a4288f1",
49 | "@type": "uco-observable:DigitalAccountFacet",
50 | "uco-observable:displayName": "Jane Balding"
51 | }
52 | ]
53 | },
54 | {
55 | "@id": "kb:f135dee3-ba06-4ded-ad63-5484ce240ec8",
56 | "@type": "uco-observable:ApplicationAccount",
57 | "uco-core:hasFacet": [
58 | {
59 | "@id": "kb:36d0abb1-bdd8-460c-8422-63f715e2e1c2",
60 | "@type": "uco-observable:AccountFacet",
61 | "uco-observable:isActive": {
62 | "@type": "xsd:boolean",
63 | "@value": "true"
64 | },
65 | "uco-observable:accountIdentifier": "363483643499@s.whatsapp.net"
66 | },
67 | {
68 | "@id": "kb:9e8995f1-fa79-432f-915d-1eed79b83413",
69 | "@type": "uco-observable:ApplicationAccountFacet",
70 | "uco-observable:application": {
71 | "@id": "kb:5340d5ad-0fe1-463c-a461-f211e64edfd4"
72 | }
73 | },
74 | {
75 | "@id": "kb:cc9400b6-044d-4fef-a7d1-adecdf0b7aa2",
76 | "@type": "uco-observable:DigitalAccountFacet",
77 | "uco-observable:displayName": "Vivienne Joosha"
78 | }
79 | ]
80 | },
81 |
82 | {
83 | "@id": "kb:4237ff8b-e049-4a56-bcf7-e89ed2797d83",
84 | "rdfs:comment": "@type: uco-observable:MessageThread",
85 | "@type": "uco-observable:ObservableObject",
86 | "uco-core:hasFacet": [
87 | {
88 | "@id": "kb:0cd2f9f8-9040-4af7-82f8-8287fb3f861d",
89 | "@type": "uco-observable:MessageThreadFacet",
90 | "identifier": "jane~vivienne@whatsapp.gs.net",
91 | "uco-observable:displayName": "Best Friend Chat!!",
92 | "uco-observable:messageThread": {
93 | "@id": "kb:1a921f84-eadd-4591-be0d-57b936933622",
94 | "@type": "uco-types:Thread",
95 | "co:size": {
96 | "@type": "xsd:nonNegativeInteger",
97 | "@value": 2
98 | },
99 | "co:element": [
100 | {
101 | "@id": "kb:d8330d5a-b8de-4425-9cd8-a37b038afe81"
102 | },
103 | {
104 | "@id": "kb:3328fbc7-1f63-4e66-b8fc-e27143a64331"
105 | }
106 | ]
107 | },
108 | "uco-observable:participant": [
109 | {
110 | "@id": "kb:a5931c7e-fc1e-4def-a618-fc31d9ae4cc7"
111 | },
112 | {
113 | "@id": "kb:f135dee3-ba06-4ded-ad63-5484ce240ec8"
114 | }
115 | ]
116 | }
117 | ]
118 | },
119 | {
120 | "@id": "kb:3328fbc7-1f63-4e66-b8fc-e27143a64331",
121 | "@type": "uco-observable:Message",
122 | "uco-core:hasFacet": [
123 | {
124 | "@id": "kb:3104e958-381e-4aa5-ba0a-6fc47b33ebc7",
125 | "@type": "uco-observable:MessageFacet",
126 | "uco-observable:application": {
127 | "@id": "kb:5340d5ad-0fe1-463c-a461-f211e64edfd4"
128 | },
129 | "uco-observable:messageText": "I said some things in a tweet! @sarahsmithtweeter #hashtag",
130 | "uco-observable:from": {
131 | "@id": "kb:f135dee3-ba06-4ded-ad63-5484ce240ec8"
132 | },
133 | "uco-observable:to": [
134 | {
135 | "@id": "kb:a5931c7e-fc1e-4def-a618-fc31d9ae4cc7"
136 | }
137 | ],
138 | "uco-observable:sentTime": {
139 | "@type": "xsd:dateTime",
140 | "@value": "2010-01-16T16:34:56.25Z"
141 | }
142 | }
143 | ]
144 | },
145 | {
146 | "@id": "kb:d8330d5a-b8de-4425-9cd8-a37b038afe81",
147 | "@type": "uco-observable:Message",
148 | "uco-core:hasFacet": [
149 | {
150 | "@id": "kb:51b43eaf-49fb-4812-baf2-210f4893e6d0",
151 | "@type": "uco-observable:MessageFacet",
152 | "uco-observable:application": {
153 | "@id": "kb:5340d5ad-0fe1-463c-a461-f211e64edfd4"
154 | },
155 | "uco-observable:messageText": "Hey bud!",
156 | "uco-observable:from": {
157 | "@id": "kb:a5931c7e-fc1e-4def-a618-fc31d9ae4cc7"
158 | },
159 | "uco-observable:to": [
160 | {
161 | "@id": "kb:f135dee3-ba06-4ded-ad63-5484ce240ec8"
162 | }
163 | ],
164 | "uco-observable:sentTime": {
165 | "@type": "xsd:dateTime",
166 | "@value": "2010-01-15T17:59:43.25Z"
167 | }
168 | }
169 | ]
170 | }
171 | ]
172 | }
173 |
--------------------------------------------------------------------------------
/json/ACTION_CASE_1.0.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": {
3 | "kb": "http://example.org/kb/",
4 | "drafting": "http://example.org/ontology/drafting/",
5 | "co": "http://purl.org/co/",
6 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
7 | "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
8 | "uco-identity": "https://ontology.unifiedcyberontology.org/uco/identity/",
9 | "uco-location": "https://ontology.unifiedcyberontology.org/uco/location/",
10 | "uco-role": "https://ontology.unifiedcyberontology.org/uco/role/",
11 | "uco-action": "https://ontology.unifiedcyberontology.org/uco/action/",
12 | "uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
13 | "uco-vocabulary":"https://ontology.unifiedcyberontology.org/uco/vocabulary/",
14 | "uco-types": "https://ontology.unifiedcyberontology.org/uco/types/",
15 | "uco-tool": "https://ontology.unifiedcyberontology.org/uco/tool/",
16 | "case-investigation": "https://ontology.caseontology.org/case/investigation/",
17 | "xsd": "http://www.w3.org/2001/XMLSchema#"
18 | },
19 | "uco-core:object": [
20 | {
21 | "@id": "kb:e4912cd1-abc3-4ad4-9d73-f54379752e02",
22 | "@type": "uco-observable:ObservableObject",
23 | "uco-core:hasFacet": [
24 | {
25 | "@id": "kb:22f9f968-e829-4a22-89fc-751feff9d0b0",
26 | "@type": "uco-observable:DeviceFacet",
27 | "uco-observable:deviceType": "Mobile phone",
28 | "uco-observable:model": "iPhone X",
29 | "uco-observable:serialNumber": "HW095687Y2022"
30 | },
31 | {
32 | "@id": "kb:1d4e9269-ad19-4fe4-8055-377301bdefde",
33 | "@type": "uco-observable:MobileDeviceFacet",
34 | "uco-observable:IMSI": "310260249043715",
35 | "uco-observable:ICCID": "8901260243790437158",
36 | "uco-observable:IMEI": "359405082912450"
37 | },
38 | {
39 | "@id": "kb:6bd89154-b501-4fd8-a750-58d39e4a51e7",
40 | "@type": "uco-observable:OperatingSystemFacet",
41 | "uco-observable:displayName": "iOS",
42 | "uco-observable:manufacturer":
43 | {
44 | "@id": "kb:73952c43-8df5-4fa3-888c-f0f00d2eab8f"
45 | },
46 | "uco-observable:version": "14.6"
47 | },
48 | {
49 | "@id": "kb:75be1e84-348e-4d19-85d3-a1e23eed77cc",
50 | "@type": "uco-observable:BluetoothAddressFacet",
51 | "uco-observable:displayName": "Good hook",
52 | "uco-observable:addressValue": "D4:A3:3D:B5:F4:6C"
53 | },
54 | {
55 | "@id": "kb:a265c5ed-95c2-46e9-af91-4b73023f918b",
56 | "@type": "uco-observable:WifiAddressFacet",
57 | "uco-observable:addressValue": "D4:A3:3D:B5:F4:48"
58 | }
59 | ]
60 | },
61 | {
62 | "@id": "kb:73952c43-8df5-4fa3-888c-f0f00d2eab8f",
63 | "@type": "uco-identity:Identity",
64 | "uco-core:description": "Huawei UK"
65 | },
66 | {
67 | "@id": "kb:7ae6b781-4704-428f-85df-3367515dc608",
68 | "@type": "uco-identity:Identity",
69 | "uco-core:description": "Cellebrite, Petah Tikva, Israel"
70 | },
71 | {
72 | "@id": "kb:8e4f771d-4fa0-4f70-b593-20d8f00e0461",
73 | "@type": "uco-observable:ObservableObject",
74 | "uco-core:hasFacet": [
75 | {
76 | "@id": "kb:22e1dd8f-6209-479d-b5e7-b8cc4ecc5f6f",
77 | "@type": "uco-identity:SimpleNameFacet",
78 | "uco-identity:givenName": "Forensic Lab FG Consulting"
79 | }
80 | ]
81 | },
82 | {
83 | "@id": "kb:4252f4ee-d2bd-4d83-bbb4-2669a7be8286",
84 | "@type": "uco-tool:Tool",
85 | "uco-core:name": "UFED PA",
86 | "uco-tool:version": "7.57.1.9",
87 | "uco-tool:toolType": "Acquisition",
88 | "uco-tool:creator": {
89 | "@id": "kb:7ae6b781-4704-428f-85df-3367515dc608"
90 | }
91 | },
92 | {
93 | "@id": "kb:5e350cd9-3e48-4f8a-82f1-26e394e0780f",
94 | "@type": "uco-observable:ObservableObject",
95 | "uco-core:hasFacet": [
96 | {
97 | "@id": "kb:0be208ff-034c-4529-b004-39b8426393b4",
98 | "@type": "uco-observable:FileFacet",
99 | "uco-observable:fileName": "Apple_iPhone X (A1901).zip",
100 | "uco-observable:filePath": "Apple_iPhone X (A1901).zip",
101 | "drafting:fileLocalPath": "files/Ucategorized/Apple_iPhone X (A1901).zip",
102 | "uco-observable:extension": ".zip",
103 | "uco-observable:accessedTime": {
104 | "@type": "xsd:dateTime",
105 | "@value": "1900-01-01T08:00:00+00:00"
106 | },
107 | "uco-observable:observableCreatedTime": {
108 | "@type": "xsd:dateTime",
109 | "@value": "1900-01-01T08:00:00+00:00"
110 | },
111 | "uco-observable:modifiedTime": {
112 | "@type": "xsd:dateTime",
113 | "@value": "1900-01-01T08:00:00+00:00"
114 | },
115 | "uco-core:tag": [
116 | "Uncategorized"
117 | ],
118 | "uco-observable:sizeInBytes": {
119 | "@type": "xsd:integer",
120 | "@value": 16965760332
121 | }
122 | },
123 | {
124 | "@id": "kb:097bc2b2-45e4-453a-a208-aeab7e77da99",
125 | "@type": "uco-observable:ContentDataFacet",
126 | "uco-observable:hash": [
127 | {
128 | "@id": "kb:fbd39b90-551d-5a80-8f3d-70e91c5fe472",
129 | "@type": "uco-types:Hash",
130 | "uco-types:hashMethod": {
131 | "@type": "uco-vocabulary:HashNameVocab",
132 | "@value": "SHA256"
133 | },
134 | "uco-types:hashValue": {
135 | "@type": "xsd:hexBinary",
136 | "@value": "6b51d431df5d7f141cbececcf79edf3dd861c3b4069f0b11661a3eefacbba918"
137 | }
138 | }
139 | ]
140 | }
141 | ]
142 | },
143 | {
144 | "@id": "kb:9ebe7b98-5323-4bf5-b44a-d499c928b93d",
145 | "@type": "case-investigation:ProvenanceRecord",
146 | "case-investigation:exhibitNumber": "E01",
147 | "uco-core:object": [
148 | {
149 | "@id": "kb:5e350cd9-3e48-4f8a-82f1-26e394e0780f"
150 | }
151 | ]
152 |
153 | },
154 | {
155 | "@id": "kb:0d549b0e-4484-4858-9e48-fb21e3f317f7",
156 | "@type": "case-investigation:InvestigativeAction",
157 | "rdfs:comment": "also the @type= uco-action:Action is admsissible",
158 | "uco-core:name": "Forensic mobile device acquisition",
159 | "uco-action:startTime": {
160 | "@type": "xsd:dateTime",
161 | "@value": "2021-07-29T12:28:49+00:00"
162 | },
163 | "uco-action:endTime": {
164 | "@type": "xsd:dateTime",
165 | "@value": "2021-07-29T12:43:44+00:00"
166 | },
167 | "uco-action:performer": {
168 | "@id": "kb:8e4f771d-4fa0-4f70-b593-20d8f00e0461"
169 | },
170 | "uco-action:instrument": {
171 | "@id": "kb:4252f4ee-d2bd-4d83-bbb4-2669a7be8286"
172 | },
173 | "uco-action:result": [
174 | {
175 | "@id": "kb:9ebe7b98-5323-4bf5-b44a-d499c928b93d"
176 | }
177 | ],
178 | "uco-action:object": {
179 | "@id": "kb:e4912cd1-abc3-4ad4-9d73-f54379752e02"
180 | }
181 | }
182 | ]
183 | }
--------------------------------------------------------------------------------
/parserDebug.py:
--------------------------------------------------------------------------------
1 | import codecs
2 |
3 | #--- class ParserDebug.py
4 | class ParserDebug:
5 | def __init__(self, debugFile):
6 | self.dFileName = debugFile
7 | self.dFileHandle = codecs.open(self.dFileName, 'w', encoding='utf8')
8 |
9 | def writeDebugCALL(self, data):
10 | line = "\n*---\nTotal CALL (deleted) " + str(data.CALLtotal)
11 | line += ' (' + str(data.CALLdeleted) + ')'
12 | line += '\n*---'
13 | self.dFileHandle.write(line)
14 | for i in range(data.CALLtotal):
15 | line = '\n[id] ' + data.CALLid[i]
16 | line += '\n\t[status] ' + data.CALLstatus[i]
17 | line += '\n\t[source] ' + data.CALLsource[i]
18 | line += '\n\t[direction] ' + data.CALLdirection[i]
19 | line += '\n\t[outcome] ' + data.CALLoutcome[i]
20 | line += '\n\t[time] ' + data.CALLtimeStamp[i]
21 | line += '\n\t[duration]' + data.CALLduration[i]
22 | if (len(data.CALLrolesTO[i]) > 0):
23 | line += '\n\t[roleTO] ' + data.CALLrolesTO[i][0]
24 | else:
25 | line += '\n\t[roleTO] ' + '_NOT_PROVIDED_'
26 |
27 | if (len(data.CALLrolesFROM[i]) > 0):
28 | line += '\n\t[roleFROM] ' + data.CALLrolesFROM[i][0]
29 | else:
30 | line += '\n\t[roleFROM] ' + '_NOT_PROVIDED_'
31 |
32 | if (len(data.CALLnamesTO[i]) > 0):
33 | line += '\n\t[nameTO] ' + data.CALLnamesTO[i][0]
34 | else:
35 | line += '\n\t[nameTO] ' + '_NOT_PROVIDED_'
36 |
37 | if (len(data.CALLnamesFROM[i]) > 0):
38 | line += '\n\t[nameFROM] ' + data.CALLnamesFROM[i][0]
39 | else:
40 | line += '\n\t[nameFROM] ' + '_NOT_PROVIDED_'
41 |
42 | if (len(data.CALLidentifiersTO[i]) > 0):
43 | line += '\n\t[identifierTO] ' + data.CALLidentifiersTO[i][0]
44 | else:
45 | line += '\n\t[identifierTO] ' + '_NOT_PROVIDED_'
46 |
47 | if (len(data.CALLidentifiersFROM[i]) > 0):
48 | line += '\n\t[identifierFROM] ' + data.CALLidentifiersFROM[i][0]
49 | else:
50 | line += '\n\t[identifierFROM] ' + '_NOT_PROVIDED_'
51 |
52 | self.dFileHandle.write(line)
53 |
54 | def writeDebugCHAT(self, data):
55 | line = "\n*---\nTotal CHAT (deleted) " + str(data.CHATtotal)
56 | line += ' (' + str(data.CHATdeleted) + ')'
57 | line += '\n*---'
58 | self.dFileHandle.write(line)
59 | for i in range(data.CHATtotal):
60 | line = '\n* [CHATid] ' + data.CHATid[i]
61 | line += '\n\t[source] ' + data.CHATsource[i]
62 | for j in range(len(data.CHATpartyIdentifiers[i])):
63 | line += '\n\t[particpantIdentifier] ' + data.CHATpartyIdentifiers[i][j]
64 | line += '\n\t[particpantName] ' + data.CHATpartyNames[i][j]
65 | for j in range(len(data.CHATmsgBodies[i])):
66 | line += '\n\t[msg n.] ' + str(j + 1)
67 | line += '\n\t\t[IdentifierFROM] ' + data.CHATmsgIdentifiersFrom[i][j]
68 | line += '\n\t\t[NameFROM] ' + data.CHATmsgNamesFrom[i][j]
69 | line += '\n\t\t[msgIdentifierTO] ' + data.CHATmsgIdentifiersTo[i][j]
70 | line += '\n\t\t[msgNameTO] ' + data.CHATmsgNamesTo[i][j]
71 | line += '\n\t\t[msgBody] ' + data.CHATmsgBodies[i][j]
72 | line += '\n\t\t[Status] ' + data.CHATmsgStatuses[i][j]
73 | line += '\n\t\t[msgTimeStamp] ' + data.CHATmsgTimeStamps[i][j]
74 | line += '\n\t\t[Attachment (File/Url)] ' + data.CHATmsgAttachmentFilenames[i][j]
75 | line += ' / ' + data.CHATmsgAttachmentUrls[i][j]
76 | self.dFileHandle.write(line)
77 |
78 | def writeDebugCONTACT(self, data):
79 | line = "\n*---\nTotal CONTACT (deleted) " + str(data.CONTACTtotal)
80 | line += ' (' + str(data.CONTACTdeleted) + ')'
81 | line += '\n*---'
82 | self.dFileHandle.write(line + '\n')
83 | for i in range(data.CONTACTtotal):
84 | line = '[CONTACTid] ' + data.CONTACTid[i] + '\n'
85 | line += ' [Name] ' + data.CONTACTname[i]
86 | for j in range(len(data.CONTACTphoneNums[i])):
87 | line += ' [PhoneNums] ' + data.CONTACTphoneNums[i][j] + ' '
88 | line += '\n'
89 | self.dFileHandle.write(line)
90 |
91 | def writeDebugCONTEXT(self, data):
92 | line = "\n*---\nCONTEXT"
93 | line += '\n*---'
94 | line += '\n\t[Ufed version] ' + data.CONTEXTufedVersionText
95 | line += '\n\t[Device Extraction start date/time] '
96 | line += data.CONTEXTdeviceCreationTimeText + '\n'
97 | line += '\n\t[Device Acquisition Start/End date/time] '
98 | line += data.CONTEXTdeviceExtractionStartText + ' / '
99 | line += data.CONTEXTdeviceExtractionEndText + '\n'
100 | line += '\n\t[Examiner name] '
101 | line += data.CONTEXTexaminerNameText + '\n'
102 | line += '\n\t[Bluetooth MAC] ' + data.CONTEXTdeviceBluetoothAddressText
103 | line += '\n\t[DeviceID] ' + data.CONTEXTdeviceIdText
104 | line += '\n\t[PhoneModel] ' + data.CONTEXTdevicePhoneModelText
105 | line += '\n\t[OS type] ' + data.CONTEXTdeviceOsTypeText
106 | line += '\n\t[OS version] ' + data.CONTEXTdeviceOsVersionText
107 | line += '\n\t[PhoneVendor] ' + data.CONTEXTdevicePhoneVendorText
108 | line += '\n\t[MAC] ' + data.CONTEXTdeviceMacAddressText
109 | line += '\n\t[ICCID] ' + data.CONTEXTdeviceIccidText
110 | line += '\n\t[IMSI] ' + data.CONTEXTdeviceImsiText
111 | line += '\n\t[IMEI] ' + data.CONTEXTdeviceImeiText
112 | line += '\n\t[Files]'
113 | for i in range (len(data.CONTEXTimagePath)):
114 | line += '\n\t\t[path]' + data.CONTEXTimagePath[i]
115 | line += '\n\t\t[size]' + data.CONTEXTimageSize[i]
116 | line += '\n\t\t[hash SHA256 / MD5]' + data.CONTEXTimageMetadataHashSHA[i] + ' / '
117 | line += data.CONTEXTimageMetadataHashMD5[i]
118 | self.dFileHandle.write(line)
119 |
120 | def writeDebugEMAIL(self, data):
121 | line = "\n*---\nTotal EMAIL (deleted) " + str(data.EMAILtotal)
122 | line += ' (' + str(data.EMAILdeleted) + ')'
123 | line += '\n*---'
124 | self.dFileHandle.write(line)
125 | for i in range(data.EMAILtotal):
126 | line = '\n[EMAILid] ' + data.EMAILid[i]
127 | line += '\n\t[status] ' + data.EMAILstatus[i]
128 | line += '\n\t[Source] ' + data.EMAILsource[i]
129 | line += '\n\t[FROM] ' + data.EMAILidentifierFROM[i]
130 | line += '\n\t[TO] '
131 | for j in range(len(data.EMAILidentifiersTO[i])):
132 | line += '\n\t\t' + data.EMAILidentifiersTO[i][j]
133 | line += '\n\t[CC] '
134 | for j in range(len(data.EMAILidentifiersCC[i])):
135 | line += '\n\t\t' + data.EMAILidentifiersCC[i][j]
136 | line += '\n\t[BCC] '
137 | for j in range(len(data.EMAILidentifiersBCC[i])):
138 | line += '\n\t\t' + data.EMAILidentifiersBCC[i][j]
139 |
140 | line += '\n\t[Body] ' + data.EMAILbody[i]
141 | line += '\n\t[Subject] ' + data.EMAILsubject[i]
142 | line += '\n\t[TimeStamp] ' + data.EMAILtimeStamp[i]
143 | line += '\n\t[Attachments]'
144 | for j in range(len(data.EMAILattachmentsFilename[i])):
145 | line += '\n\t\t' + data.EMAILattachmentsFilename[i][j]
146 | self.dFileHandle.write(line)
147 |
148 | def writeDebugEXTRA_INFO(self, data):
149 | line = '\n*---\nTotal EXTRA_INFO ' + str(len(data.EXTRA_INFOid))
150 | line += '\n*---'
151 | self.dFileHandle.write(line)
152 | for key in data.EXTRA_INFOdictPath:
153 | line = '\n[extraInofId] ' + key
154 | line += '\n\t[path] ' + data.EXTRA_INFOdictPath[key]
155 | line += '\n\t[size] ' + data.EXTRA_INFOdictSize[key]
156 | line += '\n\t[tableName] ' + data.EXTRA_INFOdictTableName[key]
157 | line += '\n\t[offset] ' + data.EXTRA_INFOdictOffset[key]
158 | line += '\n\t[nodeInfoId] ' + data.EXTRA_INFOdictNodeInfoId[key]
159 | self.dFileHandle.write(line)
160 |
161 | def writeDebugFILES(self, data):
162 | line = "\n*---\nTotal FILE " + str(len(data.FILEid))
163 | line += '\n*---'
164 | self.dFileHandle.write(line)
165 | for i in range(len(data.FILEid)):
166 | line = '\n[id]=' + data.FILEid[i]
167 | line += '\n\t[path] ' + data.FILEpath[i]
168 | line += '\n\t[size] ' + data.FILEsize[i]
169 | line += '\n\t[MD5] ' + data.FILEmd5[i]
170 | line += '\n\t[Tags] ' + data.FILEtags[i]
171 | line += '\n\t[Ctime] ' + data.FILEtimeCreate[i]
172 | line += '\n\t[Mtime] ' + data.FILEtimeModify[i]
173 | line += '\n\t[Atime] ' + data.FILEtimeAccess[i]
174 | line += '\n\t[localPath] ' + data.FILElocalPath[i]
175 | line += '\n\t[iNodeNumber] ' + data.FILEiNodeNumber[i]
176 | line += '\n\t[OwnerGID] ' + data.FILEownerGID[i]
177 | line += '\n\t[OwnerUID] ' + data.FILEownerUID[i]
178 | self.dFileHandle.write(line)
179 |
180 | def writeDebugSMS(self, data):
181 | line = "\n*---\nTotal SMS (deleted) " + str(data.SMStotal)
182 | line += ' (' + str(data.SMSdeleted) + ')'
183 | line += '\n*---'
184 | self.dFileHandle.write(line)
185 | for i in range(len(data.SMSbody)):
186 | line = '\n[SMSid] ' + data.SMSid[i]
187 | line += '\n\t[status] ' + data.SMSstatus[i]
188 | line += '\n\t[source] ' + data.SMSsource[i]
189 | line += '\n\t[parties]'
190 | for j in range(len(data.SMSpartyRoles[i])):
191 | line += '\n\t\t[role] ' + data.SMSpartyRoles[i][j]
192 | line += '\n\t\t[identifier] ' + data.SMSpartyIdentifiers[i][j]
193 | line += '\n\t\t[name] ' + data.SMSpartyNames[i][j]
194 |
195 | line += '\n\t[time] ' + data.SMStimeStamp[i]
196 | line += '\n\t[body] ' + data.SMSbody[i]
197 | self.dFileHandle.write(line)
198 |
199 | def writeDebugU_ACCOUNT(self, data):
200 | line = "\n*---\nTotal U_ACCOUNT " + str(data.U_ACCOUNTtotal)
201 | line += '\n*---'
202 | self.dFileHandle.write(line)
203 | for i in range(len(data.U_ACCOUNTsource)):
204 | line = '\n\t[Source] ' + data.U_ACCOUNTsource[i]
205 | line += '\n\t[Name] ' + data.U_ACCOUNTname[i]
206 | line += '\n\t[User Name] ' + data.U_ACCOUNTusername[i]
207 | self.dFileHandle.write(line)
208 |
209 |
210 | def writeDebugWEB_PAGE(self, data):
211 | line = "\n*---\nTotal WEB_PAGE (deleted) " + str(data.WEB_PAGEtotal)
212 | line += ' (' + str(data.WEB_PAGEdeleted) + ')'
213 | line += '\n*---'
214 | self.dFileHandle.write(line)
215 | for i in range(data.WEB_PAGEtotal):
216 | line = '\n[id] ' + data.WEB_PAGEid[i]
217 | line += '\n\t[source] ' + data.WEB_PAGEsource[i]
218 | line += '\n\t[url] ' + data.WEB_PAGEurl[i]
219 | line += '\n\t[title] ' + data.WEB_PAGEtitle[i]
220 | line += '\n\t[visitCount] ' + data.WEB_PAGEvisitCount[i]
221 | line += '\n\t[lastVisited] ' + data.WEB_PAGElastVisited[i]
222 | self.dFileHandle.write(line)
223 |
224 | def closeDebug(self):
225 | self.dFileHandle.close()
226 |
227 |
--------------------------------------------------------------------------------
/UFEDdebug.py:
--------------------------------------------------------------------------------
1 | import codecs
2 |
3 | #--- class ParserDebug.py
4 | class ParserDebug:
5 | def __init__(self, debugFile):
6 | self.dFileName = debugFile
7 | self.dFileHandle = codecs.open(self.dFileName, 'w', encoding='utf8')
8 |
9 | def writeDebugCALL(self, data):
10 | line = "\n*---\nTotal CALL (deleted) " + str(data.CALLtotal)
11 | line += ' (' + str(data.CALLdeleted) + ')'
12 | line += '\n*---'
13 | self.dFileHandle.write(line)
14 | for i in range(data.CALLtotal):
15 | line = '\n[id] ' + data.CALLid[i]
16 | line += '\n\t[status] ' + data.CALLstatus[i]
17 | line += '\n\t[source] ' + data.CALLsource[i]
18 | line += '\n\t[direction] ' + data.CALLdirection[i]
19 | line += '\n\t[outcome] ' + data.CALLoutcome[i]
20 | line += '\n\t[time] ' + data.CALLtimeStamp[i]
21 | line += '\n\t[duration]' + data.CALLduration[i]
22 | if (len(data.CALLrolesTO[i]) > 0):
23 | line += '\n\t[roleTO] ' + data.CALLrolesTO[i][0]
24 | else:
25 | line += '\n\t[roleTO] ' + '_NOT_PROVIDED_'
26 |
27 | if (len(data.CALLrolesFROM[i]) > 0):
28 | line += '\n\t[roleFROM] ' + data.CALLrolesFROM[i][0]
29 | else:
30 | line += '\n\t[roleFROM] ' + '_NOT_PROVIDED_'
31 |
32 | if (len(data.CALLnamesTO[i]) > 0):
33 | line += '\n\t[nameTO] ' + data.CALLnamesTO[i][0]
34 | else:
35 | line += '\n\t[nameTO] ' + '_NOT_PROVIDED_'
36 |
37 | if (len(data.CALLnamesFROM[i]) > 0):
38 | line += '\n\t[nameFROM] ' + data.CALLnamesFROM[i][0]
39 | else:
40 | line += '\n\t[nameFROM] ' + '_NOT_PROVIDED_'
41 |
42 | if (len(data.CALLidentifiersTO[i]) > 0):
43 | line += '\n\t[identifierTO] ' + data.CALLidentifiersTO[i][0]
44 | else:
45 | line += '\n\t[identifierTO] ' + '_NOT_PROVIDED_'
46 |
47 | if (len(data.CALLidentifiersFROM[i]) > 0):
48 | line += '\n\t[identifierFROM] ' + data.CALLidentifiersFROM[i][0]
49 | else:
50 | line += '\n\t[identifierFROM] ' + '_NOT_PROVIDED_'
51 |
52 | self.dFileHandle.write(line)
53 |
54 | def writeDebugCHAT(self, data):
55 | line = "\n*---\nTotal CHAT (deleted) " + str(data.CHATtotal)
56 | line += ' (' + str(data.CHATdeleted) + ')'
57 | line += '\n*---'
58 | self.dFileHandle.write(line)
59 | for i in range(data.CHATtotal):
60 | line = '\n* [CHATid] ' + data.CHATid[i]
61 | line += '\n\t[source] ' + data.CHATsource[i]
62 | for j in range(len(data.CHATpartyIdentifiers[i])):
63 | line += '\n\t[particpantIdentifier] ' + data.CHATpartyIdentifiers[i][j]
64 | line += '\n\t[particpantName] ' + data.CHATpartyNames[i][j]
65 | for j in range(len(data.CHATmsgBodies[i])):
66 | line += '\n\t[msg n.] ' + str(j + 1)
67 | line += '\n\t\t[IdentifierFROM] ' + data.CHATmsgIdentifiersFrom[i][j]
68 | line += '\n\t\t[NameFROM] ' + data.CHATmsgNamesFrom[i][j]
69 | line += '\n\t\t[msgIdentifierTO] ' + data.CHATmsgIdentifiersTo[i][j]
70 | line += '\n\t\t[msgNameTO] ' + data.CHATmsgNamesTo[i][j]
71 | line += '\n\t\t[msgBody] ' + data.CHATmsgBodies[i][j]
72 | line += '\n\t\t[Status] ' + data.CHATmsgStatuses[i][j]
73 | line += '\n\t\t[msgTimeStamp] ' + data.CHATmsgTimeStamps[i][j]
74 | line += '\n\t\t[Attachment (File/Url)] ' + data.CHATmsgAttachmentFilenames[i][j]
75 | line += ' @@@ ' + data.CHATmsgAttachmentUrls[i][j]
76 | self.dFileHandle.write(line)
77 |
78 | def writeDebugCONTACT(self, data):
79 | line = "\n*---\nTotal CONTACT (deleted) " + str(data.CONTACTtotal)
80 | line += ' (' + str(data.CONTACTdeleted) + ')'
81 | line += '\n*---'
82 | self.dFileHandle.write(line + '\n')
83 | for i in range(data.CONTACTtotal):
84 | line = '[CONTACTid] ' + data.CONTACTid[i] + '\n'
85 | line += ' [Name] ' + data.CONTACTname[i]
86 | for j in range(len(data.CONTACTphoneNums[i])):
87 | line += ' [PhoneNums] ' + data.CONTACTphoneNums[i][j] + ' '
88 | line += '\n'
89 | self.dFileHandle.write(line)
90 |
91 | def writeDebugCONTEXT(self, data):
92 | line = "\n*---\nCONTEXT"
93 | line += '\n*---'
94 | line += '\n\t[Ufed version] ' + data.CONTEXTufedVersionText
95 | line += '\n\t[Device Extraction start date/time] '
96 | line += data.CONTEXTdeviceCreationTimeText + '\n'
97 | line += '\n\t[Device Acquisition Start/End date/time] '
98 | line += data.CONTEXTdeviceExtractionStartText + ' / '
99 | line += data.CONTEXTdeviceExtractionEndText + '\n'
100 | line += '\n\t[Examiner name] '
101 | line += data.CONTEXTexaminerNameText + '\n'
102 | line += '\n\t[Bluetooth MAC] ' + data.CONTEXTdeviceBluetoothAddressText
103 | line += '\n\t[DeviceID] ' + data.CONTEXTdeviceIdText
104 | line += '\n\t[PhoneModel] ' + data.CONTEXTdevicePhoneModelText
105 | line += '\n\t[OS type] ' + data.CONTEXTdeviceOsTypeText
106 | line += '\n\t[OS version] ' + data.CONTEXTdeviceOsVersionText
107 | line += '\n\t[PhoneVendor] ' + data.CONTEXTdevicePhoneVendorText
108 | line += '\n\t[MAC] ' + data.CONTEXTdeviceMacAddressText
109 | line += '\n\t[ICCID] ' + data.CONTEXTdeviceIccidText
110 | line += '\n\t[IMSI] ' + data.CONTEXTdeviceImsiText
111 | line += '\n\t[IMEI] ' + data.CONTEXTdeviceImeiText
112 | line += '\n\t[Files]'
113 | for i in range (len(data.CONTEXTimagePath)):
114 | line += '\n\t\t[path]' + data.CONTEXTimagePath[i]
115 | line += '\n\t\t[size]' + data.CONTEXTimageSize[i]
116 | line += '\n\t\t[hash SHA256 / MD5]' + data.CONTEXTimageMetadataHashSHA[i] + ' / '
117 | line += data.CONTEXTimageMetadataHashMD5[i]
118 | self.dFileHandle.write(line)
119 |
120 | def writeDebugEMAIL(self, data):
121 | line = "\n*---\nTotal EMAIL (deleted) " + str(data.EMAILtotal)
122 | line += ' (' + str(data.EMAILdeleted) + ')'
123 | line += '\n*---'
124 | self.dFileHandle.write(line)
125 | for i in range(data.EMAILtotal):
126 | line = '\n[EMAILid] ' + data.EMAILid[i]
127 | line += '\n\t[status] ' + data.EMAILstatus[i]
128 | line += '\n\t[Source] ' + data.EMAILsource[i]
129 | line += '\n\t[FROM] ' + data.EMAILidentifierFROM[i]
130 | line += '\n\t[TO] '
131 | for j in range(len(data.EMAILidentifiersTO[i])):
132 | line += '\n\t\t' + data.EMAILidentifiersTO[i][j]
133 | line += '\n\t[CC] '
134 | for j in range(len(data.EMAILidentifiersCC[i])):
135 | line += '\n\t\t' + data.EMAILidentifiersCC[i][j]
136 | line += '\n\t[BCC] '
137 | for j in range(len(data.EMAILidentifiersBCC[i])):
138 | line += '\n\t\t' + data.EMAILidentifiersBCC[i][j]
139 |
140 | line += '\n\t[Body] ' + data.EMAILbody[i]
141 | line += '\n\t[Subject] ' + data.EMAILsubject[i]
142 | line += '\n\t[TimeStamp] ' + data.EMAILtimeStamp[i]
143 | line += '\n\t[Attachments]'
144 | for j in range(len(data.EMAILattachmentsFilename[i])):
145 | line += '\n\t\t' + data.EMAILattachmentsFilename[i][j]
146 | self.dFileHandle.write(line)
147 |
148 | def writeDebugEXTRA_INFO(self, data):
149 | line = '\n*---\nTotal EXTRA_INFO ' + str(len(data.EXTRA_INFOdictPath))
150 | line += '\n*---'
151 | self.dFileHandle.write(line)
152 | for key in data.EXTRA_INFOdictPath:
153 | line = '\n[extraInofId] ' + key
154 | line += '\n\t[path] ' + data.EXTRA_INFOdictPath[key]
155 | line += '\n\t[size] ' + data.EXTRA_INFOdictSize[key]
156 | line += '\n\t[tableName] ' + data.EXTRA_INFOdictTableName[key]
157 | line += '\n\t[offset] ' + data.EXTRA_INFOdictOffset[key]
158 | line += '\n\t[nodeInfoId] ' + data.EXTRA_INFOdictNodeInfoId[key]
159 | self.dFileHandle.write(line)
160 |
161 | def writeDebugFILES(self, data):
162 | line = "\n*---\nTotal FILE " + str(len(data.FILEid))
163 | line += '\n*---'
164 | self.dFileHandle.write(line)
165 | for i in range(len(data.FILEid)):
166 | line = '\n[id]=' + data.FILEid[i]
167 | line += '\n\t[path] ' + data.FILEpath[i]
168 | line += '\n\t[size] ' + data.FILEsize[i]
169 | line += '\n\t[MD5] ' + data.FILEmd5[i]
170 | line += '\n\t[Tags] ' + data.FILEtags[i]
171 | line += '\n\t[Ctime] ' + data.FILEtimeCreate[i]
172 | line += '\n\t[Mtime] ' + data.FILEtimeModify[i]
173 | line += '\n\t[Atime] ' + data.FILEtimeAccess[i]
174 | line += '\n\t[localPath] ' + data.FILElocalPath[i]
175 | line += '\n\t[iNodeNumber] ' + data.FILEiNodeNumber[i]
176 | line += '\n\t[OwnerGID] ' + data.FILEownerGID[i]
177 | line += '\n\t[OwnerUID] ' + data.FILEownerUID[i]
178 | if data.FILEexifLatitudeRef[i] != '':
179 | line += '\n\t[EXIF]\n' + '\t' + data.FILEexifLatitudeRef[i] + \
180 | ' ' + data.FILEexifLatitude[i] + '\n' + \
181 | '\t' + data.FILEexifLongitudeRef[i] + ' ' + data.FILEexifLongitude[i] + '\n' + \
182 | '\t' + data.FILEexifAltitude[i] + '\n' + \
183 | '\t' + data.FILEexifMake[i] + ' ' + data.FILEexifModel[i]
184 | self.dFileHandle.write(line)
185 |
186 | def writeDebugSMS(self, data):
187 | line = "\n*---\nTotal SMS (deleted) " + str(data.SMStotal)
188 | line += ' (' + str(data.SMSdeleted) + ')'
189 | line += '\n*---'
190 | self.dFileHandle.write(line)
191 | for i in range(len(data.SMSbody)):
192 | line = '\n[SMSid] ' + data.SMSid[i]
193 | line += '\n\t[status] ' + data.SMSstatus[i]
194 | line += '\n\t[source] ' + data.SMSsource[i]
195 | line += '\n\t[parties]'
196 | for j in range(len(data.SMSpartyRoles[i])):
197 | line += '\n\t\t[role] ' + data.SMSpartyRoles[i][j]
198 | line += '\n\t\t[identifier] ' + data.SMSpartyIdentifiers[i][j]
199 | line += '\n\t\t[name] ' + data.SMSpartyNames[i][j]
200 |
201 | line += '\n\t[time] ' + data.SMStimeStamp[i]
202 | line += '\n\t[body] ' + data.SMSbody[i]
203 | self.dFileHandle.write(line)
204 |
205 | def writeDebugU_ACCOUNT(self, data):
206 | line = "\n*---\nTotal U_ACCOUNT " + str(data.U_ACCOUNTtotal)
207 | line += '\n*---'
208 | self.dFileHandle.write(line)
209 | for i in range(len(data.U_ACCOUNTsource)):
210 | line = '\n\t[Source] ' + data.U_ACCOUNTsource[i]
211 | line += '\n\t[Name] ' + data.U_ACCOUNTname[i]
212 | line += '\n\t[User Name] ' + data.U_ACCOUNTusername[i]
213 | self.dFileHandle.write(line)
214 |
215 |
216 | def writeDebugWEB_PAGE(self, data):
217 | line = "\n*---\nTotal WEB_PAGE (deleted) " + str(data.WEB_PAGEtotal)
218 | line += ' (' + str(data.WEB_PAGEdeleted) + ')'
219 | line += '\n*---'
220 | self.dFileHandle.write(line)
221 | for i in range(data.WEB_PAGEtotal):
222 | line = '\n[id] ' + data.WEB_PAGEid[i]
223 | line += '\n\t[source] ' + data.WEB_PAGEsource[i]
224 | line += '\n\t[url] ' + data.WEB_PAGEurl[i]
225 | line += '\n\t[title] ' + data.WEB_PAGEtitle[i]
226 | line += '\n\t[visitCount] ' + data.WEB_PAGEvisitCount[i]
227 | line += '\n\t[lastVisited] ' + data.WEB_PAGElastVisited[i]
228 | self.dFileHandle.write(line)
229 |
230 | def closeDebug(self):
231 | self.dFileHandle.close()
232 |
233 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/UFED_case_generator.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | #---
4 | # CASE_generate.py:
5 | # generate the JSON file pieces (Observables) that compose the final JSON-LD CASE file
6 | #
7 |
8 | import json
9 | from datetime import datetime
10 | from uuid import uuid4
11 | from datetime import datetime
12 |
13 | class ObjectCore(dict):
14 |
15 | def __init__(self):
16 | super().__init__()
17 |
18 | def _set_properties_str(self, **kwargs):
19 | for key, var in kwargs.items():
20 | if isinstance(var, str):
21 | self[key] = var
22 | else:
23 | self.__handle_var_type_errors(key, var, 'str')
24 |
25 | def _set_properties_float(self, **kwargs):
26 | for key, var in kwargs.items():
27 | if isinstance(var, float):
28 | self[key] = {"@type": "xsd:decimal", "@value": str(var)}
29 | else:
30 | self.__handle_var_type_errors(key, var, 'float')
31 |
32 | def _set_properties_int(self, **kwargs):
33 | for key, var in kwargs.items():
34 | if isinstance(var, int):
35 | self[key] = {"@type": "xsd:integer", "@value": str(var)}
36 | else:
37 | self.__handle_var_type_errors(key, var, 'int')
38 |
39 | def _set_properties_bool(self, **kwargs):
40 | for key, var in kwargs.items():
41 | if isinstance(var, bool):
42 | self[key] = {"@type": "xsd:boolean", "@value": var}
43 | else:
44 | self.__handle_var_type_errors(key, var, 'bool')
45 |
46 | def _set_properties_date_time(self, **kwargs):
47 | for key, var in kwargs.items():
48 | if isinstance(var, datetime):
49 | tz_info = var.strftime("%z")
50 | iso_format = var.isoformat() if tz_info else var.isoformat() + '+00:00'
51 | self[key] = {"@type": "xsd:dateTime", "@value": iso_format}
52 | else:
53 | self.__handle_var_type_errors(key, var, 'date time')
54 |
55 | def _set_properties_id_reference(self, **kwargs):
56 | for key, var in kwargs.items():
57 | if var is not None:
58 | self[key] = {'@id': var.get_id()}
59 |
60 | def _set_properties_list_id_reference(self, **kwargs):
61 | for key, var in kwargs.items():
62 | if var is not None:
63 | self[key] = [{'@id': item.get_id()} for item in var]
64 |
65 | def _set_properties_list_id_reference_array(self, **kwargs):
66 | for key, var in kwargs.items():
67 | if var is not None:
68 | # print(f"key={key}")
69 | # print(f"var={var}")
70 | self[key] = [{'@id': var.get_id()}]
71 |
72 | def __str__(self):
73 | return json.dumps(self, indent=4)
74 |
75 | def __handle_var_type_errors(self, var_name, var_val, expected_type):
76 | if var_val is None:
77 | pass
78 | else:
79 | print(f"Value provided for {var_name} is not of type {expected_type}: value provided: {var_val}")
80 | raise TypeError
81 |
82 | def _add_reference_list_vars(self, **kwargs):
83 | pass
84 |
85 |
86 | def get_id(self):
87 | return self["@id"]
88 |
89 | def append_to_uco_object(self, *args):
90 | for item in args:
91 | #self[self.root].append(item)
92 | self["uco-core:object"].append(item)
93 |
94 | class Bundle(ObjectCore):
95 |
96 | def __init__(self, uco_core_name=None, spec_version=None, description=None,
97 | root="uco-core:object"):
98 | """
99 | The header of the JSON and the CASE Object container (root) of Observables.
100 | """
101 | super().__init__()
102 | #self.build = [] # ???
103 | case_identifier = 'bundle-' + str(uuid4())
104 | self["@context"] = {
105 | "@vocabulary":"http://example.org/kb/",
106 | "kb": "http://example.org/kb/",
107 | "drafting":"http://example.org/ontology/drafting/",
108 | "co": "http://purl.org/co/",
109 | "case-investigation":"https://ontology.caseontology.org/case/investigation/",
110 | "uco-action":"https://ontology.unifiedcyberontology.org/uco/action/",
111 | "uco-core":"https://ontology.unifiedcyberontology.org/uco/core/",
112 | "uco-identity":"https://ontology.unifiedcyberontology.org/uco/identity/",
113 | "uco-role":"https://ontology.unifiedcyberontology.org/uco/role/",
114 | "uco-location":"https://ontology.unifiedcyberontology.org/uco/location/",
115 | "uco-observable":"https://ontology.unifiedcyberontology.org/uco/observable/",
116 | "uco-tool":"https://ontology.unifiedcyberontology.org/uco/tool/",
117 | "uco-types":"https://ontology.unifiedcyberontology.org/uco/types/",
118 | "uco-vocabulary":"https://ontology.unifiedcyberontology.org/uco/vocabulary/",
119 | "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
120 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
121 | "xsd": "http://www.w3.org/2001/XMLSchema#"
122 | }
123 |
124 | self["@type"] = "uco-core:Bundle"
125 | # self._set_properties_str(**{"uco-core:account_name": uco_core_name,
126 | # 'uco-core:specVersion': spec_version,
127 | # 'uco-core:description': description,
128 | # '@id': case_identifier})
129 | self._set_properties_str(**{'@id': case_identifier})
130 | self.root = root
131 | self[self.root] = list()
132 |
133 | #def append_object_to_root(self, *args):
134 | #for items in args:
135 | #self["uco-core:object"].append(item)
136 |
137 | class ObjectFacet(ObjectCore):
138 | def __init__(self):
139 | super().__init__()
140 | # each Facet/@type require to have IRIs (`@id`s)
141 | self["@id"] = "kb:" + str(uuid4())
142 |
143 |
144 | class ObjectObservable(ObjectCore):
145 |
146 | def __init__(self, object_class="uco-observable:ObservableObject"):
147 | """
148 | An observable object contains Facet, a group of unique features that characterises a
149 | Cyber item / Digital vestige.
150 | :param facets: the dictionary representing the Cyber item
151 | """
152 | super().__init__()
153 | self["@id"] = "kb:" + str(uuid4())
154 | self["@type"] = object_class
155 | self["uco-core:hasFacet"] = list()
156 |
157 | def append_facets(self, *facets):
158 | for facet in facets:
159 | self["uco-core:hasFacet"].append(facet)
160 |
161 |
162 | class ObjectSpecial(ObjectCore):
163 | def __init__(self):
164 | super().__init__()
165 | self["@id"] = "kb:" + str(uuid4())
166 |
167 | class Relationship(ObjectSpecial):
168 | def __init__(self, source=None, target=None, kind_of_relationship=None, start_time=None, end_time=None,
169 | directional=None):
170 | super().__init__()
171 | self["@type"] = "uco-observable:ObservableRelationship"
172 | self._set_properties_str(**{"uco-core:kindOfRelationship": kind_of_relationship})
173 | self._set_properties_bool(**{"uco-core:isDirectional": directional})
174 | self._set_properties_date_time(**{"uco-observable:startTime": start_time,
175 | "uco-observable:endTime": end_time,
176 | })
177 | self._set_properties_id_reference(**{"uco-core:source": source,
178 | "uco-core:target": target})
179 |
180 | class ProvenanceRecord(ObjectSpecial):
181 | def __init__(self, exhibit_number=None, uco_core_objects=None):
182 | super().__init__()
183 | self['@type'] = 'case-investigation:ProvenanceRecord'
184 | self._set_properties_str(**{"case-investigation:exhibitNumber": exhibit_number})
185 | self._set_properties_list_id_reference(**{"uco-core:object": uco_core_objects})
186 |
187 | class ObjectInfo(ObjectCore):
188 |
189 | def __init__(self, name="", version="", description=""):
190 | """
191 | An observable object contains Facet, a group of unique features that characterises a
192 | Cyber item / Digital vestige. This is for storing info about name,
193 | description and version o fthe bundle
194 | """
195 | super().__init__()
196 | self["@id"] = "kb:" + str(uuid4())
197 | self["@type"] = "uco-observable:ObservableObject"
198 | self["uco-core:name"] = name
199 | self["uco-core:description"] = description
200 | self["rdfs:comment"] = "version: " + version
201 |
202 | class Account(ObjectFacet):
203 |
204 | def __init__(self, identifier=None, is_active=True, issuer_id=None):
205 | """
206 | Used to represent user accounts
207 | :param is_active: Active unless specified otherwise (False)
208 | :param identifier: The idenitifier of the account (like a Skype username)
209 | :param issuer_id: The id of issuing body for application
210 | (e.g., kb:organization-skypeapp-cc44c2ae-bdd3-4df8-9ca3-1f58d682d62b)
211 | """
212 | super().__init__()
213 | self._set_properties_str(**{"@type": "uco-observable:AccountFacet",
214 | "uco-observable:accountIdentifier": identifier})
215 | self._set_properties_id_reference(**{"uco-observable:accountIssuer": issuer_id})
216 |
217 | self._set_properties_bool(**{"uco-observable:isActive": is_active})
218 |
219 |
220 | class ContentData(ObjectFacet):
221 |
222 | def __init__(self, byte_order=None, magic_number=None, mime_type=None, size_bytes=None, data_payload=None,
223 | entropy=None, is_encrypted=None, hash_method=None, hash_value=None):
224 | """
225 | The characteristics of a block of digital data.
226 | :param byte_order: Byte order of data. Example - "BigEndian"
227 | :param magic_number: The magic phone_number of a file
228 | :param mime_type: The mime type of a file. Example - "image/jpg"
229 | :param size_bytes: A phone_number representing the size of the content
230 | :param data_payload: A base64 representation of the data
231 | :param entropy: The entropy value for the data
232 | :param is_encrypted: A boolean True/False, if encrypted or not.
233 | :param hash_method: The algorithm used to calculate the hash value
234 | :param hash_value: The cryptographic hash of this content
235 | """
236 | super().__init__()
237 | self["@type"] = "uco-observable:ContentDataFacet"
238 | self._set_properties_str(**{"uco-observable:byteOrder": byte_order,
239 | "uco-observable:magicNumber": magic_number,
240 | "uco-observable:mimeType": mime_type,
241 | "uco-observable:dataPayload": data_payload,
242 | "uco-observable:entropy": entropy,
243 | "uco-observable:sizeInBytes": size_bytes,
244 | "uco-observable:isEncrypted": is_encrypted})
245 |
246 | if hash_method is not None or hash_value is not None or hash_value != "-":
247 | data = {"@type": "uco-types:Hash", "@id": "kb:" + str(uuid4())}
248 | if hash_method is not None:
249 | data["uco-types:hashMethod"] = {"@type": "uco-vocabulary:HashNameVocab",
250 | "@value": hash_method}
251 | if hash_value is not None:
252 | data["uco-types:hashValue"] = {"@type": "xsd:hexBinary", "@value": hash_value}
253 | self["uco-observable:hash"] = [data]
254 |
255 |
256 | class Application(ObjectFacet):
257 |
258 | def __init__(self, app_name=None, app_identifier=None, installed_version_history=None, num_launches=None, os=None, version=None):
259 | """
260 | A simple application
261 | :param app_name: Name of application (e.g. Native, Facebook, WhatsApp, etc.)
262 | """
263 | super().__init__()
264 | self["@type"] = "uco-observable:ApplicationFacet"
265 | self._set_properties_str(**{"uco-core:name": app_name,
266 | "uco-observable:applicationIdentifier": app_identifier,
267 | "uco-observable:version": version,
268 | "uco-observable:operatingSystem": os})
269 | self._set_properties_int(**{"uco-observable:numberOfLaunches": num_launches})
270 | self._set_properties_id_reference(**{"uco-observable:installedVersionHistory": installed_version_history})
271 |
272 | class ApplicationVersion(ObjectFacet):
273 | """
274 | A simple application version to manage the installed application
275 | :param install_date: The date when the application was installed/purchased on the device
276 | """
277 | def __init__(self, install_date):
278 | """
279 | A simple application
280 | :param install_date: installation date of an application
281 | """
282 | super().__init__()
283 | self["@type"] = "uco-observable:ApplicationVersion"
284 | self._set_properties_date_time(**{"uco-observable:installDate": install_date})
285 |
286 | class DataRange(ObjectFacet):
287 |
288 | def __init__(self, range_offset=None, range_size=None):
289 | """
290 | A data range facet is a grouping of characteristics unique to a particular contiguous scope
291 | within a block of digital data
292 | :param range_offset: location in data at which the contiguous data starts
293 | :param range_size: the length of the data starting at the offset point
294 | """
295 | super().__init__()
296 | self["@type"] = "uco-observable:DataRangeFacet"
297 | self._set_properties_str(**{"uco-observable:rangeOffset": range_offset,
298 | "uco-observable:rangeSize": range_size})
299 |
300 |
301 | class Device(ObjectFacet):
302 |
303 | def __init__(self, device_type=None, manufacturer=None, model=None, serial=None):
304 | """
305 | Characteristics of a piece of electronic equipment.
306 | :param device_type: The type of device (e.g., "camera")
307 | :param manufacturer: The producer of the device (e.g., "Canon")
308 | :param model: The model of the device (e.g., "Powershot SX540")
309 | :param serial: The serial phone_number of the device (e.g., "1296-3219-8792-CL918")
310 | """
311 | super().__init__()
312 | self["@type"] = "uco-observable:DeviceFacet"
313 | self._set_properties_str(**{"uco-observable:deviceType": device_type,
314 | "uco-observable:manufacturer": manufacturer,
315 | "uco-observable:model": model,
316 | "uco-observable:serialNumber": serial})
317 |
318 |
319 | class WifiAddress(ObjectFacet):
320 |
321 | def __init__(self, wifi_mac_address=None):
322 | """
323 | :param wifi_mac_address: The wifi mac address of a device (EG: 11:54:00:bc:c8:ba)
324 | """
325 | super().__init__()
326 | self["@type"] = "uco-observable:WifiAddressFacet"
327 | self._set_properties_str(**{"uco-observable:addressValue": wifi_mac_address})
328 |
329 |
330 | class BrowserBookmark(ObjectFacet):
331 | def __init__(self, bookmark_source=None, url=None, bookmark_path=None, bookmark_accessed_time=None):
332 | """
333 | :param source:
334 | :param url:
335 | :param path:
336 | :param manually_entered_count:
337 | :param accessed_time: An observable object with a URLFacet
338 | """
339 | super().__init__()
340 |
341 | self['@type'] = 'uco-observable:BrowserBookmarkFacet'
342 |
343 | self._set_properties_str(**{'uco-observable:bookmarkPath': bookmark_path})
344 | self._set_properties_date_time(**{'uco-observable:observableCreatedTime': bookmark_accessed_time})
345 | self._set_properties_id_reference(**{'uco-observable:application':bookmark_source, 'uco-observable:urlTargeted': url})
346 |
347 | class BluetoothAddress(ObjectFacet):
348 |
349 | def __init__(self, name=None, address=None):
350 | """
351 | :param name:
352 | :param address: The Bluetooth address value (e.g. "D4:A3:3D:B5:F4:6C")
353 | """
354 | super().__init__()
355 | self["@type"] = "uco-observable:BluetoothAddressFacet"
356 | self._set_properties_str(**{'uco-core:name': name,
357 | 'uco-observable:addressValue': address})
358 |
359 |
360 | class UrlHistory(ObjectFacet):
361 |
362 | def __init__(self, browser=None, history_entries=None):
363 | """
364 | :param browser_info: An observable object containing a URLHistoryFacet
365 | :param history_entries: A list of URLHistoryEntry types
366 | """
367 |
368 | super().__init__()
369 | self["@type"] = "uco-observable:URLHistoryFacet"
370 | self._set_properties_id_reference(**{'uco-observable:browserInformation': browser})
371 | #self.append_history_entries(history_entries)
372 |
373 | #def append_history_entries(self, entries):
374 | #"""
375 | #Used to add history entries to this URL History facet
376 | #:param args: A single/tuple of URLHistoryEntry class types
377 | #"""
378 | ##for entry in entries:
379 | #self["uco-core:hasFacet"].append(history_entries)
380 |
381 |
382 | class UrlHistoryEntry(ObjectFacet):
383 |
384 | def __init__(self, first_visit=None, last_visit=None, expiration_time=None, manually_entered_count=None, url=None,
385 | user_profile=None, page_title=None, referrer_url=None, visit_count=None, keyword_search_term=None,
386 | allocation_status=None, browser=None):
387 | """
388 | :param first_visit:
389 | :param last_visit:
390 | :param expiration_time:
391 | :param manually_entered_count:
392 | :param url: An observable object with a URLFacet
393 | :param user_profile:
394 | :param page_title:
395 | :param referrer_url:
396 | :param visit_count:
397 | :param keyword_search_term:
398 | :param allocation_status:
399 | """
400 |
401 | super().__init__()
402 |
403 | self['@type'] = 'uco-observable:URLHistoryFacet'
404 |
405 | #self._set_properties_id_reference(**{'uco-observable:browserInformation': browser})
406 | self['uco-observable:browserInformation'] = {'@id': browser.get_id()}
407 |
408 | # self._set_properties_str(**{'uco-observable:userProfile': user_profile, # todo: referral?
409 | # 'uco-observable:pageTitle': page_title,
410 | # 'uco-observable:referrerUrl': referrer_url,
411 | # 'uco-observable:keywordSearchTerm': keyword_search_term,
412 | # 'uco-observable:allocationStatus': allocation_status})
413 | # self._set_properties_int(**{'uco-observable:visitCount': visit_count,
414 | # 'uco-observable:manuallyEnteredCount': manually_entered_count})
415 | # self._set_properties_date_time(**{'uco-observable:firstVisit': first_visit,
416 | # 'uco-observable:lastVisit': last_visit,
417 | # 'uco-observable:expirationTime': expiration_time})
418 | # self._set_properties_id_reference(**{'uco-observable:url': url})
419 |
420 |
421 | if first_visit:
422 | tz_info = first_visit.strftime("%z")
423 | first_iso_format = first_visit.isoformat() if tz_info else first_visit.isoformat() + '+00:00'
424 | else:
425 | first_iso_format = '1900-01-01T08:00:00+00:00'
426 |
427 | if last_visit:
428 | tz_info = last_visit.strftime("%z")
429 | last_iso_format = last_visit.isoformat() if tz_info else last_visit.isoformat() + '+00:00'
430 | else:
431 | last_iso_format = '1900-01-01T08:00:00+00:00'
432 |
433 | self['uco-observable:urlHistoryEntry'] = []
434 | self['uco-observable:urlHistoryEntry'].append(
435 | {'@id': "kb:" + str(uuid4()),
436 | '@type': 'uco-observable:URLHistoryEntry',
437 | 'uco-observable:firstVisit': {"@type": "xsd:dateTime", "@value": first_iso_format},
438 | 'uco-observable:lastVisit': {"@type": "xsd:dateTime", "@value": last_iso_format},
439 | 'uco-observable:pageTitle': page_title,
440 | 'uco-observable:url': {'@id': url.get_id()},
441 | 'uco-observable:visitCount': {"@type": "xsd:integer", "@value": visit_count},
442 | 'uco-observable:allocationStatus': allocation_status,
443 | 'uco-observable:keywordSearchTerm': keyword_search_term})
444 |
445 |
446 | class Url(ObjectFacet):
447 |
448 | def __init__(self, url_address=None, url_port=None, url_host=None, url_fragment=None, url_password=None,
449 | url_path=None, url_query=None, url_scheme=None, url_username=None):
450 | """
451 | :param url_address: an address of a url (i.e. google.ie)
452 | :param url_port: a tcp or udp port of a url for example 3000
453 | :param url_host: the Ip address of a host that was requested (e.g.192.168.1.1 could be your home router)
454 | :param url_fragment: A fragment of a url pointing to a specific resource (i.e subdomain=api)
455 | :param url_password: A password that may be used in authentication scheme for accessing restricted resources
456 | :param url_path: the location that may have resources available e.g. /chatapp
457 | :param url_query: a query that may be used with a resource such as an api e.g. ?health
458 | :param url_scheme: Identifies the type of URL. (e.g. ssh://)
459 | :param url_username: A username that may be required for authentication for a specific resource. (login)
460 | """
461 | super().__init__()
462 | self["@type"] = "uco-observable:URLFacet"
463 | self._set_properties_str(**{"uco-observable:fullValue": url_address,
464 | "uco-observable:host": url_host,
465 | "uco-observable:fragment": url_fragment,
466 | "uco-observable:password": url_password,
467 | "uco-observable:path": url_path,
468 | "uco-observable:query": url_query,
469 | "uco-observable:scheme": url_scheme,
470 | "uco-observable:userName": url_username})
471 | self._set_properties_int(**{"uco-observable:port": url_port})
472 |
473 |
474 | class RasterPicture(ObjectFacet):
475 |
476 | def __init__(self, camera_id=None, bits_per_pixel=None, picture_height=None, picture_width=None,
477 | image_compression_method=None, picture_type=None):
478 | """
479 | This CASEObject represents the contents of a file or device
480 | :param camera_id: An observable cyberitem
481 | :param bits_per_pixel: The phone_number (integer) of bits per pixel
482 | :param picture_height: The height of a picture (integer)
483 | :param picture_width: The width of a picture (integer)
484 | :param image_compression_method: The compression method used
485 | :param picture_type: The type of picture ("jpg", "png" etc.)
486 | """
487 | super().__init__()
488 | self["@type"] = "uco-observable:RasterPictureFacet"
489 | self._set_properties_str(**{"uco-observable:imageCompressionMethod": image_compression_method,
490 | "uco-observable:pictureType": picture_type,
491 | "uco-observable:pictureHeight": picture_height,
492 | "uco-observable:pictureWidth": picture_width,
493 | "uco-observable:bitsPerPixel": bits_per_pixel})
494 | self._set_properties_id_reference(**{"uco-observable:camera": camera_id})
495 |
496 |
497 | class PhoneCall(ObjectFacet):
498 |
499 | def __init__(self, call_type=None, start_time=None, application=None, call_from=None,
500 | call_to=None, call_duration=None, allocation_status=None):
501 | """
502 | :param call_type: incoming outgoing etc
503 | :param start_time: the time at which the device registered the call as starting
504 | :param application: ObjectObservable with call-application (e.g. WhatsApp) facet-info
505 | :param call_from: ObjectObservable with person/caller facet-info
506 | :param call_to: ObjectObservable with person/caller facet-info
507 | :param call_duration: how long the call was registedred on the device as lasting in minutes (E.G. 60)
508 | :param allocation_status: The allocation status of the record of the call i.e intact for records that are
509 | present on the device
510 | """
511 | super().__init__()
512 | self["@type"] = "uco-observable:PhoneCallFacet"
513 | self._set_properties_str(**{"uco-observable:callType": call_type,
514 | "uco-observable:allocationStatus": allocation_status})
515 | self._set_properties_int(**{"uco-observable:duration": call_duration})
516 | self._set_properties_date_time(**{"uco-observable:startTime": start_time})
517 | self._set_properties_id_reference(**{"uco-observable:application": application,
518 | "uco-observable:from": call_from,
519 | "uco-observable:to": call_to})
520 |
521 | class Call(ObjectFacet):
522 |
523 | def __init__(self, call_type=None, start_time=None, application=None, call_from=None,
524 | call_to=None, call_duration=None, allocation_status=None):
525 | """
526 | :param call_type: incoming outgoing etc
527 | :param start_time: the time at which the device registered the call as starting
528 | :param application: ObjectObservable with call-application (e.g. WhatsApp) facet-info
529 | :param call_from: ObjectObservable with person/caller facet-info
530 | :param call_to: ObjectObservable with person/caller facet-info
531 | :param call_duration: how long the call was registedred on the device as lasting in minutes (E.G. 60)
532 | :param allocation_status: The allocation status of the record of the call i.e intact for records that are
533 | present on the device
534 | """
535 | super().__init__()
536 | self["@type"] = "uco-observable:CallFacet"
537 | self._set_properties_str(**{"uco-observable:callType": call_type,
538 | "uco-observable:allocationStatus": allocation_status})
539 | self._set_properties_int(**{"uco-observable:duration": call_duration})
540 | self._set_properties_date_time(**{"uco-observable:startTime": start_time})
541 | self._set_properties_id_reference(**{"uco-observable:application": application,
542 | "uco-observable:from": call_from,
543 | "uco-observable:to": call_to})
544 |
545 |
546 | class PhoneAccount(ObjectFacet):
547 |
548 | def __init__(self, phone_number=None, account_name=None):
549 | """
550 |
551 | :param phone_number: The number for this account (e.g., "+16503889249")
552 | :param account_name: The name of this account/user (e.g., "Bill Bryson")
553 | """
554 | super().__init__()
555 | self["@type"] = "uco-observable:PhoneAccountFacet"
556 | self._set_properties_str(**{"uco-observable:phoneNumber": phone_number,
557 | "uco-observable:displayName": account_name})
558 |
559 |
560 | class EmailAccount(ObjectFacet):
561 |
562 | def __init__(self, email_address):
563 | """
564 | :param email_address: An ObjectObservable (with EmailAdressFacet)
565 | """
566 | super().__init__()
567 | self["@type"] = "uco-observable:EmailAccountFacet"
568 | self._set_properties_id_reference(**{"uco-observable:emailAddress": email_address})
569 |
570 |
571 | class EmailAddress(ObjectFacet):
572 |
573 | def __init__(self, email_address_value=None, display_name=None):
574 | """
575 | Used to represent the value of an email address.
576 | :param email_address_value: a single email address (e.g., "bob@example.com")
577 | """
578 | super().__init__()
579 | self["@type"] = "uco-observable:EmailAddressFacet"
580 | self._set_properties_str(**{"uco-observable:addressValue": email_address_value,
581 | "uco-core:displayName": display_name})
582 |
583 |
584 | class EmailMessage(ObjectFacet):
585 |
586 | def __init__(self, msg_to=None, msg_from=None, cc=None, bcc=None, subject=None, body=None, received_time=None,
587 | sent_time=None, modified_time=None, other_headers=None, application=None, body_raw=None,
588 | header_raw=None, in_reply_to=None, sender=None, x_originating_ip=None, is_read=None,
589 | content_disposition=None, content_type=None, message_id=None, priority=None, x_mailer=None,
590 | is_mime_encoded=None, allocation_status=None, is_multipart=None):
591 | """
592 | An instance of an email message, corresponding to the internet message format described in RFC 5322 and related.
593 | :param msg_to: A list of ObjectObservables (with EmailAccountFacet)
594 | :param msg_from: An ObjectObservable (with EmailAccountFacet)
595 | :param cc: A list of ObjectObservables (with EmailAccountFacet) in carbon copy
596 | :param bcc: A list of ObjectObservables (with EmailAccountFacet) in blind carbon copy
597 | :param subject: The subject of the email.
598 | :param body: The content of the email.
599 | :param received_time: The time received, in ISO8601 time format (e.g., "2020-09-29T12:13:01Z")
600 | :param sent_time: The time sent, in ISO8601 time format (e.g., "2020-09-29T12:13:01Z")
601 | :param modified_time: The time modified, in ISO8601 time format (e.g., "2020-09-29T12:13:01Z")
602 | :param other_headers: A dictionary of other headers
603 | :param application: The application associated with this object.
604 | :param body_raw:
605 | :param header_raw:
606 | :param in_reply_to: One of more unique identifiers for identifying the email(s) this email is a reply to.
607 | :param sender: ???
608 | :param x_originating_ip:
609 | :param is_read: A boolean True/False
610 | :param content_disposition:
611 | :param content_type:
612 | :param message_id: A unique identifier for the message.
613 | :param priority: The priority of the email.
614 | :param x_mailer:
615 | :param is_mime_encoded: A boolean True/False
616 | :param is_multipart: A boolean True/False
617 | :param allocation_status:
618 | """
619 | super().__init__()
620 | self["@type"] = "uco-observable:EmailMessageFacet"
621 | self._set_properties_str(**{"uco-observable:subject": subject,
622 | "uco-observable:body": body,
623 | "uco-observable:otherHeaders": other_headers,
624 | "uco-observable:bodyRaw": body_raw,
625 | "uco-observable:headerRaw": header_raw,
626 | "uco-observable:contentDisposition": content_disposition,
627 | "uco-observable:contentType": content_type,
628 | "uco-observable:messageID": message_id,
629 | "uco-observable:priority": priority,
630 | "uco-observable:xMailer": x_mailer,
631 | "uco-observable:allocationStatus": allocation_status,
632 | "uco-observable:receivedTime": received_time,
633 | "uco-observable:modifiedTime": modified_time,
634 | "uco-observable:isRead": is_read,
635 | "uco-observable:isMimeEncoded": is_mime_encoded,
636 | "uco-observable:isMultipart": is_multipart})
637 | self._set_properties_date_time(**{"uco-observable:sentTime": sent_time})
638 | self._set_properties_list_id_reference(**{"uco-observable:to": msg_to,
639 | "uco-observable:cc": cc,
640 | "uco-observable:bcc": bcc,
641 | "uco-observable:inReplyTo": in_reply_to,
642 | "uco-observable:sender": sender,
643 | "uco-observable:xOriginatingIP": x_originating_ip,
644 | "uco-observable:application": application})
645 | self._set_properties_id_reference(**{"uco-observable:from": msg_from})
646 |
647 |
648 | class EXIF(ObjectFacet):
649 |
650 | def __init__(self, **kwargs):
651 | """
652 | Specifies exchangeable image file format (Exif) metadata tags for image and sound files recorded by digital cameras.
653 | :param kwargs: The user provided key/value pairs of exif items (e.g., Make="Canon", etc.).
654 | """
655 | super().__init__()
656 | self["@type"] = "uco-observable:EXIFFacet"
657 |
658 | self["uco-observable:exifData"] = {"@type": "uco-types:ControlledDictionary", "uco-types:entry": []}
659 | for k, v in kwargs.items():
660 | if v not in ["", " "]:
661 | item = {"@type": "uco-types:ControlledDictionaryEntry", "uco-types:key": k, "uco-types:value": v}
662 | self["uco-observable:exifData"]["uco-types:entry"].append(item)
663 |
664 |
665 | class ExtInode(ObjectFacet):
666 |
667 | def __init__(self, deletion_time=None, inode_change_time=None, file_type=None, flags=None, hard_link_count=None,
668 | inode_id=None, permissions=None, sgid=None, suid=None):
669 | """
670 | An instance of an email message, corresponding to the internet message format described in RFC 5322 and related.
671 | :param deletion_time: Specifies the time at which the file represented by an Inode was 'deleted'.
672 | :param inode_change_time: The date and time at which the file Inode metadata was last modified.
673 | :param file_type: Specifies the EXT file type (FIFO, Directory, Regular file, Symbolic link, etc) for the Inode.
674 | :param flags: Specifies user flags to further protect (limit its use and modification) the file represented by an Inode.
675 | :param hard_link_count: Specifies a count of how many hard links point to an Inode.
676 | :param inode_id: Specifies a single Inode identifier.
677 | :param permissions: Specifies the read/write/execute permissions for the file represented by an EXT Inode.
678 | :param sgid: Specifies the group ID for the file represented by an Inode.
679 | :param suid: Specifies the user ID that 'owns' the file represented by an Inode.
680 | """
681 | super().__init__()
682 | self["@type"] = "uco-observable:ExtInodeFacet"
683 | self._set_properties_str(**{"uco-observable:extFileType": file_type,
684 | "uco-observable:extFlags": flags,
685 | "uco-observable:extHardLinkCount": hard_link_count,
686 | "uco-observable:extPermissions": permissions,
687 | })
688 | self._set_properties_int(**{"uco-observable:extSGID": sgid,
689 | "uco-observable:extSUID": suid,
690 | "uco-observable:extInodeID": inode_id})
691 | self._set_properties_date_time(**{"uco-observable:extDeletionTime": deletion_time,
692 | "uco-observable:extInodeChangeTime": inode_change_time})
693 |
694 |
695 | class CalendarEntry(ObjectFacet):
696 |
697 | def __init__(self, group=None, subject=None, details=None, start_time=None, end_time=None, repeat_until=None,
698 | repeat_interval=None, status=None, private=None, recurrence=None, remind_time=None,
699 | attendants=None):
700 | super().__init__()
701 | self["@type"] = "uco-observable:CalendarEntryFacet"
702 | self._set_properties_str(**{"drafting:group": group,
703 | "uco:observable:subject": subject,
704 | "drafting:details": details,
705 | "drafting:repeatInterval": repeat_interval, # todo: type?
706 | 'uco-observable:eventStatus': status,
707 | 'uco-observable:recurrence': recurrence,
708 | 'uco-observable:remindTime': remind_time,
709 | "drafting:repeatUntil": repeat_until,
710 | 'uco:observable:isPrivate': private})
711 | self._set_properties_date_time(**{"uco-observable:startTime": start_time,
712 | "uco-observable:endTime": end_time})
713 | #self.append_attendants(attendants)
714 |
715 |
716 | # def append_attendants(self, *args):
717 | # self._append_observable_objects("uco-observable:attendant", *args)
718 |
719 |
720 | class BrowserCookie(ObjectFacet):
721 |
722 | def __init__(self, source=None, name=None, path=None, domain=None, created_time=None,
723 | last_access_time=None, expiration_time=None, secure=None):
724 | super().__init__()
725 | self["@type"] = "uco-observable:BrowserCookieFacet"
726 | self._set_properties_str(**{'uco-observable:cookieName': name,
727 | "uco-observable:cookiePath": path,
728 | 'uco-observable:isSecure': secure})
729 | self._set_properties_date_time(**{'uco-observable:observableCreatedTime': created_time,
730 | "uco-observable:accessedTime": last_access_time,
731 | 'uco-observable:expirationTime': expiration_time})
732 | self._set_properties_id_reference(**{"drafting:source": source,
733 | 'uco-observable:cookieDomain': domain})
734 |
735 |
736 | class File(ObjectFacet):
737 |
738 | def __init__(self, file_system_type=None, file_name=None, file_path=None, file_local_path=None,
739 | file_extension=None,
740 | size_bytes=None, accessed_time=None, created_time=None, modified_time=None,
741 | metadata_changed_time=None,
742 | tag=None):
743 | """
744 | The basic properties associated with the storage of a file on a file system.
745 | :param file_system_type: The specific type of a file system (e.g., "EXT4")
746 | :param file_name: Specifies the account_name associated with a file in a file system (e.g., "IMG_0123.jpg").
747 | :param file_path: Specifies the file path for the location of a file within a filesystem. (e.g., "/sdcard/IMG_0123.jpg")
748 | :param file_extension: The file account_name extension. Not present if the file has no dot in its account_name. (e.g., "jpg").
749 | :param size_bytes: The size of the data in bytes (e.g., integer like 35125)
750 | :param accessed_time: The datetime the file was last accessed
751 | :param created_time: The datetime the file was created
752 | :param modified_time: The datetime the file was last modified
753 | :param metadata_changed_time: The last change to metadata of a file but not necessarily the file contents
754 | :param tag: A generic (string) tag/label, or a list/tuple of (strings) tags/labels.
755 | """
756 | super().__init__()
757 | self["@type"] = "uco-observable:FileFacet"
758 | self._set_properties_str(**{"uco-observable:fileSystemType": file_system_type,
759 | "uco-observable:fileName": file_name,
760 | "uco-observable:filePath": file_path,
761 | "drafting:fileLocalPath": file_local_path,
762 | "uco-observable:extension": file_extension,
763 | "uco-observable:mimeType": tag,
764 | "uco-observable:metadataChangeTime": metadata_changed_time})
765 | #self._set_properties_str(**{'uco-core:tag': tag})
766 | #self['uco-core:tag'] = tag
767 | self._set_properties_date_time(**{"uco-observable:accessedTime": accessed_time,
768 | "uco-observable:observableCreatedTime": created_time,
769 | "uco-observable:modifiedTime": modified_time})
770 | self._set_properties_int(**{"uco-observable:sizeInBytes": size_bytes})
771 |
772 |
773 | class Message(ObjectFacet):
774 |
775 | def __init__(self, msg_to=None, msg_from=None, message_text=None, sent_time=None,
776 | application=None, message_type=None, message_id=None, session_id=None):
777 | """
778 | Characteristics of an electronic message.
779 | :param msg_to: A list of ObjectObservables
780 | :param msg_from: An ObjectObservable
781 | :param message_text: The content of the email.
782 | :param sent_time: The time sent, in ISO8601 time format (e.g., "2020-09-29T12:13:01Z")
783 | :param application: The application associated with this object.
784 | :param message_type:
785 | :param message_id: A unique identifier for the message.
786 | :param session_id: The priority of the email.
787 | """
788 | super().__init__()
789 | self["@type"] = "uco-observable:MessageFacet"
790 | self._set_properties_str(**{"uco-observable:messageText": message_text,
791 | "uco-observable:messageType": message_type,
792 | "uco-observable:messageID": message_id,
793 | "uco-observable:sessionID": session_id})
794 | self._set_properties_date_time(**{"uco-observable:sentTime": sent_time})
795 | self._set_properties_id_reference(**{"uco-observable:from": msg_from,
796 | "uco-observable:application": application})
797 | self._set_properties_list_id_reference(**{"uco-observable:to": msg_to})
798 |
799 | class SmsMessage(ObjectFacet):
800 |
801 | def __init__(self, msg_to=None, msg_from=None, message_text=None, sent_time=None,
802 | application=None, message_id=None, session_id=None):
803 | """
804 | Characteristics of an electronic message.
805 | :param msg_to: A list of ObjectObservables
806 | :param msg_from: An ObjectObservable
807 | :param message_text: The content of the email.
808 | :param sent_time: The time sent, in ISO8601 time format (e.g., "2020-09-29T12:13:01Z")
809 | :param application: The application associated with this object.
810 | :param message_type:
811 | :param message_id: A unique identifier for the message.
812 | :param session_id: The priority of the email.
813 | """
814 | super().__init__()
815 | self["@type"] = "uco-observable:SMSMessageFacet"
816 | self._set_properties_str(**{"uco-observable:messageText": message_text,
817 | "uco-observable:messageID": message_id,
818 | "uco-observable:sessionID": session_id})
819 | self._set_properties_date_time(**{"uco-observable:sentTime": sent_time})
820 | self._set_properties_id_reference(**{"uco-observable:from": msg_from,
821 | "uco-observable:application": application})
822 | self._set_properties_list_id_reference(**{"uco-observable:to": msg_to})
823 |
824 | class MobileDevice(ObjectFacet):
825 |
826 | def __init__(self, IMSI=None, ICCID=None, IMEI=None, storage_capacity=None, keypad_pin=None):
827 | """
828 | The basic properties associated with a phone and phone account of a device or user.
829 | :param IMSI International mobile subscriber identity
830 | :param ICCID Integrated Circuit Card Identification Number
831 | :param IMEI international mobile equipment identity
832 | :param storage_capacity storage capacity of device in bytes
833 | """
834 | super().__init__()
835 | self["@type"] = "uco-observable:MobileDeviceFacet"
836 | self._set_properties_str(**{"uco-observable:IMSI": IMSI,
837 | "uco-observable:ICCID": ICCID,
838 | "uco-observable:IMEI": IMEI})
839 | self._set_properties_int(**{"uco-observable:storageCapacityInBytes": storage_capacity,
840 | "uco-observable:keypadUnlockCode": keypad_pin})
841 |
842 |
843 | class OperatingSystem(ObjectFacet):
844 |
845 | def __init__(self, os_name=None, os_manufacturer=None, os_version=None, os_install_date=None):
846 | super().__init__()
847 | self["@type"] = "uco-observable:OperatingSystemFacet"
848 | self._set_properties_str(**{"uco-observable:displayName": os_name,
849 | "uco-observable:version": os_version})
850 | self._set_properties_id_reference(**{"uco-observable:manufacturer": os_manufacturer})
851 | self._set_properties_date_time(**{"uco-observable:installDate": os_install_date})
852 |
853 |
854 | class PathRelation(ObjectFacet):
855 |
856 | def __init__(self, path):
857 | """
858 | This CASE object specifies the location of one object within another containing object.
859 | :param path: The full path to the object (e.g, "/sdcard/IMG_0123.jpg")
860 | """
861 | super().__init__()
862 | self["@type"] = "uco-observable:PathRelationFacet"
863 | self._set_properties_str(**{"uco-observable:path": path})
864 |
865 |
866 | class Event(ObjectFacet):
867 |
868 | def __init__(self, event_type=None, event_text=None, event_id=None, cyber_action=None, computer_name=None,
869 | created_time=None, start_time=None, end_time=None):
870 | """
871 | An event facet is a grouping of characteristics unique to something that happens in a digital context
872 | (e.g., operating system events).
873 | :param event_type: The type of the event, for example 'information', 'warning' or 'error'.
874 | :param event_text: The textual representation of the event.
875 | :param event_id: The identifier of the event.
876 | :param cyber_action: The action taken in response to the event.
877 | :param computer_name: A name of the computer on which the log entry was created.
878 | """
879 | super().__init__()
880 | self["@type"] = "uco-observable:EventRecordFacet"
881 | self._set_properties_str(**{"uco-observable:eventType": event_type,
882 | "uco-observable:eventRecordText": event_text,
883 | "uco-observable:eventID": event_id,
884 | "uco-observable:computerName": computer_name})
885 | self._set_properties_id_reference(**{'uco-observable:cyberAction': cyber_action})
886 | self._set_properties_date_time(**{'uco-observable:observableCreatedTime': created_time,
887 | 'drafting:observableStartTime': start_time,
888 | 'drafting:observableEndTime': end_time})
889 |
890 |
891 | # class ObservableRelationship(ObjectSpecial):
892 |
893 | # def __init__(self, source, target, start_time=None, end_time=None, kind_of_relationship=None, directional=None):
894 | # """
895 | # This object represents an assertion that one or more objects are related to another object in some way
896 | # :param source: An observable object
897 | # :param target: An observable object
898 | # :param start_time: The time, in ISO8601 time format, the action was started (e.g., "2020-09-29T12:13:01Z")
899 | # :param end_time: The time, in ISO8601 time format, the action completed (e.g., "2020-09-29T12:13:43Z")
900 | # :param kind_of_relationship: How these items relate from source to target (e.g., "Contained_Within")
901 | # :param directional: A boolean representing ???? Usually set to True
902 | # """
903 | # super().__init__()
904 | # self["@type"] = "uco-observable:ObservableRelationship"
905 | # self._bool_vars(**{"uco-core:isDirectional": directional})
906 | # self._str_vars(**{"uco-core:kindOfRelationship": kind_of_relationship})
907 | # self._datetime_vars(**{"uco-observable:startTime": start_time,
908 | # "uco-observable:endTime": end_time})
909 | # self._node_reference_vars(**{"uco-core:source": source,
910 | # "uco-core:target": target})
911 |
912 | # def set_start_accessed_time(self):
913 | # """Set the time when this action initiated."""
914 | # self._addtime(_type='start')
915 |
916 | # def set_end_accessed_time(self):
917 | # """Set the time when this action completed."""
918 | # self._addtime(_type='end')
919 |
920 | # def _addtime(self, _type):
921 | # time = datetime.now(timezone('UTC'))
922 | # self[f"uco-observable:{_type}Time"] = {"@type": "xsd:dateTime", "@value": time.isoformat()}
923 |
924 |
925 | class ApplicationAccount(ObjectFacet):
926 |
927 | def __init__(self, application=None):
928 | """
929 | An application account facet is a grouping of characteristics unique to an account within a particular software
930 | program designed for end users.
931 | :param application: An Observable Object (containing an Application Facet)
932 | """
933 | super().__init__()
934 | self["@type"] = "uco-observable:ApplicationAccountFacet"
935 | self._set_properties_id_reference(**{"uco-observable:application": application})
936 |
937 |
938 | class DigitalAccount(ObjectFacet):
939 |
940 | def __init__(self, display_name=None, login=None, first_login_time=None, disabled=None, last_login_time=None):
941 | """
942 | A digital account facet is a grouping of characteristics unique to an arrangement with an entity to enable and
943 | control the provision of some capability or service within the digital domain.
944 | """
945 | super().__init__()
946 | self["@type"] = "uco-observable:DigitalAccountFacet"
947 | self._set_properties_str(**{"uco-observable:displayName": display_name,
948 | 'uco-observable:accountLogin': login})
949 | self._set_properties_date_time(**{'uco-observable:firstLoginTime': first_login_time,
950 | 'uco-observable:lastLoginTime': last_login_time})
951 | self._set_properties_bool(**{'uco-observable:isDisabled': disabled})
952 |
953 |
954 | class WirelessNetworkConnection(ObjectFacet):
955 |
956 | def __init__(self, ssid=None, base_station=None):
957 | """
958 | A wireless network connection facet is a grouping of characteristics unique to a connection (completed or
959 | attempted) across an IEEE 802.11 standards-conformant digital network (a group of two or more computer systems
960 | linked together).
961 | """
962 | super().__init__()
963 | self["@type"] = "uco-observable:WirelessNetworkConnectionFacet"
964 | self._set_properties_str(**{"uco-observable:ssid": ssid,
965 | 'uco-observable:baseStation': base_station})
966 |
967 | class Messagethread(ObjectFacet):
968 |
969 | def __init__(self, visibility=None, participants=None, display_name=None,
970 | messages=None, message_state=None, message_has_changed=None):
971 | """
972 | A message thread facet is a grouping of characteristics unique to a running commentary of electronic messages
973 | pertaining to one topic or question.
974 | """
975 | super().__init__()
976 | self["@type"] = "uco-observable:MessageThreadFacet"
977 | self._set_properties_str(**{"uco-observable:displayName": display_name})
978 | self._set_properties_bool(**{'uco-observable:visibility': visibility})
979 | self._set_properties_list_id_reference(**{'uco-observable:participant': participants})
980 |
981 | self["uco-observable:messageThread"]=dict()
982 | self["uco-observable:messageThread"]["@id"]= "kb:" + str(uuid4())
983 | self["uco-observable:messageThread"]["@type"] = "uco-types:Thread"
984 | self["uco-observable:messageThread"]["co:size"]= dict()
985 | self["uco-observable:messageThread"]["co:size"]["@type"] = "xsd:nonNegativeInteger"
986 | self["uco-observable:messageThread"]["co:size"]["@value"] = str(len(messages))
987 | self["uco-observable:messageThread"]["co:element"]= list()
988 | for i, m in enumerate(messages):
989 | self["uco-observable:messageThread"]["co:element"].append({"@id":m.get_id()})
990 |
991 | # def append_messages(self, messages):
992 | # self['uco-observable:message'].append_indexed_items(messages)
993 |
994 | # def append_participants(self, participants):
995 | # self._append_refs('uco-observable:participant', *participants)
996 |
997 |
998 | class MessageSMS(ObjectFacet):
999 |
1000 | def __init__(self, has_changed=None, state=None, indexed_items=None):
1001 | """
1002 | A message is a discrete unit of electronic communication intended by the source for consumption by some
1003 | recipient or group of recipients. [based on https://en.wikipedia.org/wiki/Message]
1004 | """
1005 | super().__init__()
1006 | self["@type"] = "uco-observable:Message"
1007 | self._set_properties_str(**{'uco-observable:state': state})
1008 | self._set_properties_bool(**{'uco-observable:hasChanged': has_changed})
1009 | #self.append_indexed_items(indexed_items)
1010 |
1011 |
1012 | class DiskPartition(ObjectFacet):
1013 |
1014 | def __init__(self, serial_number=None, partition_type=None, total_space=None, space_left=None,
1015 | space_used=None, offset=None):
1016 | """
1017 | Used to represent Disk Partition
1018 | :param serial_number: disk partition identifier
1019 | :param partition_type: FAT32, NTFS etc.
1020 | :param total_space: free space
1021 | :param space_left: total - used space
1022 | :param space_used: used space
1023 | :param space_used: the offset to the beginning of the disk
1024 | """
1025 | super().__init__()
1026 | self["@type"] = "uco-observable:DiskPartitionFacet"
1027 | self._set_properties_str(**{"uco-observable:serialNumber": serial_number,
1028 | "uco-observable:diskPartitionType": partition_type})
1029 | self._set_properties_int(**{"uco-observable:totalSpace": total_space,
1030 | "uco-observable:spaceLeft": space_left,
1031 | "uco-observable:spaceUsed": space_used,
1032 | "uco-observable:partitionOffset": offset})
1033 |
1034 |
1035 | class Disk(ObjectFacet):
1036 |
1037 | def __init__(self, disk_type=None, size=None, partition=None):
1038 | """
1039 | Used to represent Fixed Disk
1040 | :param disk_type: Fixed default value
1041 | :param size: disk size
1042 | :param partition: array of @id references to the partitions contained
1043 | """
1044 | super().__init__()
1045 | self["@type"] = "uco-observable:DiskFacet"
1046 | self._set_properties_str(**{"uco-observable:diskType": disk_type})
1047 | self._set_properties_int(**{"uco-observable:diskSize": size})
1048 | self._set_properties_list_id_reference_array(**{"uco-observable:partition": partition})
1049 |
1050 | class CellSite(ObjectFacet):
1051 |
1052 | def __init__(self, country_code=None, network_code=None, area_code=None, site_id=None):
1053 | super().__init__()
1054 | self['@type'] = "uco-observable:CellSiteFacet"
1055 | self._set_properties_str(**{"uco-observable:cellSiteType": "GSM",
1056 | "uco-observable:cellSiteCountryCode": country_code,
1057 | "uco-observable:cellSiteNetworkCode": network_code,
1058 | "uco-observable:cellSiteLocationAreaCode": area_code,
1059 | "uco-observable:cellSiteIdentifier": site_id})
1060 |
1061 | class SocialMediaActivity(ObjectFacet):
1062 |
1063 | def __init__(self, application=None, created_time=None, body=None, page_title=None, url=None, author_id=None,
1064 | author_name=None, reactions_count=None, shares_count=None, activity_type=None, comment_count=None,
1065 | account_id=None):
1066 | """
1067 | :param application: An observable object
1068 | :param created_time:
1069 | :param body:
1070 | :param page_title:
1071 | :param url: An observable object
1072 | :param author_id:
1073 | :param author_name:
1074 | :param reactions_count:
1075 | :param shares_count:
1076 | :param activity_type:
1077 | :param comment_count:
1078 | :param account_id:
1079 | """
1080 | super().__init__()
1081 | self['@type'] = "drafting:SocialMediaActivityFacet"
1082 | self._set_properties_str(**{"uco-observable:body": body,
1083 | "uco-observable:pageTitle": page_title,
1084 | "drafting:authorIdentifier": author_id,
1085 | "drafting:authorName": author_name,
1086 | "drafting:reactionsCount": reactions_count,
1087 | "drafting:sharesCount": shares_count,
1088 | "drafting:activityType": activity_type,
1089 | "drafting:commentCount": comment_count,
1090 | "uco-observable:accountIdentifier": account_id})
1091 | self._set_properties_date_time(
1092 | **{'uco-observable:observableCreatedTime': created_time})
1093 | self._set_properties_id_reference(**{"uco-observable:application": application,
1094 | "uco-observable:url": url})
1095 |
1096 | class SearchedItem(ObjectFacet):
1097 |
1098 | def __init__(self, search_value=None, search_result=None, application=None, search_launch_time=None):
1099 | super().__init__()
1100 | self["@type"] = "drafting:SearchedItemFacet"
1101 | self._set_properties_str(**{"drafting:searchValue": search_value,
1102 | "drafting:searchResult": search_result})
1103 | self._set_properties_date_time(
1104 | **{'drafting:searchLaunchedTime': search_launch_time})
1105 | self._set_properties_id_reference(
1106 | **{'uco-observable:application': application})
1107 |
1108 | class Location(ObjectFacet):
1109 |
1110 | def __init__(self, latitude=None, longitude=None, altitude=None):
1111 | super().__init__()
1112 | self["@type"] = "uco-location:LatLongCoordinatesFacet"
1113 | self._set_properties_float(**{"uco-location:latitude": latitude,
1114 | "uco-location:longitude": longitude,
1115 | 'uco-location:altitude': altitude})
1116 | #self._set_properties_str(**{'drafting:locationType': location_type})
1117 |
1118 | class SimpleName(ObjectFacet):
1119 |
1120 | def __init__(self, given_name=None, family_name=None):
1121 | """
1122 | :param given_name: Full name of the identity of person
1123 | :param family_name: Family name of identity of person
1124 | """
1125 | super().__init__()
1126 | self["@type"] = "uco-identity:SimpleNameFacet"
1127 | self._set_properties_str(**{"uco-identity:givenName": given_name,
1128 | "uco-identity:familyName": family_name})
1129 |
1130 | class Role(ObjectSpecial):
1131 |
1132 | def __init__(self, description=None, _id=None, modified_time=None, name=None, created_time=None, spec_version=None,
1133 | tag=None, _type=None, created_by=None, objet_marking=None):
1134 | """
1135 | A role is a usual or customary function based on contextual perspective.
1136 | :param description: A description of a particular concept characterization.
1137 | :param _id: A globally unique identifier for a characterization of a concept.
1138 | :param modified_time: Specifies the time that this particular version of the object was modified.
1139 | :param name: The name of a particular concept characterization.
1140 | :param created_time: The time at which a characterization of a concept is created.
1141 | :param spec_version: The version of UCO used to characterize a concept.
1142 | :param tag: A generic tag/label.
1143 | :param _type: The explicitly-defined type of characterization of a concept.
1144 | :param created_by: The identity that created a characterization of a concept.
1145 | :param objet_marking: Marking definitions to be applied to a particular concept characterization in its entirety
1146 | """
1147 |
1148 | super().__init__()
1149 | self["@type"] = "uco-role:Role"
1150 | self._set_properties_str(**{"uco-core:description": description,
1151 | "uco-core:name": name,
1152 | "uco-core:specVersion": spec_version,
1153 | "uco-core:tag": tag,
1154 | "uco-core:type": _type})
1155 | self._set_properties_date_time(**{"uco-core:modifiedTime": modified_time,
1156 | "uco-core:objectCreatedTime": created_time})
1157 | self._set_properties_id_reference(**{"uco-core:id": _id,
1158 | "uco-core:createdBy": created_by,
1159 | "uco-core:objectMarking": objet_marking})
1160 |
1161 | class SimpleAdress(ObjectFacet):
1162 |
1163 | def __init__(self, country=None, locality=None, street=None, postal_code=None, region=None, address_type=None):
1164 | super().__init__()
1165 | self["@type"] = "uco-location:SimpleAddressFacet"
1166 | self._set_properties_str(**{"uco-location:adressType": address_type,
1167 | "uco-location:country": country,
1168 | 'uco-location:locality': locality,
1169 | 'uco-location:postalCode': postal_code,
1170 | 'uco-location:region': region,
1171 | 'uco-location:street': street})
1172 |
1173 | class Tool(ObjectSpecial):
1174 |
1175 | def __init__(self, tool_name=None, tool_version=None, tool_type=None, tool_creator=None):
1176 | """
1177 | The Uco tool is a way to define the specfifics of a tool used in an investigation
1178 | :param tool_name: The account_name of the tool (e.g., "exiftool")
1179 | :param tool_creator: The developer and or organisation that produces this tool {might need to add a dict here}
1180 | :param tool_type: The type of tool
1181 | :param tool_version: The version of the tool
1182 | """
1183 | super().__init__()
1184 | self["@type"] = "uco-tool:Tool"
1185 | self._set_properties_str(**{"uco-core:name": tool_name,
1186 | "uco-tool:version": tool_version,
1187 | "uco-tool:toolType": tool_type})
1188 | self._set_properties_id_reference(**{"uco-tool:creator": tool_creator})
1189 |
1190 | class InvestigativeAction(ObjectSpecial):
1191 |
1192 | def __init__(self, name=None, description=None, start_time=None, end_time=None,
1193 | performer=None, instrument=None, location=None, environment=None, results=None, objects=None):
1194 | """
1195 | An investigative action is a CASE object that represents the who, when, what outcome of an action
1196 | :param name: The account_name of the action (e.g., "annotated")
1197 | :param start_time: The time, in ISO8601 time format, the action was started (e.g., "2020-09-29T12:13:01Z")
1198 | :param end_time: The time, in ISO8601 time format, the action completed (e.g., "2020-09-29T12:13:43Z")
1199 | """
1200 | super().__init__()
1201 | self["@type"] = "case-investigation:InvestigativeAction"
1202 | self._set_properties_str(**{"uco-core:name": name,
1203 | 'uco-core:description': description,
1204 | "uco-action:environment": environment})
1205 | self._set_properties_date_time(**{"uco-action:startTime": start_time,
1206 | "uco-action:endTime": end_time})
1207 | self._set_properties_id_reference(**{"uco-action:performer": performer,
1208 | "uco-action:instrument": instrument,
1209 | "uco-action:location": location})
1210 | self._set_properties_list_id_reference(**{"uco-action:result": results})
1211 | self._set_properties_list_id_reference_array(**{"uco-action:object": objects})
1212 |
1213 |
1214 | class ActionReferences(ObjectFacet):
1215 |
1216 | def __init__(self, performer=None, instrument=None, location=None, environment=None, results=None, objects=None):
1217 | """
1218 | An action reference contains the details of an InvestigativeAction.
1219 | It groups the properties characterizing the core elements (who, how, with what, where, etc.) for actions.
1220 | The properties consist of identifier references to separate UCO objects detailing the particular property.
1221 | :param performer: The account_name or id of the person conducting the action
1222 | :param instrument: The tool used to conduct the action
1223 | :param location: The general location where the action took place (Room, Building or Town)
1224 | :param environment: The type of environment (lab, office)
1225 | :param results: A list of resulting output identifiers
1226 | """
1227 | super().__init__()
1228 | self["@type"] = "uco-action:ActionReferencesFacet"
1229 | self._set_properties_str(**{"uco-action:environment": environment})
1230 | self._set_properties_id_reference(**{"uco-action:performer": performer,
1231 | "uco-action:instrument": instrument,
1232 | "uco-action:location": location})
1233 | self._set_properties_list_id_reference(**{"uco-action:result": results})
1234 | self._set_properties_list_id_reference_array(**{"uco-action:object": objects})
1235 |
1236 | def append_results(self, *args):
1237 | """
1238 | Add result(s) to the list of outputs from an action
1239 | :param args: A CASE object, or objects, often an observable. (e.g., one or many devices from a search operation)
1240 | """
1241 | self._set_properties_list_id_reference("uco-action:result", *args)
1242 |
1243 | def append_objects(self, *args):
1244 | """
1245 | Add object(s) to the list of outputs from an action
1246 | :param args: A CASE object, or objects, often an observable. (e.g., one or many devices from a search operation)
1247 | """
1248 | self._set_properties_list_id_reference("uco-action:object", *args)
1249 |
1250 |
--------------------------------------------------------------------------------