You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby UDP:发送数据包时如何伪造IP地址与端口号?

Great question! The short answer is yes, you can forge the source IP address and port in UDP packets—but it requires working at a lower level than standard UDP sockets, and comes with important caveats around permissions, network behavior, and legality. Let’s break this down:

1. Why UDP Makes Forging Possible

UDP is a connectionless protocol, so unlike TCP, there’s no handshake to validate the source address. You can manually construct the entire IP and UDP headers, including the source IP/port, instead of relying on the OS to populate these fields automatically.

2. How to Implement It

To forge source details, you need to use raw sockets instead of standard UDP sockets. Raw sockets let you craft custom IP and transport layer headers. Here’s how it works across major OSes:

Linux/macOS

You’ll need root privileges to create a raw socket. Enable the IP_HDRINCL option to tell the OS you’re providing your own IP header, then manually populate the IP and UDP header fields.

Here’s a minimal C example:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <arpa/inet.h>

// Helper function to calculate IP/UDP checksums
unsigned short checksum(unsigned short *buf, int nwords) {
    unsigned long sum = 0;
    for (; nwords > 0; nwords--)
        sum += *buf++;
    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    return (unsigned short)(~sum);
}

int main() {
    // Create raw socket for UDP
    int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
    if (sockfd < 0) {
        perror("Failed to create raw socket (need root?)");
        exit(EXIT_FAILURE);
    }

    // Tell OS we'll handle IP header construction
    int optval = 1;
    setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(optval));

    char buffer[4096];
    memset(buffer, 0, sizeof(buffer));

    // Pointers to IP header, UDP header, and payload
    struct iphdr *ip = (struct iphdr *)buffer;
    struct udphdr *udp = (struct udphdr *)(buffer + sizeof(struct iphdr));
    char *data = buffer + sizeof(struct iphdr) + sizeof(struct udphdr);
    strcpy(data, "Forged UDP test packet");

    // Populate IP header
    ip->ihl = 5;
    ip->version = 4;
    ip->tos = 0;
    ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr) + strlen(data));
    ip->id = htons(12345);
    ip->frag_off = 0;
    ip->ttl = 64;
    ip->protocol = IPPROTO_UDP;
    ip->check = 0; // Calculated later
    ip->saddr = inet_addr("192.168.1.100"); // Forged source IP
    ip->daddr = inet_addr("192.168.1.200"); // Target IP

    // Populate UDP header
    udp->source = htons(54321); // Forged source port
    udp->dest = htons(12345); // Target port
    udp->len = htons(sizeof(struct udphdr) + strlen(data));
    udp->check = 0; // Optional: some systems skip UDP checksum validation

    // Calculate IP checksum
    ip->check = checksum((unsigned short *)buffer, ip->tot_len >> 1);

    // Send the forged packet
    struct sockaddr_in dest_addr;
    memset(&dest_addr, 0, sizeof(dest_addr));
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_addr.s_addr = ip->daddr;

    if (sendto(sockfd, buffer, ntohs(ip->tot_len), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) < 0) {
        perror("Failed to send packet");
        exit(EXIT_FAILURE);
    }

    close(sockfd);
    printf("Forged UDP packet sent!\n");
    return 0;
}

Compile with gcc fake_udp.c -o fake_udp, then run with sudo ./fake_udp (root is required).

Windows

Similar to Linux, you need administrator rights. Windows restricts raw sockets slightly (e.g., TCP forging is blocked), but UDP is allowed. You’ll use socket(AF_INET, SOCK_RAW, IPPROTO_UDP) and manually build headers, just like on Unix-like systems. Note that some Windows versions may require registry tweaks to enable full raw socket access.

3. Critical Caveats

  • Permissions: You must run your program as root (Linux/macOS) or Administrator (Windows)—standard user accounts don’t have access to raw sockets.
  • Network Filters: Many routers and firewalls use Reverse Path Forwarding (RPF) to drop packets with source IPs that don’t match the expected incoming interface. Your forged packet might never reach the target.
  • Reply Handling: If the target server sends a response, it will be sent to the forged source IP/port—not your actual client. Unless you control that IP/port (which you probably don’t), you’ll never receive the reply.
  • Legality/Ethics: Forging source IPs can be used for malicious purposes (e.g., DDoS attacks, spoofing). Make sure you’re only doing this in a controlled, authorized environment (like your own test network) and comply with local laws.

4. Alternatives If You Don’t Want Raw Sockets

If you just need to test how a server handles unexpected source addresses, tools like hping3 (Linux) or Nmap can send forged UDP packets without writing code. But if you need to integrate this into your own application, raw sockets are the way to go.

内容的提问来源于stack exchange,提问作者Nick Shears

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:31:18