assemblyline 4.6.1.dev166__tar.gz → 4.7.0.dev7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {assemblyline-4.6.1.dev166/assemblyline.egg-info → assemblyline-4.7.0.dev7}/PKG-INFO +2 -2
- assemblyline-4.7.0.dev7/assemblyline/VERSION +1 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/bundling.py +23 -6
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/classification.py +5 -3
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/dict_utils.py +2 -1
- assemblyline-4.7.0.dev7/assemblyline/common/dispatcher.py +39 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/log.py +2 -2
- assemblyline-4.7.0.dev7/assemblyline/common/version.py +20 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/datastore/collection.py +29 -14
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/datastore/helper.py +32 -5
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/filestore/__init__.py +3 -2
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/filestore/transport/azure.py +14 -12
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/submission.py +16 -9
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/alert.py +28 -17
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/config.py +23 -28
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/file.py +17 -17
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/result.py +61 -60
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/retrohunt.py +1 -1
- assemblyline-4.7.0.dev7/assemblyline/odm/models/signature.py +29 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/submission.py +58 -58
- assemblyline-4.7.0.dev7/assemblyline/odm/models/tagging.py +1563 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/user.py +2 -13
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/user_settings.py +2 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/random_data/__init__.py +3 -1
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/run/cli.py +3 -20
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7/assemblyline.egg-info}/PKG-INFO +2 -2
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline.egg-info/SOURCES.txt +1 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/setup.py +1 -1
- assemblyline-4.6.1.dev166/assemblyline/VERSION +0 -1
- assemblyline-4.6.1.dev166/assemblyline/common/version.py +0 -3
- assemblyline-4.6.1.dev166/assemblyline/odm/models/signature.py +0 -28
- assemblyline-4.6.1.dev166/assemblyline/odm/models/tagging.py +0 -498
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/LICENCE.md +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/MANIFEST.in +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/README.md +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/cachestore/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/archiving.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/attack_map.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/backupmanager.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/banner.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/caching.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/chunk.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/classification.yml +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/cleanup_filestore.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/codec.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/comms.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/constants.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/custom.magic +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/custom.yara +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/digests.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/entropy.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/exceptions.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/file.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/forge.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/frequency.pyx +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/heuristics.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/hexdump.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/identify.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/identify_defaults.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/importing.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/iprange.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/isotime.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/logformat.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/lucene.lark +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/memory_zip.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/metrics.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/net.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/net_static.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/null.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/path.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/postprocess.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/random_user.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/security.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/signaturing.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/str_utils.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/tag_safelist.yml +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/tagging.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/threading.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/common/uid.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/datasource/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/datasource/al.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/datasource/alert.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/datasource/common.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/datastore/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/datastore/bulk.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/datastore/exceptions.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/datastore/store.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/datastore/support/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/datastore/support/build.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/datastore/support/schemas.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/filestore/transport/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/filestore/transport/base.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/filestore/transport/ftp.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/filestore/transport/http.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/filestore/transport/local.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/filestore/transport/s3.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/filestore/transport/sftp.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/base.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/common.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/alert.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/alerter_heartbeat.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/archive_heartbeat.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/changes.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/dispatcher_heartbeat.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/dispatching.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/elastic_heartbeat.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/expiry_heartbeat.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/ingest_heartbeat.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/metrics.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/retrohunt_heartbeat.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/scaler_heartbeat.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/scaler_status_heartbeat.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/service_heartbeat.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/service_timing_heartbeat.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/task.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/vacuum_heartbeat.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/actions.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/apikey.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/badlist.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/cached_file.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/emptyresult.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/error.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/filescore.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/heuristic.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/ontology/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/ontology/file.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/ontology/filetypes/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/ontology/filetypes/pe.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/ontology/ontology.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/ontology/results/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/ontology/results/antivirus.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/ontology/results/http.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/ontology/results/malware_config.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/ontology/results/network.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/ontology/results/process.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/ontology/results/sandbox.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/ontology/results/signature.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/replay.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/safelist.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/service.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/service_delta.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/statistics.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/submission_summary.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/submission_tree.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/user_favorites.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/models/workflow.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/random_data/create_test_data.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/random_data/sample_rules.yar +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/random_data/sample_suricata.rules +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/randomizer.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/py.typed +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/cache.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/counters.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/daily_quota_tracker.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/events.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/exporting_counter.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/hash.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/lock.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/queues/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/queues/comms.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/queues/multi.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/queues/named.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/queues/priority.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/set.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/remote/datatypes/user_quota_tracker.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/run/__init__.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/run/pubsub_reader.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/run/suricata_importer.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/run/yara_importer.py +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline.egg-info/dependency_links.txt +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline.egg-info/entry_points.txt +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline.egg-info/requires.txt +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline.egg-info/top_level.txt +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/pyproject.toml +0 -0
- {assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: assemblyline
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.7.0.dev7
|
|
4
4
|
Summary: Assemblyline 4 - Automated malware analysis framework
|
|
5
5
|
Home-page: https://github.com/CybercentreCanada/assemblyline-base
|
|
6
6
|
Author: CCCS Assemblyline development team
|
|
@@ -11,10 +11,10 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: Topic :: Software Development :: Libraries
|
|
13
13
|
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENCE.md
|
|
20
20
|
Requires-Dist: arrow
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4.7.0.dev7
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import json
|
|
3
2
|
import logging
|
|
4
3
|
import os
|
|
@@ -206,7 +205,7 @@ def create_bundle(sid, working_dir=WORK_DIR, use_alert=False, user_classificatio
|
|
|
206
205
|
submission['metadata']['bundle.classification'] = submission['classification']
|
|
207
206
|
|
|
208
207
|
results, supplementary = get_results(submission.get("results", []), file_infos, datastore,
|
|
209
|
-
|
|
208
|
+
user_classification)
|
|
210
209
|
supp_info, _ = get_file_infos(copy(supplementary), datastore)
|
|
211
210
|
file_infos.update(supp_info)
|
|
212
211
|
|
|
@@ -258,8 +257,18 @@ def create_bundle(sid, working_dir=WORK_DIR, use_alert=False, user_classificatio
|
|
|
258
257
|
|
|
259
258
|
|
|
260
259
|
# noinspection PyBroadException,PyProtectedMember
|
|
261
|
-
def import_bundle(
|
|
262
|
-
|
|
260
|
+
def import_bundle(
|
|
261
|
+
path,
|
|
262
|
+
working_dir=WORK_DIR,
|
|
263
|
+
min_classification=Classification.UNRESTRICTED,
|
|
264
|
+
allow_incomplete=False,
|
|
265
|
+
rescan_services=None,
|
|
266
|
+
exist_ok=False,
|
|
267
|
+
cleanup=True,
|
|
268
|
+
identify=None,
|
|
269
|
+
reclassification=None,
|
|
270
|
+
to_ingest=False,
|
|
271
|
+
):
|
|
263
272
|
with forge.get_datastore(archive_access=True) as datastore:
|
|
264
273
|
current_working_dir = os.path.join(working_dir, get_random_id())
|
|
265
274
|
res_file = os.path.join(current_working_dir, "results.json")
|
|
@@ -382,8 +391,16 @@ def import_bundle(path, working_dir=WORK_DIR, min_classification=Classification.
|
|
|
382
391
|
}
|
|
383
392
|
with SubmissionClient(datastore=datastore, filestore=filestore,
|
|
384
393
|
config=config, identify=identify) as sc:
|
|
385
|
-
|
|
386
|
-
|
|
394
|
+
|
|
395
|
+
sc.rescan(
|
|
396
|
+
submission,
|
|
397
|
+
results["results"],
|
|
398
|
+
extracted_file_infos,
|
|
399
|
+
files["tree"],
|
|
400
|
+
list(errors["errors"].keys()),
|
|
401
|
+
rescan_services,
|
|
402
|
+
to_ingest=to_ingest,
|
|
403
|
+
)
|
|
387
404
|
elif not exist_ok:
|
|
388
405
|
raise SubmissionAlreadyExist("Submission %s already exists." % sid)
|
|
389
406
|
|
|
@@ -342,9 +342,11 @@ class Classification(object):
|
|
|
342
342
|
|
|
343
343
|
# Swap to long format if required
|
|
344
344
|
if long_format:
|
|
345
|
-
return
|
|
346
|
-
[self.groups_map_stl.get(r, r) for r in g1_set]),
|
|
347
|
-
[self.subgroups_map_stl[r] for r in g2_set]),
|
|
345
|
+
return (
|
|
346
|
+
sorted([self.groups_map_stl.get(r, r) for r in g1_set]),
|
|
347
|
+
sorted([self.subgroups_map_stl[r] for r in g2_set]),
|
|
348
|
+
list(others)
|
|
349
|
+
)
|
|
348
350
|
return sorted(list(g1_set)), sorted(list(g2_set)), list(others)
|
|
349
351
|
|
|
350
352
|
@staticmethod
|
|
@@ -11,7 +11,8 @@ def strip_nulls(d):
|
|
|
11
11
|
for k, v in list(d.items()):
|
|
12
12
|
v = strip_nulls(v) if v is not None else None
|
|
13
13
|
# Assess if stripped value is null, if not then add it to the new dictionary returned
|
|
14
|
-
|
|
14
|
+
# allow empty value
|
|
15
|
+
if v is not None:
|
|
15
16
|
new_dict[k] = v
|
|
16
17
|
return new_dict
|
|
17
18
|
elif isinstance(d, list):
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from redis import Redis
|
|
2
|
+
|
|
3
|
+
from assemblyline.remote.datatypes.hash import Hash
|
|
4
|
+
from assemblyline.remote.datatypes.queues.named import NamedQueue
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
DISPATCH_TASK_ASSIGNMENT = 'dispatcher-tasks-assigned-to-'
|
|
8
|
+
TASK_ASSIGNMENT_PATTERN = DISPATCH_TASK_ASSIGNMENT + '*'
|
|
9
|
+
DISPATCH_START_EVENTS = 'dispatcher-start-events-'
|
|
10
|
+
DISPATCH_RESULT_QUEUE = 'dispatcher-results-'
|
|
11
|
+
DISPATCH_COMMAND_QUEUE = 'dispatcher-commands-'
|
|
12
|
+
DISPATCH_DIRECTORY = 'dispatchers-directory'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Dispatcher:
|
|
16
|
+
"""A utility class for fetching information about the dispatchers running in the system."""
|
|
17
|
+
@staticmethod
|
|
18
|
+
def all_instances(persistent_redis: Redis) -> list[str]:
|
|
19
|
+
"""List all dispatchers who have created a listing for themselves."""
|
|
20
|
+
return Hash(DISPATCH_DIRECTORY, host=persistent_redis).keys()
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def instance_assignment_size(persistent_redis: Redis, instance_id: str):
|
|
24
|
+
"""Get the number of submissions assigned to a given dispatcher instance."""
|
|
25
|
+
return Hash(DISPATCH_TASK_ASSIGNMENT + instance_id, host=persistent_redis).length()
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def instance_assignment(persistent_redis: Redis, instance_id: str) -> list[str]:
|
|
29
|
+
"""List the submissions assigned to a given dispatcher instance."""
|
|
30
|
+
return Hash(DISPATCH_TASK_ASSIGNMENT + instance_id, host=persistent_redis).keys()
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def all_queue_lengths(redis: Redis, instance_id: str):
|
|
34
|
+
"""Get the queue lengths for a given dispatcher instance."""
|
|
35
|
+
return {
|
|
36
|
+
'start': NamedQueue(DISPATCH_START_EVENTS + instance_id, host=redis).length(),
|
|
37
|
+
'result': NamedQueue(DISPATCH_RESULT_QUEUE + instance_id, host=redis).length(),
|
|
38
|
+
'command': NamedQueue(DISPATCH_COMMAND_QUEUE + instance_id, host=redis).length()
|
|
39
|
+
}
|
|
@@ -3,7 +3,7 @@ import logging.config
|
|
|
3
3
|
import logging.handlers
|
|
4
4
|
|
|
5
5
|
from traceback import format_exception
|
|
6
|
-
from typing import Optional
|
|
6
|
+
from typing import Optional, Union
|
|
7
7
|
|
|
8
8
|
import json
|
|
9
9
|
import os
|
|
@@ -65,7 +65,7 @@ class JsonFormatter(logging.Formatter):
|
|
|
65
65
|
return ''.join(format_exception(*exc_info))
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
def init_logging(name: str, config: Config = None, log_level: Optional[str] = None):
|
|
68
|
+
def init_logging(name: str, config: Config = None, log_level: Optional[Union[str, int]] = None):
|
|
69
69
|
logger = logging.getLogger('assemblyline')
|
|
70
70
|
|
|
71
71
|
# If the environment has a log level override, use it.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Try to find the version of the code base that is running or assume an arbitrary one for testing.
|
|
3
|
+
"""
|
|
4
|
+
import os
|
|
5
|
+
import re
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
ASSEMBLYLINE_VERSION = os.environ.get('ASSEMBLYLINE_VERSION', "4.0.0.dev0")
|
|
9
|
+
|
|
10
|
+
PATTERN = r'v?(?P<framework>[0-9]+)\.(?P<system>[0-9]+)\.(?P<minor>[0-9]+)\.(?P<channel>dev|stable)?(?P<build>[0-9]+)'
|
|
11
|
+
|
|
12
|
+
matching = re.match(PATTERN, ASSEMBLYLINE_VERSION, re.IGNORECASE)
|
|
13
|
+
if matching:
|
|
14
|
+
groups = matching.groupdict()
|
|
15
|
+
else:
|
|
16
|
+
raise EnvironmentError("Could not process the ASSEMBLYLINE_VERSION variable to extract a release version.")
|
|
17
|
+
|
|
18
|
+
FRAMEWORK_VERSION = int(groups['framework'])
|
|
19
|
+
SYSTEM_VERSION = int(groups['system'])
|
|
20
|
+
BUILD_MINOR = int(groups['minor'])
|
|
@@ -7,29 +7,45 @@ import re
|
|
|
7
7
|
import time
|
|
8
8
|
import typing
|
|
9
9
|
import warnings
|
|
10
|
-
|
|
10
|
+
from copy import deepcopy
|
|
11
11
|
from datetime import datetime
|
|
12
12
|
from enum import Enum
|
|
13
13
|
from os import environ
|
|
14
|
-
from typing import Dict,
|
|
15
|
-
from copy import deepcopy
|
|
14
|
+
from typing import Any, Dict, Generic, Optional, TypeVar, Union
|
|
16
15
|
|
|
17
|
-
from datemath import dm
|
|
18
|
-
from datemath.helpers import DateMathException
|
|
19
16
|
import elasticsearch
|
|
20
17
|
import elasticsearch.helpers
|
|
18
|
+
from datemath import dm
|
|
19
|
+
from datemath.helpers import DateMathException
|
|
21
20
|
|
|
22
21
|
from assemblyline import odm
|
|
23
|
-
from assemblyline.common.isotime import now_as_iso
|
|
24
22
|
from assemblyline.common.dict_utils import recursive_update
|
|
23
|
+
from assemblyline.common.isotime import now_as_iso
|
|
25
24
|
from assemblyline.datastore.bulk import ElasticBulkPlan
|
|
26
25
|
from assemblyline.datastore.exceptions import (
|
|
27
|
-
|
|
26
|
+
ArchiveDisabled,
|
|
27
|
+
DataStoreException,
|
|
28
|
+
MultiKeyError,
|
|
29
|
+
SearchException,
|
|
30
|
+
VersionConflictException,
|
|
31
|
+
)
|
|
28
32
|
from assemblyline.datastore.support.build import back_mapping, build_mapping
|
|
29
|
-
from assemblyline.datastore.support.schemas import (
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
from assemblyline.datastore.support.schemas import (
|
|
34
|
+
default_dynamic_strings,
|
|
35
|
+
default_dynamic_templates,
|
|
36
|
+
default_index,
|
|
37
|
+
default_mapping,
|
|
38
|
+
)
|
|
39
|
+
from assemblyline.odm.base import (
|
|
40
|
+
BANNED_FIELDS,
|
|
41
|
+
ClassificationObject,
|
|
42
|
+
Integer,
|
|
43
|
+
Keyword,
|
|
44
|
+
List,
|
|
45
|
+
Mapping,
|
|
46
|
+
Model,
|
|
47
|
+
_Field,
|
|
48
|
+
)
|
|
33
49
|
|
|
34
50
|
if typing.TYPE_CHECKING:
|
|
35
51
|
from .store import ESStore
|
|
@@ -737,7 +753,6 @@ class ESCollection(Generic[ModelType]):
|
|
|
737
753
|
# copy backup to replace deleted index
|
|
738
754
|
self._safe_index_copy(self.datastore.client.indices.clone, backup_index, index,
|
|
739
755
|
settings=self._get_index_settings(archive=archive))
|
|
740
|
-
|
|
741
756
|
finally:
|
|
742
757
|
# Unblock write to the index
|
|
743
758
|
self.with_retries(self.datastore.client.indices.put_settings,
|
|
@@ -1055,7 +1070,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
1055
1070
|
:return: True if the document was saved properly
|
|
1056
1071
|
"""
|
|
1057
1072
|
if " " in key:
|
|
1058
|
-
raise DataStoreException(
|
|
1073
|
+
raise DataStoreException(f'You are not allowed to use spaces in datastore keys: "{key}"')
|
|
1059
1074
|
|
|
1060
1075
|
data = self.normalize(data)
|
|
1061
1076
|
|
|
@@ -2115,7 +2130,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
2115
2130
|
matching = set(fields.keys()) & set(model.keys())
|
|
2116
2131
|
for field_name in matching:
|
|
2117
2132
|
if fields[field_name]['indexed'] != model[field_name].index and model[field_name].index:
|
|
2118
|
-
log.warning("Field %s should be indexed but is not.", field_name)
|
|
2133
|
+
log.warning("Field %s of '%s' index should be indexed but is not.", field_name, self.name)
|
|
2119
2134
|
|
|
2120
2135
|
possible_field_types = self.__get_possible_fields(model[field_name].__class__)
|
|
2121
2136
|
|
|
@@ -48,8 +48,19 @@ config = forge.get_config()
|
|
|
48
48
|
|
|
49
49
|
THREAD_POOL_SIZE = int(os.environ.get("POOL_SIZE", 20))
|
|
50
50
|
|
|
51
|
-
JSON_SECTIONS = [
|
|
52
|
-
|
|
51
|
+
JSON_SECTIONS = [
|
|
52
|
+
"GRAPH_DATA",
|
|
53
|
+
"IMAGE",
|
|
54
|
+
"JSON",
|
|
55
|
+
"KEY_VALUE",
|
|
56
|
+
"MULTI",
|
|
57
|
+
"ORDERED_KEY_VALUE",
|
|
58
|
+
"PROCESS_TREE",
|
|
59
|
+
"SANDBOX",
|
|
60
|
+
"TABLE",
|
|
61
|
+
"TIMELINE"
|
|
62
|
+
"URL",
|
|
63
|
+
]
|
|
53
64
|
|
|
54
65
|
|
|
55
66
|
class AssemblylineDatastore(object):
|
|
@@ -1166,9 +1177,25 @@ class AssemblylineDatastore(object):
|
|
|
1166
1177
|
as_obj=False, as_dictionary=False)]
|
|
1167
1178
|
|
|
1168
1179
|
# Recursively update the service data with the service delta while stripping nulls
|
|
1169
|
-
services = [
|
|
1170
|
-
|
|
1171
|
-
|
|
1180
|
+
services = []
|
|
1181
|
+
for data, delta in zip(service_data, service_delta):
|
|
1182
|
+
data = data.as_primitives(strip_null=True)
|
|
1183
|
+
delta = delta.as_primitives(strip_null=True)
|
|
1184
|
+
service = recursive_update(data, delta, stop_keys=['config'])
|
|
1185
|
+
|
|
1186
|
+
# Check if there's any configurations that were removed in the delta based on the current version of the service
|
|
1187
|
+
for key in list(service.get('config', {}).keys()):
|
|
1188
|
+
if key not in data.get('config', {}):
|
|
1189
|
+
service['config'].pop(key, None)
|
|
1190
|
+
|
|
1191
|
+
# Check for any submission parameters that aren't applicable to the current version of the service
|
|
1192
|
+
if data.get('submission_params'):
|
|
1193
|
+
current_params = [param['name'] for param in data['submission_params']]
|
|
1194
|
+
for param in list(service.get('submission_params', [])):
|
|
1195
|
+
if param['name'] not in current_params:
|
|
1196
|
+
service['submission_params'].remove(param)
|
|
1197
|
+
|
|
1198
|
+
services.append(service)
|
|
1172
1199
|
|
|
1173
1200
|
# Return as an objet if needs be...
|
|
1174
1201
|
if as_obj:
|
|
@@ -77,7 +77,8 @@ def create_transport(url, connection_attempts=None):
|
|
|
77
77
|
sftp: private_key (string), private_key_pass (string), validate_host (bool)
|
|
78
78
|
s3: aws_region (string), s3_bucket (string), use_ssl (bool), verify (bool)
|
|
79
79
|
file: normalize (bool)
|
|
80
|
-
azure: access_key (string), tenant_id (string), client_id (string), client_secret (string),
|
|
80
|
+
azure: access_key (string), tenant_id (string), client_id (string), client_secret (string),
|
|
81
|
+
allow_directory_access (bool), use_default_credentials (bool), initalize_container (bool)
|
|
81
82
|
|
|
82
83
|
"""
|
|
83
84
|
|
|
@@ -137,7 +138,7 @@ def create_transport(url, connection_attempts=None):
|
|
|
137
138
|
|
|
138
139
|
elif scheme == 'azure':
|
|
139
140
|
valid_str_keys = ['access_key', 'tenant_id', 'client_id', 'client_secret']
|
|
140
|
-
valid_bool_keys = ['allow_directory_access', 'use_default_credentials']
|
|
141
|
+
valid_bool_keys = ['allow_directory_access', 'use_default_credentials', 'initalize_container']
|
|
141
142
|
extras = _get_extras(parse_qs(parsed.query), valid_str_keys=valid_str_keys, valid_bool_keys=valid_bool_keys)
|
|
142
143
|
|
|
143
144
|
t = TransportAzure(base=base, host=host, connection_attempts=connection_attempts, **extras)
|
{assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/filestore/transport/azure.py
RENAMED
|
@@ -29,7 +29,8 @@ This class assumes a flat file structure in the Azure storage blob.
|
|
|
29
29
|
class TransportAzure(Transport):
|
|
30
30
|
|
|
31
31
|
def __init__(self, base=None, access_key=None, tenant_id=None, client_id=None, client_secret=None,
|
|
32
|
-
|
|
32
|
+
host=None, connection_attempts=None, allow_directory_access=False, use_default_credentials=False,
|
|
33
|
+
initalize_container=True):
|
|
33
34
|
self.log = logging.getLogger('assemblyline.transport.azure')
|
|
34
35
|
self.read_only = False
|
|
35
36
|
self.connection_attempts: Optional[int] = connection_attempts
|
|
@@ -69,18 +70,19 @@ class TransportAzure(Transport):
|
|
|
69
70
|
self.container_client = self.service_client.get_container_client(self.blob_container)
|
|
70
71
|
|
|
71
72
|
# Init
|
|
72
|
-
|
|
73
|
-
self.with_retries(self.container_client.get_container_properties)
|
|
74
|
-
except TransportException as e:
|
|
75
|
-
if not isinstance(e.cause, ResourceNotFoundError):
|
|
76
|
-
raise
|
|
73
|
+
if initalize_container:
|
|
77
74
|
try:
|
|
78
|
-
self.with_retries(self.container_client.
|
|
79
|
-
except TransportException as
|
|
80
|
-
if not isinstance(
|
|
75
|
+
self.with_retries(self.container_client.get_container_properties)
|
|
76
|
+
except TransportException as e:
|
|
77
|
+
if not isinstance(e.cause, ResourceNotFoundError):
|
|
81
78
|
raise
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
try:
|
|
80
|
+
self.with_retries(self.container_client.create_container)
|
|
81
|
+
except TransportException as error:
|
|
82
|
+
if not isinstance(error.cause, ResourceNotFoundError):
|
|
83
|
+
raise
|
|
84
|
+
self.log.info('Failed to create container, we\'re most likely in read only mode')
|
|
85
|
+
self.read_only = True
|
|
84
86
|
|
|
85
87
|
def azure_normalize(path):
|
|
86
88
|
# flatten path to just the basename
|
|
@@ -115,7 +117,7 @@ class TransportAzure(Transport):
|
|
|
115
117
|
raise
|
|
116
118
|
|
|
117
119
|
except Exception as e:
|
|
118
|
-
self.log.warning(f"No connection to Azure transport "
|
|
120
|
+
self.log.warning(f"Could not run {func}, No connection to Azure transport "
|
|
119
121
|
f"{os.path.join(self.endpoint_url, self.blob_container)}, retrying... "
|
|
120
122
|
f"[{e.__class__.__name__}: {str(e)}]")
|
|
121
123
|
time.sleep(0.25)
|
{assemblyline-4.6.1.dev166 → assemblyline-4.7.0.dev7}/assemblyline/odm/messages/submission.py
RENAMED
|
@@ -21,6 +21,10 @@ class Submission(odm.Model):
|
|
|
21
21
|
notification: Notification = odm.Compound(Notification, default={}, description="Notification queue parameters")
|
|
22
22
|
params: SubmissionParams = odm.Compound(SubmissionParams, description="Parameters of the submission")
|
|
23
23
|
scan_key: Opt[str] = odm.Optional(odm.Keyword())
|
|
24
|
+
file_tree = odm.Any(default={}, description="File tree of the files in this submission")
|
|
25
|
+
file_infos = odm.Mapping(odm.Any(), default={}, description="SHA256 and file information in the file.")
|
|
26
|
+
errors = odm.List(odm.Keyword(), default=[], description="List of error keys")
|
|
27
|
+
results = odm.Mapping(odm.Any(), default={}, description="Result key value mapping")
|
|
24
28
|
|
|
25
29
|
|
|
26
30
|
def from_datastore_submission(submission: DatabaseSubmission):
|
|
@@ -28,19 +32,22 @@ def from_datastore_submission(submission: DatabaseSubmission):
|
|
|
28
32
|
A helper to convert between database model version of Submission
|
|
29
33
|
and the message version of Submission.
|
|
30
34
|
"""
|
|
31
|
-
return Submission(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
return Submission(
|
|
36
|
+
{
|
|
37
|
+
"sid": submission.sid,
|
|
38
|
+
"files": submission.files,
|
|
39
|
+
"metadata": submission.metadata,
|
|
40
|
+
"params": submission.params,
|
|
41
|
+
"scan_key": submission.scan_key,
|
|
42
|
+
}
|
|
43
|
+
)
|
|
38
44
|
|
|
39
45
|
|
|
40
46
|
@odm.model(description="Model of Submission Message")
|
|
41
47
|
class SubmissionMessage(odm.Model):
|
|
42
48
|
msg = odm.Compound(Submission, description="Body of the message")
|
|
43
|
-
msg_loader = odm.Enum(
|
|
44
|
-
|
|
49
|
+
msg_loader = odm.Enum(
|
|
50
|
+
values={LOADER_CLASS}, default=LOADER_CLASS, description="Class to use to load the message as an object"
|
|
51
|
+
) #
|
|
45
52
|
msg_type = odm.Enum(values=MSG_TYPES, description="Type of message")
|
|
46
53
|
sender = odm.Keyword(description="Sender of the message")
|
|
@@ -21,14 +21,25 @@ def merge_extended_scan(a: str, b: str) -> str:
|
|
|
21
21
|
raise ValueError(f"Invalid program state. scan state {a} {b}")
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
DetailedItemSubtype = odm.Enum(
|
|
25
|
+
[
|
|
26
|
+
'CFG', # Configuration blocks
|
|
27
|
+
'EXP', # Exploits
|
|
28
|
+
'IMP', # Implants
|
|
29
|
+
'OB', # Obfuscation methods
|
|
30
|
+
'TA', # Threat actors
|
|
31
|
+
],
|
|
32
|
+
description="Specifies the item's subtype (e.g., EXP, CFG, OB, IMP, TA)."
|
|
33
|
+
)
|
|
34
|
+
|
|
24
35
|
@odm.model(index=True, store=False, description="""Represents a granular element within the detailed analysis results, providing specific insights into the analysis findings.
|
|
25
36
|
""")
|
|
26
37
|
class DetailedItem(odm.Model):
|
|
27
38
|
type = odm.Keyword(description="Defines the specific attribute or aspect of the analysis that this detailed item pertains to.")
|
|
28
39
|
value = odm.Keyword(description="The specific value or identifier for the detail item.")
|
|
29
|
-
verdict = odm.Enum(['safe', 'info', 'suspicious', 'malicious'], description="
|
|
30
|
-
subtype = odm.Optional(
|
|
31
|
-
|
|
40
|
+
verdict = odm.Enum(['safe', 'info', 'suspicious', 'highly suspicious', 'malicious'], description="Security assessment of the detailed item.")
|
|
41
|
+
subtype = odm.Optional(DetailedItemSubtype, description="Specifies the item's subtype (e.g., CFG, EXP, IMP, OB, TA).")
|
|
42
|
+
|
|
32
43
|
def __hash__(self) -> int:
|
|
33
44
|
return hash(tuple(sorted(self.as_primitives().items())))
|
|
34
45
|
|
|
@@ -57,16 +68,16 @@ class Screenshot(odm.Model):
|
|
|
57
68
|
@odm.model(index=True, store=False, description="""Provides a comprehensive breakdown of specific attributes and their associated analysis results.
|
|
58
69
|
""")
|
|
59
70
|
class DetailedResults(odm.Model):
|
|
60
|
-
attack_pattern = odm.List(odm.Compound(DetailedItem), default=[], description="
|
|
61
|
-
attack_category = odm.List(odm.Compound(DetailedItem), default=[], description="
|
|
62
|
-
attrib = odm.List(odm.Compound(DetailedItem), default=[], description="
|
|
63
|
-
av = odm.List(odm.Compound(DetailedItem), default=[], description="
|
|
64
|
-
behavior = odm.List(odm.Compound(DetailedItem), default=[], description="
|
|
65
|
-
domain = odm.List(odm.Compound(DetailedItem), default=[], description="
|
|
66
|
-
heuristic = odm.List(odm.Compound(DetailedItem), default=[], description="
|
|
67
|
-
ip = odm.List(odm.Compound(DetailedItem), default=[], description="
|
|
68
|
-
uri = odm.List(odm.Compound(DetailedItem), default=[], description="
|
|
69
|
-
yara = odm.List(odm.Compound(DetailedItem), default=[], description="
|
|
71
|
+
attack_pattern = odm.List(odm.Compound(DetailedItem), default=[], description="MITRE ATT&CK® framework patterns identified in the analysis.")
|
|
72
|
+
attack_category = odm.List(odm.Compound(DetailedItem), default=[], description="MITRE ATT&CK® framework categories associated with the alert.")
|
|
73
|
+
attrib = odm.List(odm.Compound(DetailedItem), default=[], description="Attribution information that provides context by suggesting associations with known malware families, suspected threat actors, or ongoing campaigns.")
|
|
74
|
+
av = odm.List(odm.Compound(DetailedItem), default=[], description="Information on antivirus signature matches.")
|
|
75
|
+
behavior = odm.List(odm.Compound(DetailedItem), default=[], description="Descriptions of the behaviors exhibited by the analyzed file or artifact that led to the alert.")
|
|
76
|
+
domain = odm.List(odm.Compound(DetailedItem), default=[], description="Domain information related to the alert.")
|
|
77
|
+
heuristic = odm.List(odm.Compound(DetailedItem), default=[], description="Heuristic information that triggered the alert.")
|
|
78
|
+
ip = odm.List(odm.Compound(DetailedItem), default=[], description="IP address information related to the alert.")
|
|
79
|
+
uri = odm.List(odm.Compound(DetailedItem), default=[], description="URI information related to the alert.")
|
|
80
|
+
yara = odm.List(odm.Compound(DetailedItem), default=[], description="Information on YARA rule matches that contributed to the alert.")
|
|
70
81
|
|
|
71
82
|
def update(self, other: DetailedResults) -> None:
|
|
72
83
|
for field in self.fields().keys():
|
|
@@ -128,16 +139,16 @@ class File(odm.Model):
|
|
|
128
139
|
@odm.model(index=True, store=False, description="""The Verdict submodel captures the conclusions drawn by users regarding the nature of a submission. It lists user identifiers for those who have deemed the submission as either malicious or non-malicious, representing a collective assessment of the threat.
|
|
129
140
|
""")
|
|
130
141
|
class Verdict(odm.Model):
|
|
131
|
-
malicious = odm.List(odm.Keyword(), default=[], description="User
|
|
142
|
+
malicious = odm.List(odm.Keyword(), default=[], description="User IDs of those who have marked the alert as malicious.")
|
|
132
143
|
non_malicious = odm.List(odm.Keyword(), default=[],
|
|
133
|
-
description="User
|
|
144
|
+
description="User IDs of those who have marked the alert as non-malicious.")
|
|
134
145
|
|
|
135
146
|
def update(self, other: Verdict) -> None:
|
|
136
147
|
self.malicious = list(set(self.malicious + other.malicious))
|
|
137
148
|
self.non_malicious = list(set(self.non_malicious + other.non_malicious))
|
|
138
149
|
|
|
139
150
|
|
|
140
|
-
@odm.model(index=True, store=False, description="""Summarizes the
|
|
151
|
+
@odm.model(index=True, store=False, description="""Summarizes the heuristics that were triggered during the analysis. These heuristics are part of the detection logic used by Assemblyline to identify suspicious or malicious behavior in the analyzed file.
|
|
141
152
|
""")
|
|
142
153
|
class Heuristic(odm.Model):
|
|
143
154
|
name = odm.List(odm.Keyword(), default=[], description="Names of the heuristics that have been matched in the analysis.")
|
|
@@ -195,7 +206,7 @@ class Alert(odm.Model):
|
|
|
195
206
|
al = odm.compound(ALResults, description="Contains the results of the Assemblyline analysis for the alert.")
|
|
196
207
|
archive_ts = odm.Optional(odm.Date(), description="Timestamp indicating when the alert was archived in the system.")
|
|
197
208
|
attack = odm.Compound(Attack, description="Structured data representing MITRE ATT&CK information associated with the alert.")
|
|
198
|
-
classification = odm.Classification(description="Security classification
|
|
209
|
+
classification = odm.Classification(description="Security classification assigned to the alert based on its contents and context.")
|
|
199
210
|
expiry_ts = odm.Optional(odm.Date(store=False), description="Timestamp indicating when the alert is scheduled to expire from the system.")
|
|
200
211
|
extended_scan = odm.Enum(values=EXTENDED_SCAN_VALUES, description="Indicates the status of an extended scan, if applicable. Extended scans are additional analyses performed after the initial analysis.")
|
|
201
212
|
file = odm.Compound(File, description="Information about the file associated with the alert.")
|