mirror of
https://github.com/MISP/misp-galaxy.git
synced 2024-11-26 08:47:18 +00:00
Add [config] optional "private" relations
This commit is contained in:
parent
9d2dfba0b9
commit
9467e101bf
3 changed files with 38 additions and 8 deletions
|
@ -42,7 +42,7 @@ The configuration file is located in `config.json` and maps the fields of the Ti
|
|||
>Note: The fields `meta` can be formatted as the format of the data the API provides sometimes does not match the format defined by the [MISP galaxy format](https://www.misp-standard.org/rfc/misp-standard-galaxy-format.html#name-conventions-and-terminology). You can configure this using an extraction configuration.
|
||||
|
||||
### Extraction Configuration
|
||||
The extraction configuration is a dictionary that maps the fields of the Tidal Cyber API to the fields of the MISP galaxy. It can be used to extract data stored in a array or object in the API response. The extraction configuration looks like this:
|
||||
The extraction configuration is a dictionary that maps the fields of the Tidal Cyber API to the fields of the MISP galaxy. It can be used to extract data stored in an object in the API response. The extraction configuration looks like this:
|
||||
```json
|
||||
{
|
||||
"extract": "<mode>",
|
||||
|
@ -56,6 +56,23 @@ The extraction configuration is a dictionary that maps the fields of the Tidal C
|
|||
- `multiple`: Extracts multiple values from the API response
|
||||
- `reverse`: Gets the value of the key and writes it into an array (no subkey needed)
|
||||
|
||||
### "Private" Relations
|
||||
The Tidal Cyber API provides relations between different objects. Some of these relations point to objects that are not part of the galaxies created based on the API response nor are they part of the MISP galaxy. These relations can be marked as `private` in the config file. For example:
|
||||
```json
|
||||
"related": {
|
||||
"tactic": {
|
||||
"mode": "public",
|
||||
"dest-uuid": "tactic_id",
|
||||
"type": "uses"
|
||||
},
|
||||
"sub_technique": {
|
||||
"mode": "private",
|
||||
"dest-uuid": "id",
|
||||
"type": "sub-technique-of"
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
## Usage
|
||||
```bash
|
||||
python3 main.py create-galaxy -v <version> --type <galaxy_to_create>
|
||||
|
|
|
@ -134,10 +134,12 @@
|
|||
},
|
||||
"related": {
|
||||
"groups": {
|
||||
"mode": "private",
|
||||
"dest-uuid": "group_id",
|
||||
"type": "used-by"
|
||||
},
|
||||
"associated_software": {
|
||||
"mode": "private",
|
||||
"dest-uuid": "id",
|
||||
"type": "related-to"
|
||||
}
|
||||
|
@ -175,6 +177,7 @@
|
|||
},
|
||||
"related": {
|
||||
"associated_groups": {
|
||||
"mode": "private",
|
||||
"dest-uuid": "id",
|
||||
"type": "related-to"
|
||||
}
|
||||
|
@ -214,10 +217,12 @@
|
|||
},
|
||||
"related": {
|
||||
"tactic": {
|
||||
"mode": "public",
|
||||
"dest-uuid": "tactic_id",
|
||||
"type": "uses"
|
||||
},
|
||||
"sub_technique": {
|
||||
"mode": "private",
|
||||
"dest-uuid": "id",
|
||||
"type": "sub-technique-of"
|
||||
}
|
||||
|
@ -236,6 +241,7 @@
|
|||
},
|
||||
"related": {
|
||||
"techniques": {
|
||||
"mode": "public",
|
||||
"dest-uuid": "technique_id",
|
||||
"type": "uses"
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ CLUSTER_CONFIGS = config["CLUSTER_CONFIGS"]
|
|||
VALUE_FIELDS = config["VALUE_FIELDS"]
|
||||
|
||||
|
||||
def create_cluster_values(data, cluster):
|
||||
def create_cluster_values(data, cluster, add_private):
|
||||
value_fields = VALUE_FIELDS[cluster.internal_type]
|
||||
for entry in data["data"]:
|
||||
values = {}
|
||||
|
@ -28,7 +28,7 @@ def create_cluster_values(data, cluster):
|
|||
metadata = create_metadata(entry, value)
|
||||
values["meta"] = metadata
|
||||
case "related":
|
||||
relations = create_relations(entry, value)
|
||||
relations = create_relations(entry, value, add_private)
|
||||
values["related"] = relations
|
||||
case "uuid":
|
||||
values[key] = entry.get(value)
|
||||
|
@ -63,13 +63,17 @@ def create_metadata(data, format):
|
|||
return metadata
|
||||
|
||||
|
||||
def create_relations(data, format):
|
||||
def create_relations(data, format, add_private):
|
||||
relations = []
|
||||
for i in range(len(list(format))):
|
||||
for relation in data[list(format)[i]]:
|
||||
if not add_private and list(format.values())[i].get("mode") == "private":
|
||||
continue
|
||||
relation_entry = {}
|
||||
for relation_key, relation_value in list(format.values())[i].items():
|
||||
if relation_key != "type":
|
||||
if relation_key == "mode":
|
||||
continue
|
||||
relation_entry[relation_key] = relation.get(relation_value)
|
||||
else:
|
||||
relation_entry[relation_key] = relation_value
|
||||
|
@ -77,14 +81,14 @@ def create_relations(data, format):
|
|||
return relations
|
||||
|
||||
|
||||
def create_galaxy_and_cluster(galaxy_type, version):
|
||||
def create_galaxy_and_cluster(galaxy_type, version, add_private=False):
|
||||
api = TidalAPI()
|
||||
galaxy = Galaxy(**GALAXY_CONFIGS[galaxy_type], version=version)
|
||||
galaxy.save_to_file(f"{GALAXY_PATH}/tidal-{galaxy_type}.json")
|
||||
|
||||
cluster = Cluster(**CLUSTER_CONFIGS[galaxy_type], internal_type=galaxy_type)
|
||||
data = api.get_data(galaxy_type)
|
||||
create_cluster_values(data, cluster)
|
||||
create_cluster_values(data, cluster, add_private)
|
||||
cluster.save_to_file(f"{CLUSTER_PATH}/tidal-{galaxy_type}.json")
|
||||
|
||||
print(f"Galaxy tidal-{galaxy_type} created")
|
||||
|
@ -93,9 +97,9 @@ def create_galaxy_and_cluster(galaxy_type, version):
|
|||
def create_galaxy(args):
|
||||
if args.all:
|
||||
for galaxy_type in GALAXY_CONFIGS:
|
||||
create_galaxy_and_cluster(galaxy_type, args.version)
|
||||
create_galaxy_and_cluster(galaxy_type, args.version, args.addprivate)
|
||||
else:
|
||||
create_galaxy_and_cluster(args.type, args.version)
|
||||
create_galaxy_and_cluster(args.type, args.version, args.addprivate)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -118,6 +122,9 @@ if __name__ == "__main__":
|
|||
galaxy_parser.add_argument(
|
||||
"--all", action="store_true", help="Flag to create all predefined galaxy types"
|
||||
)
|
||||
galaxy_parser.add_argument(
|
||||
"--addprivate", action="store_true", help="Flag to add private relations"
|
||||
)
|
||||
galaxy_parser.set_defaults(func=create_galaxy)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
|
Loading…
Reference in a new issue