diff --git a/src/maltest/tests/test_icsnpp_protocols.py b/src/maltest/tests/test_icsnpp_protocols.py new file mode 100644 index 0000000..1a425fe --- /dev/null +++ b/src/maltest/tests/test_icsnpp_protocols.py @@ -0,0 +1,139 @@ +import logging +import mmguero +import requests + +UPLOAD_ARTIFACTS = [ + 'Protocols/BACnet.pcap', + 'Protocols/BSAP.pcap', + 'Protocols/DNP3.pcap', + 'Protocols/ENIP.pcap', + 'Protocols/ETHERCAT.pcap', + 'Protocols/GENISYS.pcap', + 'Protocols/hart-ip.pcap', + 'Protocols/hart-ip_all_messageIDs.pcap', + 'Protocols/hart-ip_all_types_and_commands_sent.pcap', + 'Protocols/hart-ip_publish_and_keepAlive.pcap', + 'Protocols/Modbus.pcap', + 'Protocols/MQTT.pcap', + 'Protocols/OPCUA-Binary.pcap', + 'Protocols/PROFINET.pcap', + 'Protocols/S7comm.pcap', + 'Protocols/Synchrophasor.pcap', + 'Protocols/TDS.pcap', +] + +# TODO: genisys is not enabled by default? +EXPECTED_DATASETS = [ + "bacnet", + "bacnet_device_control", + "bacnet_discovery", + "bacnet_property", + "bestguess", + "bsap_ip_header", + "bsap_ip_rdb", + "bsap_serial_header", + "bsap_serial_rdb", + "cip", + "cip_identity", + "cip_io", + "cotp", + "dnp3", + "dnp3_control", + "dnp3_objects", + "ecat_aoe_info", + "ecat_coe_info", + "ecat_dev_info", + "ecat_log_address", + "ecat_registers", + "enip", + "hart_ip", + "hart_ip_common_commands", + "hart_ip_direct_pdu_command", + "hart_ip_session_record", + "hart_ip_universal_commands", + "known_modbus", + "modbus", + "modbus_detailed", + "modbus_mask_write_register", + "modbus_read_device_identification", + "modbus_read_write_multiple_registers", + "mqtt_connect", + "mqtt_publish", + "mqtt_subscribe", + "opcua_binary", + "opcua_binary_activate_session", + "opcua_binary_activate_session_locale_id", + "opcua_binary_browse", + "opcua_binary_browse_description", + "opcua_binary_browse_request_continuation_point", + "opcua_binary_browse_response_references", + "opcua_binary_browse_result", + "opcua_binary_close_session", + "opcua_binary_create_monitored_items", + "opcua_binary_create_monitored_items_create_item", + "opcua_binary_create_session", + "opcua_binary_create_session_discovery", + "opcua_binary_create_session_endpoints", + "opcua_binary_create_session_user_token", + "opcua_binary_create_subscription", + "opcua_binary_diag_info_detail", + "opcua_binary_get_endpoints", + "opcua_binary_get_endpoints_description", + "opcua_binary_get_endpoints_discovery", + "opcua_binary_get_endpoints_locale_id", + "opcua_binary_get_endpoints_profile_uri", + "opcua_binary_get_endpoints_user_token", + "opcua_binary_opensecure_channel", + "opcua_binary_read", + "opcua_binary_read_nodes_to_read", + "opcua_binary_read_results", + "opcua_binary_status_code_detail", + "opcua_binary_variant_array_dims", + "opcua_binary_variant_data", + "opcua_binary_variant_data_value", + "opcua_binary_variant_extension_object", + "opcua_binary_variant_metadata", + "opcua_binary_write", + "profinet", + "profinet_io_cm", + "s7comm", + "s7comm_plus", + "s7comm_read_szl", + "s7comm_upload_download", + "synchrophasor", + "synchrophasor_cfg", + "synchrophasor_cmd", + "synchrophasor_hdr", + "tds", + "tds_rpc", + "tds_sql_batch", +] + +LOGGER = logging.getLogger(__name__) + +HEADERS = {"Content-Type": "application/json"} + + +def test_icsnpp_protocols( + malcolm_http_auth, + malcolm_url, + pcap_hash_map, +): + assert all([pcap_hash_map.get(x, None) for x in mmguero.GetIterable(UPLOAD_ARTIFACTS)]) + + response = requests.post( + f"{malcolm_url}/mapi/agg/event.dataset", + headers=HEADERS, + json={ + "from": "0", + "filter": {"event.provider": "zeek"}, + }, + allow_redirects=True, + auth=malcolm_http_auth, + verify=False, + ) + response.raise_for_status() + buckets = { + item['key']: item['doc_count'] for item in mmguero.DeepGet(response.json(), ['event.dataset', 'buckets'], []) + } + assert all([(buckets.get(x, 0) > 0) for x in EXPECTED_DATASETS]) diff --git a/src/maltest/tests/test_malcolm_pcap.py b/src/maltest/tests/test_malcolm_pcap.py new file mode 100644 index 0000000..9ceba59 --- /dev/null +++ b/src/maltest/tests/test_malcolm_pcap.py @@ -0,0 +1,103 @@ +import mmguero + +UPLOAD_ARTIFACTS = [ + 'CTF/malcolm-micro-ctf.pcap', + 'Cyberville/Cyberville.pcap', + 'Plugins/2015-04-09-Nuclear-EK-traffic.pcap', + 'Plugins/2021-12-11-thru-13-server-activity-with-log4j-attempts.pcap', + 'Plugins/6in4-linklocal-hlimit-less255.pcap', + 'Plugins/apache_exploit_success.pcap', + 'Plugins/broken.pcap', + 'Plugins/chrome-34-google.trace', + 'Plugins/CVE-2020-1472_exploit_win2016.pcap', + 'Plugins/CVE-2020-1472_exploit_win2019.pcap', + 'Plugins/CVE-2020-1472_test_win2016.pcap', + 'Plugins/CVE-2020-1472_test_win2019.pcap', + 'Plugins/CVE-2021-38647-exploit-craigmunsw-omigod-lab.pcap', + 'Plugins/cve-2022-26809-4.pcap', + 'Plugins/doublepulsar-backdoor-connect-win7.pcap', + 'Plugins/download_over_dns.pcap', + 'Plugins/ecdsa-cert.pcap', + 'Plugins/esteemedaudit-failed-XPSP2.pcap', + 'Plugins/eternalblue-failed-patched-win7.pcap', + 'Plugins/eternalblue-success-unpatched-win7.pcap', + 'Plugins/eternalchampion.pcap', + 'Plugins/eternalromance-doublepulsar-meterpreter.pcap', + 'Plugins/eternalromance-success-2008r2.pcap', + 'Plugins/explicit.pcap', + 'Plugins/exploit.pcap', + 'Plugins/favicon.pcap', + 'Plugins/gnutls-tls1.2-non-vulnerable.pcap', + 'Plugins/gnutls-tls1.2-vulnerable.pcap', + 'Plugins/gnutls-tls1.3.pcap', + 'Plugins/http-etag-and-filename.pcap', + 'Plugins/http-filename-and-etag.pcap', + 'Plugins/http-filename.pcap', + 'Plugins/http_post.trace', + 'Plugins/http.trace', + 'Plugins/ipv6-neighbor-discovery.pcap', + 'Plugins/ipv6-router-advertisement-leaving.pcap', + 'Plugins/log4j-attack.pcap', + 'Plugins/log4j-dns_exfil.pcap', + 'Plugins/log4j-user_agent.pcap', + 'Plugins/log4j-webapp.pcap', + 'Plugins/metasploit-ms017-010-win7x64.pcap', + 'Plugins/pi3_poc.pcap', + 'Plugins/quasarrat.pcap', + 'Plugins/RS-RA.pcap', + 'Plugins/sample_OpenSSLv3.0.5.pcap', + 'Plugins/smb_mimikatz_copy_to_host.pcap', + 'Plugins/spcap-CEXKLs3NQWdEM2CoMj-1639421287179170294-1.pcap', + 'Plugins/spookyssl-merged.pcap', + 'Plugins/wannacry.pcap', + 'Protocols/BACnet.pcap', + 'Protocols/BSAP.pcap', + 'Protocols/DCERPC.pcap', + 'Protocols/DHCP.pcap', + 'Protocols/DNP3.pcap', + 'Protocols/DNS.pcap', + 'Protocols/ENIP.pcap', + 'Protocols/ETHERCAT.pcap', + 'Protocols/FTP.pcap', + 'Protocols/GENISYS.pcap', + 'Protocols/HTTP_1.pcap', + 'Protocols/HTTP_2.pcap', + 'Protocols/IPsec.pcap', + 'Protocols/IRC.pcap', + 'Protocols/KRB5.pcap', + 'Protocols/LDAP.pcap', + 'Protocols/Modbus.pcap', + 'Protocols/MQTT.pcap', + 'Protocols/MySQL.pcap', + 'Protocols/NTLM.pcap', + 'Protocols/NTP.pcap', + 'Protocols/OPCUA-Binary.pcap', + 'Protocols/OpenVPN.pcap', + 'Protocols/OSPF.pcap', + 'Protocols/PROFINET.pcap', + 'Protocols/QUIC.pcap', + 'Protocols/RADIUS.pcap', + 'Protocols/RDP.pcap', + 'Protocols/RFB.pcap', + 'Protocols/S7comm.pcap', + 'Protocols/SIP.pcap', + 'Protocols/SMB.pcap', + 'Protocols/SMTP.pcap', + 'Protocols/SNMP.pcap', + 'Protocols/SSH.pcap', + 'Protocols/SSL.pcap', + 'Protocols/STUN.pcap', + 'Protocols/Synchrophasor.pcap', + 'Protocols/Syslog.pcap', + 'Protocols/TDS.pcap', + 'Protocols/Telnet.pcap', + 'Protocols/TFTP.pcap', + 'Protocols/Tunnels.pcap', + 'Protocols/WireGuard.pcap', +] + + +def test_malcolm_pcap_hash( + pcap_hash_map, +): + assert all([pcap_hash_map.get(x, None) for x in mmguero.GetIterable(UPLOAD_ARTIFACTS)])