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

如何用Python构建ICMP报文?基于Scapy实现ICMP/DNS隐式传文件

Hey there! Let's break this down step by step since you're working on a class assignment with Scapy—super cool project idea, by the way. I'll cover both building ICMP packets and walking you through the basics of covert file transfer using ICMP/DNS payloads.

1. 如何用Python+Scapy构建ICMP报文?

First, make sure you've got Scapy installed:

pip install scapy

Scapy makes packet building ridiculously straightforward—you just stack layers. Here's a simple example to build and send an ICMP Echo Request (ping) packet:

from scapy.all import IP, ICMP, send

# Build the packet: IP layer + ICMP layer
ip_layer = IP(dst="192.168.1.1")  # Replace with your target IP
icmp_layer = ICMP()  # Default is Echo Request (type 8, code 0)
packet = ip_layer / icmp_layer

# Optional: Add custom payload to the ICMP packet
packet = packet / "This is my custom ICMP payload!"

# Send the packet
send(packet, verbose=0)  # verbose=0 turns off extra output

To receive ICMP packets and inspect their content, use Scapy's sniff() function:

from scapy.all import sniff, ICMP

def icmp_callback(packet):
    if packet.haslayer(ICMP):
        # Check if it's an Echo Reply (type 0)
        if packet[ICMP].type == 0:
            print(f"Received ICMP reply from {packet[IP].src}")
            print(f"Payload: {packet[ICMP].payload.load.decode('utf-8', errors='ignore')}")

# Start sniffing ICMP packets (requires elevated privileges)
sniff(prn=icmp_callback, filter="icmp", store=0)

Note: On Linux/macOS, run this with sudo; on Windows, open your terminal as Administrator—raw packet access needs elevated permissions.

2. 基于ICMP/DNS载荷的隐式文件传输入门指导

Your project's core logic is solid: split a file into chunks, embed each chunk into a packet payload, send them over, then reassemble the file on the receiving end. Let's start with ICMP (it's simpler) then touch on DNS.

2.1 ICMP File Transfer: Sender Side

The sender needs to:

  • Read the target file in small chunks
  • Assign a sequence number to each chunk (so the receiver can reorder correctly)
  • Pack the sequence number + chunk data into the ICMP payload
  • Send each packet to the receiver's IP
  • Send a "termination" packet to signal the end of transfer

Here's a minimal working example:

from scapy.all import IP, ICMP, send
import struct

def send_file_via_icmp(file_path, dst_ip, chunk_size=100):
    with open(file_path, "rb") as f:
        seq_num = 0
        while True:
            chunk = f.read(chunk_size)
            if not chunk:
                break  # End of file reached
            # Pack sequence number (4 bytes, big-endian) + chunk data
            payload = struct.pack(">I", seq_num) + chunk
            # Build and send the packet
            packet = IP(dst=dst_ip) / ICMP() / payload
            send(packet, verbose=0)
            seq_num += 1
        # Send termination packet (seq_num = -1 encoded as 0xFFFFFFFF)
        termination_payload = struct.pack(">I", 0xFFFFFFFF)
        send(IP(dst=dst_ip) / ICMP() / termination_payload, verbose=0)

# Usage: Replace with your file path and receiver IP
send_file_via_icmp("secret_file.txt", "192.168.1.100")

2.2 ICMP File Transfer: Receiver Side

The receiver needs to:

  • Sniff incoming ICMP packets
  • Extract the sequence number and chunk data from each payload
  • Store chunks in a dictionary keyed by sequence number
  • Once the termination packet is received, sort chunks and write to file

Example code:

from scapy.all import sniff, ICMP, IP
import struct

received_chunks = {}

def icmp_file_receiver(packet):
    global received_chunks
    # Listen for Echo Requests (we're using these to carry data)
    if packet.haslayer(ICMP) and packet[ICMP].type == 8:
        payload = packet[ICMP].payload.load
        # Unpack sequence number (first 4 bytes of payload)
        seq_num = struct.unpack(">I", payload[:4])[0]
        
        if seq_num == 0xFFFFFFFF:
            # Termination signal received—reassemble the file
            print("Transfer complete! Reassembling file...")
            with open("received_file.txt", "wb") as f:
                for seq in sorted(received_chunks.keys()):
                    f.write(received_chunks[seq])
            print("File saved as received_file.txt")
            return True  # Stop sniffing after transfer finishes
        
        # Store the chunk data (skip the first 4 bytes which are the sequence number)
        received_chunks[seq_num] = payload[4:]
        print(f"Received chunk {seq_num}")

# Start sniffing ICMP packets
sniff(prn=icmp_file_receiver, filter="icmp", store=0, stop_filter=lambda p: icmp_file_receiver(p))

2.3 Quick Notes on DNS-Based Transfer

If you want to use DNS instead, the core idea is similar but uses DNS query/response payloads (like TXT records):

  • Sender: Split the file into chunks, encode each chunk as a TXT record string, send DNS queries to a dummy domain (e.g., chunk-123.example.com where 123 is the sequence number)
  • Receiver: Sniff DNS packets, extract the TXT record data from incoming queries/responses, then reassemble the file

Here's a quick snippet to build a DNS query with a custom payload using Scapy:

from scapy.all import IP, UDP, DNS, DNSQR

# Embed chunk data in the DNS query's QNAME
chunk_data = "a1b2c3"
dns_query = IP(dst="8.8.8.8") / UDP(dport=53) / DNS(rd=1, qd=DNSQR(qname=f"{chunk_data}.example.com"))
send(dns_query, verbose=0)

Note: DNS has stricter payload limits (TXT records max 255 bytes per string, QNAME has length restrictions), so you'll need smaller chunks or split data across multiple records.

Key Tips for Your Assignment

  • Test in a controlled environment: Firewalls often block ICMP or unsolicited DNS traffic—use a local network (e.g., two VMs or your own machine sending to itself)
  • Add error checking: Include checksums for each chunk to detect corrupted data
  • Handle retransmissions: Optional, but adding a way for the receiver to request missing chunks will make your project more robust
  • Document your code: Since it's a class assignment, explain each part clearly so your instructor understands your logic

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:57:14