I recently began exploring Scapy. A wonderful tool indeed!
I have a problem... When I monitor my network card using Wireshark and I do a regular ping from the systems command prompt with the standard PING installation, wireshark pops up with "Ping request" and then "Ping reply" indication that it sent a reply. But when i do it manually in Scapy, it sends no reply back.. How can this be? I spent alot of time trying to figure this out so i really hope someone can shed some light on this issue of mine...
Here is the code i used:
>>> from scapy.all import IP, ICMP, send
>>> IP = IP(dst="127.0.0.1")
>>> Ping = ICMP()
>>> send(IP/Ping)
The packet is sent successfully and Wireshark shows a Ping request received, but not that it has sent a reply back.
This is an FAQ item:
I can't ping 127.0.0.1. Scapy does not work with 127.0.0.1 or on the loopback interface
The loopback interface is a very special interface. Packets going through it are not really assembled and dissassembled. The kernel routes the packet to its destination while it is still stored an internal structure. What you see with tcpdump -i lo is only a fake to make you think everything is normal. The kernel is not aware of what Scapy is doing behind his back, so what you see on the loopback interface is also a fake. Except this one did not come from a local structure. Thus the kernel will never receive it.
In order to speak to local applications, you need to build your packets one layer upper, using a PF_INET/SOCK_RAW socket instead of a PF_PACKET/SOCK_RAW (or its equivalent on other systems that Linux) :
>>> conf.L3socket
<class __main__.L3PacketSocket at 0xb7bdf5fc>
>>> conf.L3socket=L3RawSocket
>>> sr1(IP(dst="127.0.0.1")/ICMP())
<IP version=4L ihl=5L tos=0x0 len=28 id=40953 flags= frag=0L ttl=64 proto=ICMP chksum=0xdce5 src=127.0.0.1 dst=127.0.0.1 options='' |<ICMP type=echo-reply code=0 chksum=0xffff id=0x0 seq=0x0 |>>
Try this
def ping(host, repeat=3):
packet = IP(dst=host)/ICMP()
for x in range(repeat):
response = sr1(packet)
response.show2()
Your not storing the reply properly
Related
I am trying to send a udp packet to a local ip address. This is my example code:
from scapy.all import *
if __name__ == "__main__":
send(IP(dst="127.0.0.1")/UDP(sport=19600,dport=39600)/"abc")
I've started netcat to catch what I am going to send:
nc -ul 39600
Then I am executing the code:
python3 example_scapy_send.py
Nothing is received by the listening netcat.
At the same time I have started wireshark and I can see the packet is sent.
If I send a packet using netcat it is ariving on the listening netcat.
usr#dev:/home/usr# nc -u 127.0.0.1 39600
test
Wireshark:
The only difference I can see is that at layer 2 - destination address is multicast/broadcast when sent with scapy and unicast when sent with netcat. But this is not something I can control.
If I sent the same packet with scapy to another ip on the network (another host) the packet is received (by netcat). So the issue applies only if I am sending to a local address. Tested with any local ip. Not only 127.0.0.1. I've also tested with sendp and sr scapy functions but the result is the same.
Something more: if I've started another scapy script to listen to UDP/39600 (instead of netcat) I can see/I am receiving the packet I've sent.
Any ideas what is wrong?
tests done under ubuntu/scapy 2.5/python 3.8
I couldn't find a way to make it work with send/sendp scapy functions, but instead I tried using standart python socket and it did the job:
someSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
someSocket.sendto(bytes('abc', "utf-8"), (127.0.0.1, 39600))
Acording to Scapy troubleshooting:
The loopback interface is a very special interface. Packets going through it are not really assembled and disassembled. The kernel routes the packet to its destination while it is still stored an internal structure. What you see with tcpdump -i lo is only a fake to make you think everything is normal. The kernel is not aware of what Scapy is doing behind his back, so what you see on the loopback interface is also a fake. Except this one did not come from a local structure. Thus the kernel will never receive it.
On Linux, in order to speak to local IPv4 applications, you need to build your packets one layer upper, using a PF_INET/SOCK_RAW socket instead of a PF_PACKET/SOCK_RAW (or its equivalent on other systems than Linux)
So you may need to add line before sending packet:
conf.L3socket = L3RawSocket
In your script. That way everything should supposed to work. At least in my environment worked out fine.
I have tcpdump and scapy running sniff() on the same interface. There is a scp file transfer happening.
tcpdump: I see the tcp packets with the seq and acks going over.
scapy sniff() returned list: All I see in each packet summary() is (MAC addr1 ) > (Mac addr 2) (0x800) / Raw. Even in the packet .show(), all I see is a link layer stuff with "## [ Ethernet ] ##", src and dst.
I ran this with a timeout of 30 so I know I would capture the scp transfer of an empty text file so I know I timed it right.
There are definitely TCP packets going over, but none of them are being detected. Is there an issue with Scapy?
Thank you
There is probably a bug that prevents Scapy from processing the ethernet payload.
You can try to set conf.debug_dissector = True to debug the issue.
You can also get the current development version of Scapy (from the repository), since this may be an already fixed bug (we had a bug similar to what you are seeing with Python 3 until very recently).
If the bug still exists after updating to the current development version, please report it!
I am sending packets using:
send(IP(dst="192.168.1.114")/fuzz(UDP()/NTP(version=4)), loop=1)
But I am not able to capture these packets in any other nearby machine (including the one with IP 192.168.1.114) which is on the same network. I am using wlan as my interface.
I also tried to sniff and then replay using scapy but I am still not able to capture those packets.
i would first try to capture the traffic on the sender machine with tcpdump while executing your program:
tcpdump -i any udp dst 192.168.1.114
if you can see the traffic leaving the source host it may be that it does not arrive on the target host. UDP packets are the first packets to be dropped by any network device and as it is the nature of UDP it wont get retransmitted. if you are sure the packet leaves the source verify if it arrives at the target:
tcpdump -i any upd dst 192.168.1.114
Another point to check is your firewall settings. It could be either on the source or target system that your firewall is blocking those requests.
I finally resolved this. Here is the checklist I made which might help others when dealing with replaying/fuzzing using scapy.
Check if all IP addresses you are dealing with are alive in the
network (use ping)
Understand the difference between send() (layer 3)and sendp() (layer 2)
If mutating existing packet make sure to
remove the checksum (using 'del') and recalculate the checksum
either using show2() or using str to convert packets to string
and then converting them back to packets
You should use Wireshark, or the sniff function in Scapy and make it pretty print the contents on the screen:
sniff(lambda x:x.show())
I'm having trouble receiving all related packets to a request when using scapy's sr function.
ans, unans = sr(IP(dst="172.xxx.xxx.xxx")/TCP(dport=80,flags="S"))
returns:
Received 2 packets, got 1 answers, remaining 0 packets
What happens is that I first get an ICMP redirect. Afterwards I get the answer from my local service with SA. Sometimes it tells me it received two packets, which makes sense, but when I look at it in the summary it prints the following:
<bound method SndRcvList.summary of <Results: TCP:0 UDP:0 ICMP:1 Other:0>>
and in summary() I find this:
IP / TCP 172.xxx.xxx.xxx:ftp_data > 172.zzz.zzz.zzz:http S ==> IP / ICMP 172.yyy.yyy.yyy > 172.xxx.xxx.xxx redirect host-redirect / IPerror / TCPerror
For one, I wonder where my SA flagged TCP packet is. When I look at the network dump, I definitely see it, right after the ICMP packet. I've made sure to run scapy with and without running tcpdump, just in case it would interfere, which it shouldn't.
I've also tried to set and increased timeout, just in case it didn't wait long enough to receive the TCP packet. Didn't work.
I've also tried it out on loopback interface, the local lan and systems that are located in the internet. Same result everywhere.
Any ideas on where the error could be located?
Scapy considers this ICMP packet to be response on initial TCP SYN request (which it actually is). Try using sr(..., multi = True) to get multiple response packets.
I am broadcasting UDP packets between 2 machines and listening to them on a third machine. I can see the packets in Wireshark and need any easy way to obtain the "Data" portion of the UDP packets. I have been able to dump the packet infromation to a file using tshark
C:>tshark -V -R "udp" > C:/test.txt
However, this prints out everything in the packet, and i only want to print out the "Data" portion. Is there a way to do this?
Also, if there is a way to capture this in Python, that would be great as well. I have set up the following code:
Host = "myip"
Port = 5000
While True:
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.bind((Host,Port))
data = sock.recv(4096)
sock.close()
When i implement this code, using my "listening" pc, no data is received.
When i implement this code, using one of my two communicating pcs, "The requested address is not valid in its context"
Mind you, I see all the data being passed between the 2 pcs in Wireshark on my "listening" pc.
Thanks!
McFly,
If you want to do sniffing and display/parse packets in Python, Scapy is the way to go here. Just drop tshark as Scapy can automatically do 99% of what tshark can do out of the box.