Scapy ICMPv6EchoRequest sends from Scapy command prompt but NOT from within script? - python

I am trying to send an ICMPv6 Echo Request from within a python script. When I do this process out within the Scapy environment, it works perfectly. I can see the packet exchanges within Wireshark. However, when I have this code:
#Spacy commands
ip = IPv6()
ip.dst = "fe80::ba8d:12ff:fe42:98c8"
ip.show()
print'-----------------------------------------'
request = ICMPv6EchoRequest()
request.id=98
request.show()
print'-----------------------------------------\n'
send(request/ip) #send Echo Request w/ IPv6 Header
in my python script and then call the script, I get this:
WARNING: Mac address to reach destination not found. Using broadcast.
WARNING: No IPv6 underlayer to compute checksum. Leaving null.
.
Sent 1 packets.
But no packet is actually sent... does anyone have any idea what I'm doing wrong?
EDIT: I should have mentioned that the sending node is a Virtual Ubuntu Linux Machine and the attempted Receiver is a Macbook on a bridged network adapter.

In Scapy, when you use the / operator the operand on the left encapsulates or places the operand on the right as it's data, or underlayer. It's what will come next in the packet.
Your problem is your sending line -
send(request/ip)
You have them reversed. This produces a packet where the IP Layer is the data of the ICMPv6 layer. This is why you are getting the error WARNING: No IPv6 underlayer to compute checksum. Leaving null, because you aren't actually putting anything there since your layers are in the wrong order.
This is what you meant to do.
send(ip/request)
Changing that one send line and you should see the results you expect.

Related

Sending packet with python and scapy to local address doesn't work

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.

Scapy sniff() doesn't seem to capture TCP packets, only shows ethernet frames

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!

How to capture the packets that you send in Scapy?

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())

scapy sr function problems

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.

scapy sniff function not catching any packets

I've been following Seitz's black hat python book and he gives an example of capturing network traffic using the scapy library.
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
def packet_callback(packet):
print packet.show()
sniff(filter="",iface="any",prn=packet_callback, count = 1)
I run the above function as follows: sudo python sniffer.py and open google chrome to a page. No packets get captured. I do a ping request to a domain and nothing gets captured. I was expecting the print packet.show() line to print the first packet being sent.
All of this is being run on a Macbook Pro on a wireless internet connection.
Can someone help me troubleshoot?
if you want scapy to sniff on all interfaces, just remove the iface = "any" parameter. Since "any" is not an interface therefore scapy cannot sniff.
Also remove the filter parameter since it is not applying any filter.
The correct command would like like this.
sniff(prn=packet_callback, count = 1)
iface argument expects exact name of the interface. Most likely you do not have an interface named ANY. You can omit the argument, which is most likely what you have to do in this case, or use actual interface name (such as "eth0").
I actually get an exception "No such device", when I try your code. Is this the actual code you run?
Also, please, write scapy version. I am using python3 version, which you can get from http://github.com/phaethon/scapy or as scapy-python3.

Categories