Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Talking to C socket with Scapy

I have a UDP connection up and listening on a port (localhost) and I am trying to send a Scapy packet from localhost as well. For some reason, my C code never actually captures the packet, however I can see the packet show up in Wireshark just fine. It's been awhile since I've used sockets, but is there some special socket options I have to set or why would I be able to see the packet in Wireshark just fine but not by the C socket?

Note: I was able to successfully catch a packet when I wrote corresponding socket code to send out packets (from localhost) however I am still unable to get the listening code to catch the packet when sent from another computer.

I have found a similar question but when I tried their approach (using UDP instead of TCP), I still couldn't get netcat to catch the Scapy packet.

C Code (condensed for clarity sake)

int main() {
    int sock, dataLen, inLen;
    struct sockaddr_in inAddr;
    short listen_port = 8080;
    char buffer[2048];

    if (sock = socket(AF_INET,SOCK_DGRAM,0) < 0) {
        printf("ERROR: unable to establish socket\n");
    return -1;
    }

    // zero out address structure
    memset(&inAddr, 0, sizeof(inAddr));

    inAddr.sin_family = AF_INET;
    inAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    inAddr.sin_port = htons(listen_port);

    if (bind(sock, (struct sockaddr*)&inAddr, sizeof(inAddr)) < 0) {
    printf("ERROR: unable to bind\n");
    return -1;
    }

    inLen = sizeof(inAddr);

    printf("Now listening on port %d\n", listen_port);
    while(1) {
    dataLen = recvfrom(sock, buffer, 1500, 0, (struct sockaddr*)&inAddr, &inLen);

    if (dataLen < 0)
        printf("Error receiving datagram\n");
    else
        printf("Received packet of length %d\n", dataLen);

    }
    return 0;
}

Scapy Script

# set interface
conf.iface="lo0"

# create IP packet
ip_pkt = IP()/UDP()
ip_pkt.payload = "payload test message"
ip_pkt.dport = 8080
ip_pkt.dst = "127.0.0.1"
ip_pkt.src = "127.0.0.1"

# send out packet
send(ip_pkt)
like image 500
Josh Bradley Avatar asked Jul 16 '13 22:07

Josh Bradley


2 Answers

Scapy needs to be configured slightly differently to work on the Loopback interface, see http://www.secdev.org/projects/scapy/doc/troubleshooting.html under the heading "I can’t ping 127.0.0.1. Scapy does not work with 127.0.0.1 or on the loopback interface"

I used the code given there and sent a scapy packet which was received by a C Socket, this was specifically:

from scapy.all import *
conf.L3socket=L3RawSocket
packet=IP()/UDP(dport=32000)/"HELLO WORLD"
send(packet)

This was then received on a UDP C Socket bound to lo on port 32000 (Scapy defaults to sending IP packets over the loopback interface).

like image 106
Eosis Avatar answered Oct 02 '22 03:10

Eosis


I have the same problem, udp socket does not receive scapy packet. I suppose there might be something related to this post: Raw Socket Help: Why UDP packets created by raw sockets are not being received by kernel UDP? And what works for me is the socket.IP_HDRINCL option. Here is the working code for both and sender.

sender:

import socket
from scapy.all import *

rawudp=socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
rawudp.bind(('0.0.0.0',56789))
rawudp.setsockopt(socket.SOL_IP, socket.IP_HDRINCL,1)

pkt = IP()/UDP(sport=56789, dport=7890)/'hello'

rawudp.sendto(pkt.build(), ('127.0.0.1',7890))

receiver:

import socket
so = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
so.bind(('0.0.0.0',7890))
while True:
    print so.recv(1024)

Verified on Fedora 14, although doesn't work on my MBP...

like image 45
赵伟辰 Avatar answered Oct 02 '22 02:10

赵伟辰