Hello guys I have a problem with Scapy in Python 3 on Windows 10. I tried to send a Ping (ICMP) request to my default-gateway. This is the packet command:
p = IP(dst='10.0.0.138')/ICMP(type='echo-request')/Raw('Hello')
But after I write r = sr1(ping) the program is stuck on this output:
Begin emission:
Finished sending 1 packets.
I used Wireshark to check the packets and I saw the both packets: Request and response. What do I do wrong? This has been working for me for whole life until now.
Edit: I am using the Scapy-Shell right now.
the problem is solved, I just needed to give networks privileges to the Python Interpreter. Thanks for all your help.
Python Version: 3.8.1
Scapy Version: 2.4.3
Where Working?
It is working fine with a single IP address.
Where Not Working?
When passing the IP range in the constructor, it never worked.
But when we assign IP range, it works sometimes.
Tried Methods?
tried in the script, like
from scapy.all import ARP
arp_request = ARP()
arp_request.pdst = ip
print(arp_request.summary())
tried in terminal using scapy, whose screenshot attached above
I know the question is already been asked on
Scapy ARP function not giving proper output when running it
But it has no answers.
EDIT:
I tried to analyze packets sent by the main device using Wireshark on one of the devices present in the network.
I find that in spite of showing range as ??, sometime ARP request covers whole range 0-256 and programs stop successfully.
But sometimes it stops at 192.168.43.170 and keeps sending the request for 192.168.43.1. And this also blocks the internet.
I don't know why at 192.168.43.170 because my gateway is at 192.168.43.1 and devices are at 192.168.43.98 and 192.168.43.198
Wireshark Output
This was a bug in scapy
Bug:
https://github.com/secdev/scapy/issues/2400
Which fixed recently
Fix:
https://github.com/secdev/scapy/pull/2395
Latest code.
https://github.com/secdev/scapy
I followed the Scapy tutorial and sent a ping packet to a website.
In WireShark, I got the reply packets immediately. But not in scapy python shell.
I built a IP/ICMP packet and sent it with sr() but the only thing I got was endless packet reception.
>>> conf.iface = <NetworkInterface [Npcap Loopback Adapter] ...>
...
>>> p = IP(dst='www.bilibili.com')/ICMP()
>>> res = sr(p)
Scapy tutorial says I can get a normal answer, but actually I got endless dots
Begin emission:
Finished sending 1 packets..
...............................................
(ctrl + c)
Received 36 packets, got 0 answers, remaining 1 packets
the interface you are using is the loopback one = only local packets. check IFACES.show() for the others. My guess would be that you're missing an installation step.
the answer is never received
you could add a timeout=... to sr()
Ok, I realize this situation is somewhat unusual, but I need to establish a TCP connection (the 3-way handshake) using only raw sockets (in C, in linux) -- i.e. I need to construct the IP headers and TCP headers myself. I'm writing a server (so I have to first respond to the incoming SYN packet), and for whatever reason I can't seem to get it right. Yes, I realize that a SOCK_STREAM will handle this for me, but for reasons I don't want to go into that isn't an option.
The tutorials I've found online on using raw sockets all describe how to build a SYN flooder, but this is somewhat easier than actually establishing a TCP connection, since you don't have to construct a response based on the original packet. I've gotten the SYN flooder examples working, and I can read the incoming SYN packet just fine from the raw socket, but I'm still having trouble creating a valid SYN/ACK response to an incoming SYN from the client.
So, does anyone know a good tutorial on using raw sockets that goes beyond creating a SYN flooder, or does anyone have some code that could do this (using SOCK_RAW, and not SOCK_STREAM)? I would be very grateful.
MarkR is absolutely right -- the problem is that the kernel is sending reset packets in response to the initial packet because it thinks the port is closed. The kernel is beating me to the response and the connection dies. I was using tcpdump to monitor the connection already -- I should have been more observant and noticed that there were TWO replies one of which was a reset that was screwing things up, as well as the response my program created. D'OH!
The solution that seems to work best is to use an iptables rule, as suggested by MarkR, to block the outbound packets. However, there's an easier way to do it than using the mark option, as suggested. I just match whether the reset TCP flag is set. During the course of a normal connection this is unlikely to be needed, and it doesn't really matter to my application if I block all outbound reset packets from the port being used. This effectively blocks the kernel's unwanted response, but not my own packets. If the port my program is listening on is 9999 then the iptables rule looks like this:
iptables -t filter -I OUTPUT -p tcp --sport 9999 --tcp-flags RST RST -j DROP
You want to implement part of a TCP stack in userspace... this is ok, some other apps do this.
One problem you will come across is that the kernel will be sending out (generally negative, unhelpful) replies to incoming packets. This is going to screw up any communication you attempt to initiate.
One way to avoid this is to use an IP address and interface that the kernel does not have its own IP stack using- which is fine but you will need to deal with link-layer stuff (specifically, arp) yourself. That would require a socket lower than IPPROTO_IP, SOCK_RAW - you need a packet socket (I think).
It may also be possible to block the kernel's responses using an iptables rule- but I rather suspect that the rules will apply to your own packets as well somehow, unless you can manage to get them treated differently (perhaps applying a netfilter "mark" to your own packets?)
Read the man pages
socket(7)
ip(7)
packet(7)
Which explain about various options and ioctls which apply to types of sockets.
Of course you'll need a tool like Wireshark to inspect what's going on. You will need several machines to test this, I recommend using vmware (or similar) to reduce the amount of hardware required.
Sorry I can't recommend a specific tutorial.
Good luck.
I realise that this is an old thread, but here's a tutorial that goes beyond the normal SYN flooders: http://www.enderunix.org/docs/en/rawipspoof/
Hope it might be of help to someone.
I can't help you out on any tutorials.
But I can give you some advice on the tools that you could use to assist in debugging.
First off, as bmdhacks has suggested, get yourself a copy of wireshark (or tcpdump - but wireshark is easier to use). Capture a good handshake. Make sure that you save this.
Capture one of your handshakes that fails. Wireshark has quite good packet parsing and error checking, so if there's a straightforward error it will probably tell you.
Next, get yourself a copy of tcpreplay. This should also include a tool called "tcprewrite".
tcprewrite will allow you to split your previously saved capture files into two - one for each side of the handshake.
You can then use tcpreplay to play back one side of the handshake so you have a consistent set of packets to play with.
Then you use wireshark (again) to check your responses.
I don't have a tutorial, but I recently used Wireshark to good effect to debug some raw sockets programming I was doing. If you capture the packets you're sending, wireshark will do a good job of showing you if they're malformed or not. It's useful for comparing to a normal connection too.
There are structures for IP and TCP headers declared in netinet/ip.h & netinet/tcp.h respectively. You may want to look at the other headers in this directory for extra macros & stuff that may be of use.
You send a packet with the SYN flag set and a random sequence number (x). You should receive a SYN+ACK from the other side. This packet will have an acknowledgement number (y) that indicates the next sequence number the other side is expecting to receive as well as another sequence number (z). You send back an ACK packet that has sequence number x+1 and ack number z+1 to complete the connection.
You also need to make sure you calculate appropriate TCP/IP checksums & fill out the remainder of the header for the packets you send. Also, don't forget about things like host & network byte order.
TCP is defined in RFC 793, available here: http://www.faqs.org/rfcs/rfc793.html
Depending on what you're trying to do it may be easier to get existing software to handle the TCP handshaking for you.
One open source IP stack is lwIP (http://savannah.nongnu.org/projects/lwip/) which provides a full tcp/ip stack. It is very possible to get it running in user mode using either SOCK_RAW or pcap.
if you are using raw sockets, if you send using different source mac address to the actual one, linux will ignore the response packet and not send an rst.
Having issues with a get_mac function i created below, which takes an IP Address and finds its mac address, returning it or None.
The actual python function is:
def get_mac(ip_addr):
"get_mac is used to obtain the mac address of the target ip."
print "Getting Mac for: %s" % ip_addr
responses, unanswered = srp(Ether(dst="de:ad:be:ef:ca:fe")/ARP(pdst=ip_addr),timeout=2,retry=10)
for s,r in responses:
return r[Ether].src
return None
Im thinking that there may be a better way to do this. This was taken out of the Black Hat Python book, and im leveraging the imports:
from scapy.all import *
from scapy.base_classes import Gen, SetGen
import scapy.plist as plist
from scapy.utils import PcapReader
from scapy.data import MTU, ETH_P_ARP
import os
import sys
import threading
import signal
for my entire file file I have been working ith. I was working on creating a custom tool for a very fine tuned purpose. I was running it against my buddy to by way of ipconfig told me his IP was 192.168.0.20 so when running against that, i could see the console outputting this information.
....
Begin emission:
Finished to send 1 packets.
Received 12 packets, got 0 answers, remaining 1 packets
....
12 times and then printed what i told it to since it returned none.
! Failed to find Target Mac
Is this the right course of action? Did my buddy send me the wrong IP address? I think i saw him give me the ipv4 in ipconfig
I guess iam curious if there is a better way then the srp() function i ended up calling.
The base sample I was working with was page 52 of BlackhatPython called: ARP Cache Poisoning via Scapy.
Assuming that you're just trying to implement an ARP request, then the request should be sent to the MAC broadcast address (FF-FF-FF-FF-FF-FF). You should be filling in your own NIC's MAC address as the source address, both in the Ethernet header, and as the ARP sender-MAC address.
The way ARP typically works is that a broadcast message is sent to the local network, in essence saying "Hey everybody, who has IP address N.N.N.N? Tell me <my MAC address>." It typically also includes the sender's IP address, which in effect says "And oh, by the way, my IP address is M.M.M.M."
The response is then usually sent via unicast back to the requester which is why you need to fill in your own MAC as the sender address: so that you get the response.
There are other ARP usages wherein the "who has?" part is a dummy, and the "oh, by the way, my address is..." is the main goal -- that's known as gratuitous ARP since it's often sent without a preceding request and is essentially just announcing the sender's own IP/MAC association.
(It doesn't appear that you meant to ask about ARP cache poisoning, but that's essentially just lying about the "oh, by the way" clause. Either with the wrong MAC address or a completely bogus one.)
The scapy srp function is fine for doing this. Probably the easiest way to implement it in python.