misp-modules 3.0.2__tar.gz → 3.0.4__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.
- {misp_modules-3.0.2 → misp_modules-3.0.4}/PKG-INFO +15 -3
- {misp_modules-3.0.2 → misp_modules-3.0.4}/README.md +10 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/__init__.py +2 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/__main__.py +70 -1
- misp_modules-3.0.4/misp_modules/lib/anyrun_sandbox/config.py +2 -0
- misp_modules-3.0.4/misp_modules/lib/anyrun_sandbox/parser.py +147 -0
- misp_modules-3.0.4/misp_modules/lib/anyrun_sandbox/submitter.py +164 -0
- misp_modules-3.0.4/misp_modules/modules/action_mod/nextcloud_talk.py +129 -0
- misp_modules-3.0.4/misp_modules/modules/expansion/_assemblyline_api.py +128 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/_vulnerability_parser/vulnerability_parser.py +234 -51
- misp_modules-3.0.4/misp_modules/modules/expansion/anyrun_sandbox_submit.py +100 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/assemblyline_query.py +120 -42
- misp_modules-3.0.4/misp_modules/modules/expansion/assemblyline_submit.py +185 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/btc_steroids.py +2 -2
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/crowdstrike_falcon.py +65 -1
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/cve.py +1 -1
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/malwarebazaar.py +4 -2
- misp_modules-3.0.4/misp_modules/modules/expansion/rapid7_attackerkb.py +292 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/reversedns.py +1 -1
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/sophoslabs_intelix.py +86 -65
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/threatfox.py +5 -2
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/urlhaus.py +10 -8
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/virustotal_public.py +6 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/vulnerability_lookup.py +2 -2
- misp_modules-3.0.4/misp_modules/modules/expansion/yara_syntax_validator.py +117 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/osqueryexport.py +44 -2
- misp_modules-3.0.4/misp_modules/modules/import_mod/__init__.py +0 -0
- misp_modules-3.0.4/misp_modules/modules/import_mod/anyrun_sandbox_import.py +99 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/csvimport.py +2 -1
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/url_import.py +8 -3
- misp_modules-3.0.4/misp_modules/openapi.py +226 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/pyproject.toml +2 -1
- misp_modules-3.0.2/misp_modules/modules/expansion/assemblyline_submit.py +0 -107
- misp_modules-3.0.2/misp_modules/modules/expansion/yara_syntax_validator.py +0 -50
- {misp_modules-3.0.2 → misp_modules-3.0.4}/LICENSE +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/ODTReader/LICENSE +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/ODTReader/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/ODTReader/odtreader.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/ODTReader/win32_unicode_argv.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/_vmray/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/_vmray/parser.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/_vmray/rest_api.py +0 -0
- {misp_modules-3.0.2/misp_modules/lib/cof2misp → misp_modules-3.0.4/misp_modules/lib/anyrun_sandbox}/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/cof2misp/LICENSE-2.0.txt +0 -0
- {misp_modules-3.0.2/misp_modules/modules → misp_modules-3.0.4/misp_modules/lib/cof2misp}/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/cof2misp/cof.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/dnstrails/LICENSE +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/dnstrails/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/dnstrails/api.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/dnstrails/exception.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/joe_mapping.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/joe_parser.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/lastline_api.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/onyphe/LICENSE +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/onyphe/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/onyphe/client.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/onyphe/exception.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/qintel_helper.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/synonymsToTagNames.json +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/vt_graph_parser/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/vt_graph_parser/errors.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/vt_graph_parser/helpers/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/vt_graph_parser/helpers/parsers.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/vt_graph_parser/helpers/rules.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/vt_graph_parser/helpers/wrappers.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/vt_graph_parser/importers/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/vt_graph_parser/importers/base.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/lib/vt_graph_parser/importers/pymisp_response.py +0 -0
- {misp_modules-3.0.2/misp_modules/modules/action_mod → misp_modules-3.0.4/misp_modules/modules}/__init__.py +0 -0
- {misp_modules-3.0.2/misp_modules/modules/action_mod/_utils → misp_modules-3.0.4/misp_modules/modules/action_mod}/__init__.py +0 -0
- {misp_modules-3.0.2/misp_modules/modules/expansion/_dnsdb_query → misp_modules-3.0.4/misp_modules/modules/action_mod/_utils}/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/action_mod/_utils/utils.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/action_mod/mattermost.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/action_mod/slack.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/action_mod/testaction.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/_dnsdb_query/COPYRIGHT +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/_dnsdb_query/LICENSE +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/_dnsdb_query/README.md +0 -0
- {misp_modules-3.0.2/misp_modules/modules/expansion/_ransomcoindb → misp_modules-3.0.4/misp_modules/modules/expansion/_dnsdb_query}/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/_dnsdb_query/dnsdb_query.py +0 -0
- {misp_modules-3.0.2/misp_modules/modules/expansion/_vulnerability_parser → misp_modules-3.0.4/misp_modules/modules/expansion/_ransomcoindb}/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/_ransomcoindb/ransomcoindb.py +0 -0
- {misp_modules-3.0.2/misp_modules/modules/export_mod → misp_modules-3.0.4/misp_modules/modules/expansion/_vulnerability_parser}/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/abuseipdb.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/apiosintds.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/apivoid.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/backscatter_io.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/btc_scam_check.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/censys_enrich.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/circl_passivedns.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/circl_passivessl.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/clamav.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/cluster25_expand.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/convert_markdown_to_pdf.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/countrycode.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/cpe.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/crowdsec.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/cuckoo_submit.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/cve_advanced.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/cytomic_orion.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/dbl_spamhaus.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/dns.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/docx_enrich.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/domaintools.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/eql.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/eupi.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/extract_url_components.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/farsight_passivedns.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/geoip_asn.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/geoip_city.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/geoip_country.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/google_safe_browsing.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/google_threat_intelligence.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/greynoise.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/hashdd.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/hashlookup.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/hibp.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/html_to_markdown.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/hyasinsight.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/intel471.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/intelmq_eventdb.py.experimental +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/ip2locationio.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/ipasn.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/ipinfo.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/iprep.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/jinja_template_rendering.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/joesandbox_query.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/joesandbox_submit.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/lastline_query.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/lastline_submit.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/macaddress_io.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/macvendors.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/malshare_upload.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/mcafee_insights_enrich.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/mmdb_lookup.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/module.py.skeleton +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/module_misp_standard.py.skeleton +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/mwdb.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/ocr_enrich.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/ods_enrich.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/odt_enrich.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/onion_lookup.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/onyphe.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/onyphe_full.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/otx.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/passive_ssh.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/passivetotal.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/pdf_enrich.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/pptx_enrich.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/qintel_qsentry.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/qrcode.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/ransomcoindb.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/rbl.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/recordedfuture.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/securitytrails.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/shodan.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/sigma_queries.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/sigma_syntax_validator.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/sigmf_expand.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/socialscan.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/sourcecache.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/stairwell.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/stix2_pattern_syntax_validator.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/threatcrowd.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/threatminer.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/triage_submit.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/trustar_enrich.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/urlscan.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/variotdbs.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/virustotal.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/virustotal_upload.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/vmray_submit.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/vmware_nsx.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/vulndb.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/vulners.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/vysion.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/whois.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/whoisfreaks.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/wiki.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/xforceexchange.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/xlsx_enrich.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/yara_query.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/expansion/yeti.py +0 -0
- {misp_modules-3.0.2/misp_modules/modules/import_mod → misp_modules-3.0.4/misp_modules/modules/export_mod}/__init__.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/cef_export.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/defender_endpoint_export.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/goamlexport.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/liteexport.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/mass_eql_export.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/nexthinkexport.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/pdfexport.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/testexport.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/threatStream_misp_export.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/threat_connect_export.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/virustotal_collections.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/vt_graph.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/export_mod/yara_export.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/cof2misp.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/cuckooimport.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/email_import.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/goamlimport.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/import_blueprint.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/joe_import.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/lastline_import.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/mispjson.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/ocr.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/openiocimport.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/taxii21.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/testimport.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/threatanalyzer_import.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/vmray_import.py +0 -0
- {misp_modules-3.0.2 → misp_modules-3.0.4}/misp_modules/modules/import_mod/vmray_summary_json_import.py +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: misp-modules
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.4
|
|
4
4
|
Summary: MISP modules are autonomous modules that can be used for expansion and other services in MISP
|
|
5
|
-
License: AGPL-3.0-only
|
|
5
|
+
License-Expression: AGPL-3.0-only
|
|
6
|
+
License-File: LICENSE
|
|
6
7
|
Author: Alexandre Dulaunoy
|
|
7
8
|
Author-email: alexandre.dulaunoy@circl.lu
|
|
8
9
|
Requires-Python: >=3.9,<3.13
|
|
@@ -14,6 +15,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
14
15
|
Classifier: Topic :: Security
|
|
15
16
|
Provides-Extra: all
|
|
16
17
|
Provides-Extra: minimal
|
|
18
|
+
Requires-Dist: anyrun-sdk (>=1.10.10,<2.0.0)
|
|
17
19
|
Requires-Dist: apiosintds ; extra == "all"
|
|
18
20
|
Requires-Dist: assemblyline_client ; extra == "all"
|
|
19
21
|
Requires-Dist: backscatter ; extra == "all"
|
|
@@ -156,6 +158,12 @@ In order to provide documentation about some modules that require specific input
|
|
|
156
158
|
- **input** - description of the format of data used in input
|
|
157
159
|
- **output** - description of the format given as the result of the module execution
|
|
158
160
|
|
|
161
|
+
## OpenAPI and API explorer
|
|
162
|
+
|
|
163
|
+
When the service is running you can discover the available endpoints in a machine-readable way via `/openapi.json`.
|
|
164
|
+
An interactive Swagger UI that consumes the same specification is available at `/openapi`.
|
|
165
|
+
The specification is generated during service startup, so restart `misp-modules` after adding or removing modules to refresh what those endpoints expose.
|
|
166
|
+
|
|
159
167
|
## Licenses
|
|
160
168
|
For further Information see the [license file](https://misp.github.io/misp-modules/license/).
|
|
161
169
|
|
|
@@ -163,6 +171,7 @@ For further Information see the [license file](https://misp.github.io/misp-modul
|
|
|
163
171
|
|
|
164
172
|
## Expansion Modules
|
|
165
173
|
* [Abuse IPDB](https://misp.github.io/misp-modules/expansion/#abuse-ipdb) - AbuseIPDB MISP expansion module
|
|
174
|
+
* [ANYRUN Sandbox Submit](https://misp.github.io/misp-modules/expansion/#anyrun-sandbox-submit) - A module designed to submit URLs or files to the ANY.RUN Sandbox for analysis and return the unique analysis link and ID.
|
|
166
175
|
* [OSINT DigitalSide](https://misp.github.io/misp-modules/expansion/#osint-digitalside) - On demand query API for OSINT.digitalside.it project.
|
|
167
176
|
* [APIVoid](https://misp.github.io/misp-modules/expansion/#apivoid) - Module to query APIVoid with some domain attributes.
|
|
168
177
|
* [AssemblyLine Query](https://misp.github.io/misp-modules/expansion/#assemblyline-query) - A module tu query the AssemblyLine API with a submission ID to get the submission report and parse it.
|
|
@@ -235,6 +244,7 @@ For further Information see the [license file](https://misp.github.io/misp-modul
|
|
|
235
244
|
* [Qintel QSentry Lookup](https://misp.github.io/misp-modules/expansion/#qintel-qsentry-lookup) - A hover and expansion module which queries Qintel QSentry for ip reputation data
|
|
236
245
|
* [QR Code Decode](https://misp.github.io/misp-modules/expansion/#qr-code-decode) - Module to decode QR codes.
|
|
237
246
|
* [RandomcoinDB Lookup](https://misp.github.io/misp-modules/expansion/#randomcoindb-lookup) - Module to access the ransomcoinDB (see https://ransomcoindb.concinnity-risks.com)
|
|
247
|
+
* [r7_akb](https://misp.github.io/misp-modules/expansion/#r7_akb) - Enrich CVEs via AttackerKB and return structured MISP events. Handles rate limits, regex CVE detection, and markdown cleanup.
|
|
238
248
|
* [Real-time Blackhost Lists Lookup](https://misp.github.io/misp-modules/expansion/#real-time-blackhost-lists-lookup) - Module to check an IPv4 address against known RBLs.
|
|
239
249
|
* [Recorded Future Enrich](https://misp.github.io/misp-modules/expansion/#recorded-future-enrich) - Module to enrich attributes with threat intelligence from Recorded Future.
|
|
240
250
|
* [Reverse DNS](https://misp.github.io/misp-modules/expansion/#reverse-dns) - Simple Reverse DNS expansion service to resolve reverse DNS from MISP attributes.
|
|
@@ -292,6 +302,7 @@ For further Information see the [license file](https://misp.github.io/misp-modul
|
|
|
292
302
|
* [YARA Rule Export](https://misp.github.io/misp-modules/export_mod/#yara-rule-export) - This module is used to export MISP events to YARA.
|
|
293
303
|
|
|
294
304
|
## Import Modules
|
|
305
|
+
* [ANYRUN Sandbox Import](https://misp.github.io/misp-modules/import_mod/#anyrun-sandbox-import) - A module designed to retrieve an analysis report from the ANY.RUN Sandbox by its unique ID and extract results (such as verdict, malware tags, and IOCs), converting them into MISP attributes within your event.
|
|
295
306
|
* [PDNS COF Importer](https://misp.github.io/misp-modules/import_mod/#pdns-cof-importer) - Passive DNS Common Output Format (COF) MISP importer
|
|
296
307
|
* [CSV Import](https://misp.github.io/misp-modules/import_mod/#csv-import) - Module to import MISP attributes from a csv file.
|
|
297
308
|
* [Cuckoo Sandbox Import](https://misp.github.io/misp-modules/import_mod/#cuckoo-sandbox-import) - Module to import Cuckoo JSON.
|
|
@@ -312,6 +323,7 @@ For further Information see the [license file](https://misp.github.io/misp-modul
|
|
|
312
323
|
|
|
313
324
|
## Action Modules
|
|
314
325
|
* [Mattermost](https://misp.github.io/misp-modules/action_mod/#mattermost) - Simplistic module to send message to a Mattermost channel.
|
|
326
|
+
* [Nextcloud talk](https://misp.github.io/misp-modules/action_mod/#nextcloud-talk) - Simplistic module to send a message to a Nextcloud talk conversation.
|
|
315
327
|
* [Slack](https://misp.github.io/misp-modules/action_mod/#slack) - Simplistic module to send messages to a Slack channel.
|
|
316
328
|
* [Test action](https://misp.github.io/misp-modules/action_mod/#test-action) - This module is merely a test, always returning true. Triggers on event publishing.
|
|
317
329
|
|
|
@@ -30,6 +30,12 @@ In order to provide documentation about some modules that require specific input
|
|
|
30
30
|
- **input** - description of the format of data used in input
|
|
31
31
|
- **output** - description of the format given as the result of the module execution
|
|
32
32
|
|
|
33
|
+
## OpenAPI and API explorer
|
|
34
|
+
|
|
35
|
+
When the service is running you can discover the available endpoints in a machine-readable way via `/openapi.json`.
|
|
36
|
+
An interactive Swagger UI that consumes the same specification is available at `/openapi`.
|
|
37
|
+
The specification is generated during service startup, so restart `misp-modules` after adding or removing modules to refresh what those endpoints expose.
|
|
38
|
+
|
|
33
39
|
## Licenses
|
|
34
40
|
For further Information see the [license file](https://misp.github.io/misp-modules/license/).
|
|
35
41
|
|
|
@@ -37,6 +43,7 @@ For further Information see the [license file](https://misp.github.io/misp-modul
|
|
|
37
43
|
|
|
38
44
|
## Expansion Modules
|
|
39
45
|
* [Abuse IPDB](https://misp.github.io/misp-modules/expansion/#abuse-ipdb) - AbuseIPDB MISP expansion module
|
|
46
|
+
* [ANYRUN Sandbox Submit](https://misp.github.io/misp-modules/expansion/#anyrun-sandbox-submit) - A module designed to submit URLs or files to the ANY.RUN Sandbox for analysis and return the unique analysis link and ID.
|
|
40
47
|
* [OSINT DigitalSide](https://misp.github.io/misp-modules/expansion/#osint-digitalside) - On demand query API for OSINT.digitalside.it project.
|
|
41
48
|
* [APIVoid](https://misp.github.io/misp-modules/expansion/#apivoid) - Module to query APIVoid with some domain attributes.
|
|
42
49
|
* [AssemblyLine Query](https://misp.github.io/misp-modules/expansion/#assemblyline-query) - A module tu query the AssemblyLine API with a submission ID to get the submission report and parse it.
|
|
@@ -109,6 +116,7 @@ For further Information see the [license file](https://misp.github.io/misp-modul
|
|
|
109
116
|
* [Qintel QSentry Lookup](https://misp.github.io/misp-modules/expansion/#qintel-qsentry-lookup) - A hover and expansion module which queries Qintel QSentry for ip reputation data
|
|
110
117
|
* [QR Code Decode](https://misp.github.io/misp-modules/expansion/#qr-code-decode) - Module to decode QR codes.
|
|
111
118
|
* [RandomcoinDB Lookup](https://misp.github.io/misp-modules/expansion/#randomcoindb-lookup) - Module to access the ransomcoinDB (see https://ransomcoindb.concinnity-risks.com)
|
|
119
|
+
* [r7_akb](https://misp.github.io/misp-modules/expansion/#r7_akb) - Enrich CVEs via AttackerKB and return structured MISP events. Handles rate limits, regex CVE detection, and markdown cleanup.
|
|
112
120
|
* [Real-time Blackhost Lists Lookup](https://misp.github.io/misp-modules/expansion/#real-time-blackhost-lists-lookup) - Module to check an IPv4 address against known RBLs.
|
|
113
121
|
* [Recorded Future Enrich](https://misp.github.io/misp-modules/expansion/#recorded-future-enrich) - Module to enrich attributes with threat intelligence from Recorded Future.
|
|
114
122
|
* [Reverse DNS](https://misp.github.io/misp-modules/expansion/#reverse-dns) - Simple Reverse DNS expansion service to resolve reverse DNS from MISP attributes.
|
|
@@ -166,6 +174,7 @@ For further Information see the [license file](https://misp.github.io/misp-modul
|
|
|
166
174
|
* [YARA Rule Export](https://misp.github.io/misp-modules/export_mod/#yara-rule-export) - This module is used to export MISP events to YARA.
|
|
167
175
|
|
|
168
176
|
## Import Modules
|
|
177
|
+
* [ANYRUN Sandbox Import](https://misp.github.io/misp-modules/import_mod/#anyrun-sandbox-import) - A module designed to retrieve an analysis report from the ANY.RUN Sandbox by its unique ID and extract results (such as verdict, malware tags, and IOCs), converting them into MISP attributes within your event.
|
|
169
178
|
* [PDNS COF Importer](https://misp.github.io/misp-modules/import_mod/#pdns-cof-importer) - Passive DNS Common Output Format (COF) MISP importer
|
|
170
179
|
* [CSV Import](https://misp.github.io/misp-modules/import_mod/#csv-import) - Module to import MISP attributes from a csv file.
|
|
171
180
|
* [Cuckoo Sandbox Import](https://misp.github.io/misp-modules/import_mod/#cuckoo-sandbox-import) - Module to import Cuckoo JSON.
|
|
@@ -186,6 +195,7 @@ For further Information see the [license file](https://misp.github.io/misp-modul
|
|
|
186
195
|
|
|
187
196
|
## Action Modules
|
|
188
197
|
* [Mattermost](https://misp.github.io/misp-modules/action_mod/#mattermost) - Simplistic module to send message to a Mattermost channel.
|
|
198
|
+
* [Nextcloud talk](https://misp.github.io/misp-modules/action_mod/#nextcloud-talk) - Simplistic module to send a message to a Nextcloud talk conversation.
|
|
189
199
|
* [Slack](https://misp.github.io/misp-modules/action_mod/#slack) - Simplistic module to send messages to a Slack channel.
|
|
190
200
|
* [Test action](https://misp.github.io/misp-modules/action_mod/#test-action) - This module is merely a test, always returning true. Triggers on event publishing.
|
|
191
201
|
|
|
@@ -41,14 +41,46 @@ from tornado import concurrent as tornado_concurrent
|
|
|
41
41
|
from tornado import ioloop
|
|
42
42
|
|
|
43
43
|
import misp_modules
|
|
44
|
+
from misp_modules import openapi as openapi_builder
|
|
44
45
|
|
|
45
46
|
# See https://github.com/MISP/misp-modules/issues/662
|
|
46
47
|
MAX_BUFFER_SIZE = 1073741824
|
|
47
48
|
|
|
48
49
|
# Global variables
|
|
49
50
|
MODULES_HANDLERS = {}
|
|
51
|
+
OPENAPI_DOCUMENT = {}
|
|
50
52
|
LOGGER = logging.getLogger("misp-modules")
|
|
51
53
|
|
|
54
|
+
SWAGGER_UI_TEMPLATE = (
|
|
55
|
+
"<!DOCTYPE html>\n"
|
|
56
|
+
"<html lang='en'>\n"
|
|
57
|
+
"<head>\n"
|
|
58
|
+
" <meta charset='utf-8' />\n"
|
|
59
|
+
" <title>MISP Modules API Explorer</title>\n"
|
|
60
|
+
" <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css' />\n"
|
|
61
|
+
"</head>\n"
|
|
62
|
+
"<body>\n"
|
|
63
|
+
" <div id='swagger-ui'></div>\n"
|
|
64
|
+
" <script src='https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.min.js'></script>\n"
|
|
65
|
+
" <script src='https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-standalone-preset.js'></script>\n"
|
|
66
|
+
" <script>\n"
|
|
67
|
+
" window.addEventListener('load', function() {\n"
|
|
68
|
+
" const ui = SwaggerUIBundle({\n"
|
|
69
|
+
" url: '__SPEC_URL__',\n"
|
|
70
|
+
" dom_id: '#swagger-ui',\n"
|
|
71
|
+
" presets: [\n"
|
|
72
|
+
" SwaggerUIBundle.presets.apis,\n"
|
|
73
|
+
" SwaggerUIStandalonePreset\n"
|
|
74
|
+
" ],\n"
|
|
75
|
+
" layout: 'StandaloneLayout'\n"
|
|
76
|
+
" });\n"
|
|
77
|
+
" window.ui = ui;\n"
|
|
78
|
+
" });\n"
|
|
79
|
+
" </script>\n"
|
|
80
|
+
"</body>\n"
|
|
81
|
+
"</html>\n"
|
|
82
|
+
)
|
|
83
|
+
|
|
52
84
|
# Module that, if present, guarantees that the extra 'all' has been installed
|
|
53
85
|
DEGRADED_SENTINEL_MODULE = "yara"
|
|
54
86
|
DEGRADED_MESSAGE = [
|
|
@@ -132,6 +164,30 @@ class HealthCheck(tornado.web.RequestHandler):
|
|
|
132
164
|
self.write(orjson.dumps({"status": True}))
|
|
133
165
|
|
|
134
166
|
|
|
167
|
+
class OpenAPISpec(tornado.web.RequestHandler):
|
|
168
|
+
"""OpenAPI specification handler."""
|
|
169
|
+
|
|
170
|
+
def get(self):
|
|
171
|
+
LOGGER.debug("OpenAPI spec request")
|
|
172
|
+
if not OPENAPI_DOCUMENT:
|
|
173
|
+
self.send_error(503)
|
|
174
|
+
return
|
|
175
|
+
self.set_header("Content-Type", "application/json")
|
|
176
|
+
self.write(orjson.dumps(OPENAPI_DOCUMENT))
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class SwaggerUI(tornado.web.RequestHandler):
|
|
180
|
+
"""Swagger UI explorer handler."""
|
|
181
|
+
|
|
182
|
+
def get(self):
|
|
183
|
+
LOGGER.debug("Swagger UI request")
|
|
184
|
+
if not OPENAPI_DOCUMENT:
|
|
185
|
+
self.send_error(503)
|
|
186
|
+
return
|
|
187
|
+
self.set_header("Content-Type", "text/html; charset=utf-8")
|
|
188
|
+
self.write(SWAGGER_UI_TEMPLATE.replace('__SPEC_URL__', '/openapi.json'))
|
|
189
|
+
|
|
190
|
+
|
|
135
191
|
class ListModules(tornado.web.RequestHandler):
|
|
136
192
|
"""ListModules handler."""
|
|
137
193
|
|
|
@@ -197,7 +253,7 @@ class QueryModule(tornado.web.RequestHandler):
|
|
|
197
253
|
|
|
198
254
|
def main():
|
|
199
255
|
"""Init function."""
|
|
200
|
-
global MODULES_HANDLERS
|
|
256
|
+
global MODULES_HANDLERS # noqa: F824
|
|
201
257
|
|
|
202
258
|
signal.signal(signal.SIGINT, handle_signal)
|
|
203
259
|
signal.signal(signal.SIGTERM, handle_signal)
|
|
@@ -249,6 +305,17 @@ def main():
|
|
|
249
305
|
MODULES_HANDLERS[f"type:{module_name}"] = module_type.name
|
|
250
306
|
LOGGER.info("CUSTOM MISP module %s (type=%s) imported", module_name, module_type.name)
|
|
251
307
|
|
|
308
|
+
global OPENAPI_DOCUMENT # noqa: PLW0603
|
|
309
|
+
try:
|
|
310
|
+
OPENAPI_DOCUMENT = openapi_builder.build_document(
|
|
311
|
+
MODULES_HANDLERS,
|
|
312
|
+
listen=args.listen,
|
|
313
|
+
port=args.port,
|
|
314
|
+
)
|
|
315
|
+
except Exception:
|
|
316
|
+
LOGGER.exception("Failed to build OpenAPI document; continuing without it")
|
|
317
|
+
OPENAPI_DOCUMENT = {}
|
|
318
|
+
|
|
252
319
|
try:
|
|
253
320
|
server = tornado.httpserver.HTTPServer(
|
|
254
321
|
tornado.web.Application(
|
|
@@ -257,6 +324,8 @@ def main():
|
|
|
257
324
|
(r"/query", QueryModule),
|
|
258
325
|
(r"/healthcheck", HealthCheck),
|
|
259
326
|
(r"/version", VersionCheck),
|
|
327
|
+
(r"/openapi.json", OpenAPISpec),
|
|
328
|
+
(r"/openapi", SwaggerUI),
|
|
260
329
|
]
|
|
261
330
|
),
|
|
262
331
|
max_buffer_size=MAX_BUFFER_SIZE,
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from http import HTTPStatus
|
|
3
|
+
from pymisp import MISPEvent, MISPObject
|
|
4
|
+
|
|
5
|
+
from anyrun import RunTimeException
|
|
6
|
+
from anyrun.connectors.sandbox.operation_systems import WindowsConnector, LinuxConnector, AndroidConnector
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AnyRunParser:
|
|
10
|
+
"""
|
|
11
|
+
Implements functionality for parsing ANY.RUN Sandbox reports into MISP objects and attributes
|
|
12
|
+
"""
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
config: dict[str, str],
|
|
16
|
+
analysis_uuid: str,
|
|
17
|
+
connector: WindowsConnector | LinuxConnector | AndroidConnector
|
|
18
|
+
) -> None:
|
|
19
|
+
self._event = MISPEvent()
|
|
20
|
+
self._connector = connector
|
|
21
|
+
self._analysis_uuid = analysis_uuid
|
|
22
|
+
self._config = config
|
|
23
|
+
|
|
24
|
+
def generate_results(self) -> dict[str, dict]:
|
|
25
|
+
"""
|
|
26
|
+
Enriches the results dictionary with ANY.RUN report objects
|
|
27
|
+
|
|
28
|
+
:return: MISP results dictionary
|
|
29
|
+
"""
|
|
30
|
+
self._check_analysis_completion()
|
|
31
|
+
|
|
32
|
+
summary = self._connector.get_analysis_report(self._analysis_uuid)
|
|
33
|
+
|
|
34
|
+
self._add_report()
|
|
35
|
+
|
|
36
|
+
if self._check_option("IOCs"):
|
|
37
|
+
self._add_indicators()
|
|
38
|
+
|
|
39
|
+
if self._check_option("Tags"):
|
|
40
|
+
self._add_tags(summary)
|
|
41
|
+
|
|
42
|
+
if self._check_option("MITRE"):
|
|
43
|
+
self._add_mitre_galaxies(summary)
|
|
44
|
+
|
|
45
|
+
results = json.loads(self._event.to_json())
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
"results": {
|
|
49
|
+
key: results[key]
|
|
50
|
+
for key in ("Attribute", "Object", "Tag")
|
|
51
|
+
if (key in results and results[key])
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
def _check_analysis_completion(self) -> None:
|
|
56
|
+
"""
|
|
57
|
+
Checks if ANY.RUN Sandbox analysis is completed
|
|
58
|
+
|
|
59
|
+
:raises RunTimeException: If analysis is not completed
|
|
60
|
+
"""
|
|
61
|
+
status = self._connector.get_analysis_report(self._analysis_uuid).get("data").get("status")
|
|
62
|
+
|
|
63
|
+
if status != "done":
|
|
64
|
+
raise RunTimeException(
|
|
65
|
+
f"Analysis is running. Please, wait a few minutes to request a report",
|
|
66
|
+
HTTPStatus.BAD_REQUEST
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def _add_indicators(self) -> None:
|
|
70
|
+
"""
|
|
71
|
+
Converts ANY.RUN indicators to the MISP attributes
|
|
72
|
+
"""
|
|
73
|
+
if iocs := self._connector.get_analysis_report(self._analysis_uuid, report_format="ioc"):
|
|
74
|
+
for ioc in iocs:
|
|
75
|
+
if ioc.get("type") in ("domain", "ip", "sha256") and ioc.get("reputation") in (1, 2):
|
|
76
|
+
ioc_type = ioc.get("type")
|
|
77
|
+
ioc_reputation = {1: "Suspicious", 2: "Malicious"}.get(ioc.get("reputation"))
|
|
78
|
+
attribute = self._event.add_attribute(
|
|
79
|
+
type=ioc_type if ioc_type in ("domain", "sha256") else "ip-dst",
|
|
80
|
+
value=ioc.get("ioc"),
|
|
81
|
+
categories="Network activity" if ioc_type in ("ip", "domain") else "Payload delivery",
|
|
82
|
+
comment=f"{ioc_reputation} IoC from https://app.any.run/tasks/{self._analysis_uuid}."
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
attribute.add_tag("ANY.RUN Sandbox")
|
|
86
|
+
|
|
87
|
+
def _add_tags(self, summary: dict) -> None:
|
|
88
|
+
"""
|
|
89
|
+
Converts ANY.RUN analysis tags to the MISP tags
|
|
90
|
+
|
|
91
|
+
:param summary: ANY.RUN Sandbox report
|
|
92
|
+
"""
|
|
93
|
+
self._event.add_tag("ANY.RUN Sandbox")
|
|
94
|
+
if tags := summary.get("data").get("analysis").get("tags"):
|
|
95
|
+
for tag in tags:
|
|
96
|
+
self._event.add_tag(tag.get("tag"))
|
|
97
|
+
|
|
98
|
+
def _add_mitre_galaxies(self, summary: dict) -> None:
|
|
99
|
+
"""
|
|
100
|
+
Converts ANY.RUN analysis mitre techniques to the MISP Galaxies
|
|
101
|
+
|
|
102
|
+
:param summary: ANY.RUN Sandbox report
|
|
103
|
+
"""
|
|
104
|
+
if mitre_techniques := summary.get("data").get("mitre"):
|
|
105
|
+
for entry in mitre_techniques:
|
|
106
|
+
if entry:
|
|
107
|
+
mitre_name = entry.get("name")
|
|
108
|
+
mitre_id = entry.get("id")
|
|
109
|
+
self._event.add_tag(f'misp-galaxy:mitre-attack-pattern="{mitre_name} - {mitre_id}"')
|
|
110
|
+
|
|
111
|
+
def _add_report(self) -> None:
|
|
112
|
+
"""
|
|
113
|
+
Converts ANY.RUN analysis HTML report and external references to the MISP attributes
|
|
114
|
+
|
|
115
|
+
:return:
|
|
116
|
+
"""
|
|
117
|
+
report = self._connector.get_analysis_report(self._analysis_uuid, report_format="html")
|
|
118
|
+
|
|
119
|
+
self._event.add_attribute(
|
|
120
|
+
type="text",
|
|
121
|
+
value=f"ANY.RUN Sandbox verdict: {self._connector.get_analysis_verdict(self._analysis_uuid)}",
|
|
122
|
+
categories="Other",
|
|
123
|
+
comment="ANYRUN Sandbox Analysis verdict."
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
self._event.add_attribute(
|
|
127
|
+
type="link",
|
|
128
|
+
value=f"https://app.any.run/tasks/{self._analysis_uuid}",
|
|
129
|
+
categories="External analysis",
|
|
130
|
+
comment="ANYRUN Sandbox Analysis report."
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
self._event.add_attribute(
|
|
134
|
+
type="attachment",
|
|
135
|
+
value="report.html",
|
|
136
|
+
data=report.encode(),
|
|
137
|
+
comment="ANYRUN Sandbox Analysis report."
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
def _check_option(self, option_name: str) -> bool:
|
|
141
|
+
"""
|
|
142
|
+
Checks if option is active
|
|
143
|
+
|
|
144
|
+
:param option_name: Option name to check
|
|
145
|
+
:return: True if option is enabled else False
|
|
146
|
+
"""
|
|
147
|
+
return bool(int(self._config.get(option_name)))
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import base64
|
|
3
|
+
import zipfile
|
|
4
|
+
|
|
5
|
+
from anyrun import RunTimeException
|
|
6
|
+
from anyrun.connectors import SandboxConnector
|
|
7
|
+
from anyrun.connectors.sandbox.operation_systems import WindowsConnector, LinuxConnector, AndroidConnector
|
|
8
|
+
|
|
9
|
+
from anyrun_sandbox.config import Config
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AnyRunSubmitter:
|
|
13
|
+
"""
|
|
14
|
+
Implements functionality for sending MISP entities to the ANY.RUN sandbox
|
|
15
|
+
"""
|
|
16
|
+
def __init__(self, request: dict) -> None:
|
|
17
|
+
self._request = request
|
|
18
|
+
self._config: dict = request.get("config")
|
|
19
|
+
|
|
20
|
+
def submit(self) -> str:
|
|
21
|
+
"""
|
|
22
|
+
Configures ANY.RUN Sandbox environment and executes the analysis
|
|
23
|
+
|
|
24
|
+
:return: ANY.RUN Sandbox analysis uuid
|
|
25
|
+
"""
|
|
26
|
+
self._parse_config()
|
|
27
|
+
self._sanitize_config()
|
|
28
|
+
|
|
29
|
+
if self._os_type == "windows":
|
|
30
|
+
with SandboxConnector.windows(self._token, Config.INTEGRATION) as connector:
|
|
31
|
+
analysis_uuid = self._process_analysis(connector)
|
|
32
|
+
elif self._os_type in ("ubuntu", "debian"):
|
|
33
|
+
with SandboxConnector.linux(self._token, Config.INTEGRATION) as connector:
|
|
34
|
+
analysis_uuid = self._process_analysis(connector)
|
|
35
|
+
elif self._os_type == "android":
|
|
36
|
+
with SandboxConnector.android(self._token, Config.INTEGRATION) as connector:
|
|
37
|
+
analysis_uuid = self._process_analysis(connector)
|
|
38
|
+
else:
|
|
39
|
+
raise RunTimeException(
|
|
40
|
+
f"Received invalid OS type: {self._os_type}. Supports: windows, ubuntu, debian, android"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
return analysis_uuid
|
|
44
|
+
|
|
45
|
+
def _parse_config(self) -> None:
|
|
46
|
+
"""
|
|
47
|
+
Configures analysis options according to the chosen environment
|
|
48
|
+
|
|
49
|
+
"""
|
|
50
|
+
self._token = self._config.pop("api_key", "")
|
|
51
|
+
self._os_type = self._config.pop("os_type", "")
|
|
52
|
+
|
|
53
|
+
if not any((self._token, self._os_type)):
|
|
54
|
+
raise RunTimeException(f"ANYRUN Sandbox API-KEY and OS type must be specified.")
|
|
55
|
+
|
|
56
|
+
if "url" in self._request:
|
|
57
|
+
self._prepare_url_params()
|
|
58
|
+
self._config["obj_url"] = self._request.get("url")
|
|
59
|
+
elif "malware-sample" in self._request:
|
|
60
|
+
self._prepare_file_params()
|
|
61
|
+
self._prepare_file_content("malware-sample")
|
|
62
|
+
elif "attachment" in self._request:
|
|
63
|
+
self._prepare_file_params()
|
|
64
|
+
self._prepare_file_content("attachment")
|
|
65
|
+
else:
|
|
66
|
+
raise RunTimeException("Received invalid Object. Supports: url, attachment, malware-sample.")
|
|
67
|
+
|
|
68
|
+
def _process_analysis(self, connector: WindowsConnector | LinuxConnector | AndroidConnector) -> str:
|
|
69
|
+
"""
|
|
70
|
+
Executes analysis
|
|
71
|
+
|
|
72
|
+
:param connector: Instance of the ANY.RUN connector
|
|
73
|
+
:return: ANY.RUN Sandbox analysis uuid
|
|
74
|
+
"""
|
|
75
|
+
connector.check_authorization()
|
|
76
|
+
|
|
77
|
+
if "obj_url" in self._config:
|
|
78
|
+
analysis_uuid = connector.run_url_analysis(**self._config)
|
|
79
|
+
else:
|
|
80
|
+
analysis_uuid = connector.run_file_analysis(**self._config)
|
|
81
|
+
return analysis_uuid
|
|
82
|
+
|
|
83
|
+
def _prepare_url_params(self) -> None:
|
|
84
|
+
"""
|
|
85
|
+
Prepares analysis configuration for the url submission
|
|
86
|
+
"""
|
|
87
|
+
if self._os_type != "windows":
|
|
88
|
+
self._config.pop("env_version", "")
|
|
89
|
+
self._config.pop("env_bitness", "")
|
|
90
|
+
self._config.pop("env_type", "")
|
|
91
|
+
|
|
92
|
+
self._config.pop("obj_ext_extension", "")
|
|
93
|
+
self._config.pop("obj_ext_startfolder", "")
|
|
94
|
+
self._config.pop("obj_ext_cmd", "")
|
|
95
|
+
self._config.pop("obj_force_elevation", "")
|
|
96
|
+
self._config.pop("run_as_root", "")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _prepare_file_params(self) -> None:
|
|
100
|
+
"""
|
|
101
|
+
Prepares analysis configuration for the file submission
|
|
102
|
+
"""
|
|
103
|
+
self._config.pop("obj_ext_browser", "")
|
|
104
|
+
|
|
105
|
+
if self._os_type == "windows":
|
|
106
|
+
self._config.pop("run_as_root", "")
|
|
107
|
+
elif self._os_type in ("ubuntu", "debian"):
|
|
108
|
+
self._config.pop("env_version", "")
|
|
109
|
+
self._config.pop("env_bitness", "")
|
|
110
|
+
self._config.pop("env_type", "")
|
|
111
|
+
self._config.pop("obj_force_elevation", "")
|
|
112
|
+
self._config["env_os"] = self._os_type
|
|
113
|
+
elif self._os_type == "android":
|
|
114
|
+
self._config.pop("env_version", "")
|
|
115
|
+
self._config.pop("env_bitness", "")
|
|
116
|
+
self._config.pop("env_type", "")
|
|
117
|
+
self._config.pop("obj_force_elevation", "")
|
|
118
|
+
self._config.pop("obj_ext_startfolder", "")
|
|
119
|
+
self._config.pop("run_as_root", "")
|
|
120
|
+
|
|
121
|
+
def _prepare_file_content(self, sample_type: str) -> None:
|
|
122
|
+
"""
|
|
123
|
+
Prepares file content to the analysis
|
|
124
|
+
|
|
125
|
+
:param sample_type: Attachment or malware-sample MISP entity
|
|
126
|
+
"""
|
|
127
|
+
if sample_type == "attachment":
|
|
128
|
+
filename = self._request.get("attachment")
|
|
129
|
+
file_content = self._extract_file_content(self._request.get("data"))
|
|
130
|
+
else:
|
|
131
|
+
filename = self._request.get("malware-sample").split("|", 1)[0]
|
|
132
|
+
file_content = self._extract_file_content(self._request.get("data"), is_encoded=True)
|
|
133
|
+
|
|
134
|
+
self._config["filename"] = filename
|
|
135
|
+
self._config["file_content"] = file_content
|
|
136
|
+
|
|
137
|
+
def _sanitize_config(self) -> None:
|
|
138
|
+
"""
|
|
139
|
+
Removes empty parameters from the analysis configuration
|
|
140
|
+
"""
|
|
141
|
+
temp_config = dict()
|
|
142
|
+
|
|
143
|
+
for key, value in self._config.items():
|
|
144
|
+
if value is not None:
|
|
145
|
+
temp_config[key] = value
|
|
146
|
+
|
|
147
|
+
self._config = temp_config
|
|
148
|
+
|
|
149
|
+
@staticmethod
|
|
150
|
+
def _extract_file_content(file_content: str, is_encoded: bool = False) -> bytes:
|
|
151
|
+
"""
|
|
152
|
+
Extracts file content from the **malware-sample** MISP entity
|
|
153
|
+
|
|
154
|
+
:param file_content: Base64 file content
|
|
155
|
+
:param is_encoded: Marks if **malware-sample** or **attachment** entity received
|
|
156
|
+
:return: File bytes payload
|
|
157
|
+
"""
|
|
158
|
+
data = base64.b64decode(file_content)
|
|
159
|
+
|
|
160
|
+
if is_encoded:
|
|
161
|
+
with zipfile.ZipFile(io.BytesIO(data)) as file:
|
|
162
|
+
data = file.read(file.namelist()[0], pwd=b"infected")
|
|
163
|
+
|
|
164
|
+
return data
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import requests
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
from ._utils import utils
|
|
6
|
+
|
|
7
|
+
misperrors = {"error": "Error"}
|
|
8
|
+
|
|
9
|
+
# config fields that your code expects from the site admin
|
|
10
|
+
moduleconfig = {
|
|
11
|
+
"params": {
|
|
12
|
+
"nextcloud_baseurl": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "The Nexctloud domain or URL",
|
|
15
|
+
"value": "https://example.nextcloud.org:443",
|
|
16
|
+
},
|
|
17
|
+
"nextcloud_app_uuid_login": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "The nextcloud username",
|
|
20
|
+
},
|
|
21
|
+
"app_access_token": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "The nextcloud application token",
|
|
24
|
+
},
|
|
25
|
+
"nextcloud_conversation_token": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "The token of the conversation the message should be sent to",
|
|
28
|
+
},
|
|
29
|
+
"message_template": {
|
|
30
|
+
"type": "large_string",
|
|
31
|
+
"description": "The template to be used to generate the message to be posted",
|
|
32
|
+
"value": "The **template** will be rendered using *Jinja2*!",
|
|
33
|
+
"jinja_supported": True,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
# Blocking modules break the exection of the current of action
|
|
37
|
+
"blocking": False,
|
|
38
|
+
# Indicates whether parts of the data passed to this module should be filtered. Filtered data can be found under the `filteredItems` key
|
|
39
|
+
"support_filters": True,
|
|
40
|
+
# Indicates whether the data passed to this module should be compliant with the MISP core format
|
|
41
|
+
"expect_misp_core_format": False,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# returns either "boolean" or "data"
|
|
46
|
+
# Boolean is used to simply signal that the execution has finished.
|
|
47
|
+
# For blocking modules the actual boolean value determines whether we break execution
|
|
48
|
+
returns = "boolean"
|
|
49
|
+
|
|
50
|
+
moduleinfo = {
|
|
51
|
+
"version": "0.1",
|
|
52
|
+
"author": "Jeroen Pinoy",
|
|
53
|
+
"description": "Simplistic module to send a message to a Nextcloud talk conversation.",
|
|
54
|
+
"module-type": ["action"],
|
|
55
|
+
"name": "Nextcloud talk",
|
|
56
|
+
"logo": "",
|
|
57
|
+
"requirements": [],
|
|
58
|
+
"features": "",
|
|
59
|
+
"references": [],
|
|
60
|
+
"input": "",
|
|
61
|
+
"output": "",
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def createPost(request):
|
|
66
|
+
params = request["params"]
|
|
67
|
+
nextcloud_baseurl = params["nextcloud_baseurl"]
|
|
68
|
+
nextcloud_conversation_token = params["nextcloud_conversation_token"]
|
|
69
|
+
|
|
70
|
+
# Construct the API endpoint
|
|
71
|
+
endpoint = f"{nextcloud_baseurl}/ocs/v2.php/apps/spreed/api/v1/chat/{nextcloud_conversation_token}"
|
|
72
|
+
|
|
73
|
+
# Headers required for the API call
|
|
74
|
+
headers = {
|
|
75
|
+
'OCS-APIRequest': 'true',
|
|
76
|
+
'Accept': 'application/json',
|
|
77
|
+
'Content-Type': 'application/json'
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
data = {}
|
|
81
|
+
if "matchingData" in request:
|
|
82
|
+
data = request["matchingData"]
|
|
83
|
+
else:
|
|
84
|
+
data = request["data"]
|
|
85
|
+
|
|
86
|
+
if params["message_template"]:
|
|
87
|
+
message = utils.renderTemplate(data, params["message_template"])
|
|
88
|
+
else:
|
|
89
|
+
message = "```\n{}\n```".format(json.dumps(data))
|
|
90
|
+
|
|
91
|
+
# Message data
|
|
92
|
+
message_data = {
|
|
93
|
+
'message': message
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
# Make POST request to send message
|
|
98
|
+
requests.post(
|
|
99
|
+
endpoint,
|
|
100
|
+
headers=headers,
|
|
101
|
+
auth=(params["nextcloud_app_uuid_login"], params["app_access_token"]),
|
|
102
|
+
json=message_data
|
|
103
|
+
)
|
|
104
|
+
return True
|
|
105
|
+
except requests.exceptions.RequestException:
|
|
106
|
+
return True
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def handler(q=False):
|
|
110
|
+
if q is False:
|
|
111
|
+
return False
|
|
112
|
+
request = json.loads(q)
|
|
113
|
+
createPost(request)
|
|
114
|
+
r = {"data": True}
|
|
115
|
+
return r
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def introspection():
|
|
119
|
+
modulesetup = {}
|
|
120
|
+
try:
|
|
121
|
+
modulesetup["config"] = moduleconfig
|
|
122
|
+
except NameError:
|
|
123
|
+
pass
|
|
124
|
+
return modulesetup
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def version():
|
|
128
|
+
moduleinfo["config"] = moduleconfig
|
|
129
|
+
return moduleinfo
|