Convert PCAP to MAC addresses in Python - scapy

I'm tryng to read a Pcap file, and after that I get the Ip's and the realtions between Ip's, I want to transform these relattions in MAC relations but I'm not sure how I have to do it.
trafico= rdpcap('example-01.pcap')
unique_streams =[]
for frame in trafico:
packet = frame[IP]
src = packet.src
dst = packet.dst
layer4_segment = packet.payload.name
sport = packet[layer4_segment].sport
dport = packet[layer4_segment].dport
unique_streams.append(f"{src}:{dst}:{layer4_segment}:{sport}:{dport}")
tre= set(unique_streams)
for k in tre:
print(k)
I have these code to show the Ip's source and destination and also the ports
thanks

I don't know how to transform these relations in MAC relations...
To get the MAC from the packet you need to look at the 'Ether' layer and not the'IP' layer:
e = frame[Ether]
print(e.src,e.dst)
e.src is the MAC for the IP packet.src etc.

Related

How to send a RARP-request using Scapy in Python

I am trying to fetch an ip address of a remote machine B from my machine A using mac address of Machine B. Both A & B are on same subnet. I am trying to use Scapy library in python and issuing a RARP request.
Below is my code. I am getting 0.0.0.0 as ouput.
import scapy.all as scapy
def get_ip(mac):
arp_request=scapy.ARP(op=3, hwdst=mac)
broadcast = scapy.Ether(dst = 'ff:ff:ff:ff:ff:ff')
arp_request_broadcast = broadcast / arp_request
# print('$$$', arp_request_broadcast.show())
answered_list=scapy.srp(arp_request_broadcast, timeout=1, verbose=False)[0]
unanswered_list=scapy.srp(arp_request_broadcast, timeout=1, verbose=False)[1]
response = {'answered_list':answered_list, 'unanswered_list':unanswered_list}
print('unanswered_list',unanswered_list[0].pdst)
return response
macB='Mac address of machine B'
obj=get_ip(macB)
print(obj)
Output:
unanswered_list 0.0.0.0
{'answered_list': <Results: TCP:0 UDP:0 ICMP:0 Other:0>, 'unanswered_list': <Unanswered: TCP:0 UDP:0 ICMP:0 Other:1>}

Adding a timestamp (48 bits) field in the ethernet packet (before source Mac Address) using Scapy

I have a PCAP file containing many packets. There I can access the timestamp as follows:
from scapy.all import *
pcap = PcapReader("file.pcap")
for pkt in pcap:
print("Time Stamp = ", pkt.time)
Now, I want to store the same timestamp as a header field in layer L2 of the packet. Currently layer L2 is as follows:
L2
{
#Other fields
bit<48> Source MAC
bit<48> Destination MAC
bit<8> Ethertype
}
What I want is:
L2
{
#Other fields
**bit<48> TimeStamp**
bit<48> Source MAC
bit<48> Destination MAC
bit<8> Ethertype
}
How to achieve this? I have heard that scapy allows us to add new fields to existing layer of the packet. But how can I add a field in L2 of packet before source mac address?
Any directions? Thank you!

Scapy & Docker: Get container's IP address w/o using Container ID?

What is the easiest way to compare IP addresses using Scapy (in Python3.6) and Docker? I have a piece of code that sniffs my Docker bridge network using Scapy sniff(). I want to look at each packet's source IP address, and if it matches the IP address for my container named "plc1", do additional steps. If they don't match, I just return an empty list and move on.
However I cannot figure out how to compare a packet's source IP address to a container name. It really needs to be the container's name and not the ID, since I am running a ton of containers in parallel and looking up ID's to plug into my Python3.6 script is tedious. Any thoughts? I've tried using the Docker SDK but it needs the Container ID, which is what I am trying to avoid...
Sample Python3.6 code, which does not work, included below:
#!/usr/bin/env python3
from scapy.all import *
def find_ports(pkt):
# if src IPaddr matches IP addr of container plc1...
if pkt[IP].src == 'plc1': # THIS DOES NOT WORK
# if there is a match, get some additional packet info
if TCP in pkt:
tcp_dport = pkt[TCP].dport
ip_total_len = pkt.getlayer(IP).len
ip_header_len = pkt.getlayer(IP).ihl * 32 / 8
tcp_header_len = pkt.getlayer(TCP).dataofs * 32 / 8
tcp_seg_len = ip_total_len - ip_header_len - tcp_header_len
sequence_num = pkt[1].ack
return [tcp_dport, tcp_seg_len, sequence_num]
# else if NO MATCHING ip addr's, return blank list...
else:
return []
tempList = sniff(filter="ip", prn=find_ports, iface="br-19f0ba1cf88f")
# if templist not empty...
if tempList:
# send a TCP RST packet...
ip = IP(src="plc1", dst="hmi_pass_thru")
tcp = TCP(sport=502, dport=tempList[0], flags="R", seq=int(tempList[1]), ack=int(tempList[2]) + 1)
pkt = ip / tcp
ls(pkt)
send(pkt, verbose=0)

Forwarding packets to windows

I wrote a code to send a packet from my Kali Linux machine to my Windows PC but the packet doesn't show in Wireshark. There are no errors in the code and it sends the packets but they are not received.
Any one can help ?
#!/usr/bin/python
from scapy.all import *
def synflood(src,tgt,message):
for dport in range(1024,65535):
IPlayer = IP(src=src, dst=tgt)
TCPlayer = TCP(sport=4444, dport=dport)
RAWlayer = Raw(load=message)
pkt = IPlayer/TCPlayer
send(pkt)
source = input("src: ")
target = input("targert : ")
message = input(" load : ")
while True:
synflood(source,target,message)
Update: So i fixed the problem! i tried replacing the for statement by "dport = 80" and for the target IP i chose another dest IP than my pc aand it showed up in wireshark, that's how i realised that i should configure an internal VM network instead of the bridged one , and it worked

Not able to communicate ping through scapy using global address while using multiple network cards

I am using 3 network cards on my ubuntu 14.04 machine. I am trying to simultaneously communicate to 3 different networks using three different network cards. I want to use IPv6 Global addresses.
Below is the network structure.
Interface_A (8003::2) <-----> Get0 (8003::1)
Interface_B (8001::2) <-----> Get1 (8001::1)
Interface_C (8002::2) <-----> Get2 (8002::1)
When I work with IPv6 link layer addresses, simultaneous communication is working. i.e. below code is working successfully.
dst_a="FE80::C1:4160" # get0
dst_c="FE80::3617:EBFF:FEAE:DEB4" # get2
src_a="FE80::3617:EBFF:FEAE:DEB5" # my_pc_interfac_A
src_c="FE80::523E:AAFF:FE08:8AAF" # my_pc_interface_C
IFACE_A = "eth0"
IFACE_C = "eth2"
echo_a = IPv6(src=src_a, dst=dst_a, nh=58) / ICMPv6EchoRequest(data='aaaa')
echo_c = IPv6(src=src_c, dst=dst_c, nh=58) / ICMPv6EchoRequest(data='cccc')
conf.iface = IFACE_A
a = sr1(echo_a)
a.display()
conf.iface = IFACE_C
c = sr1(echo_C)
c.display()
While below code is not working, only 1st ping is successful (echo_a). For the next one I am not getting any response. When I am working with only interface_C (echo_c) with global ipv6 addresses, echo_c is also working.
dst_a_global="8003::1" # get0
dst_c_global="8002::1" # get2
src_a_global="8003::2" # my_pc_interfac_A
src_c_global="8002::2" # my_pc_interface_C
IFACE_A = "eth0"
IFACE_C = "eth2"
echo_a = IPv6(src=src_a_global, dst=dst_a_global, nh=58) / ICMPv6EchoRequest(data='aaaa')
echo_c = IPv6(src=src_c_global, dst=dst_c_global, nh=58) / ICMPv6EchoRequest(data='cccc')
conf.iface = IFACE_A
a = sr1(echo_a)
a.display()
conf.iface = IFACE_C
c = sr1(echo_C)
c.display()
I am getting only echo_a output, for echo_c there is no response.
If I run echo_c first, I am not getting response for echo_a.
I expect that, for both the echo request there should be an echo reply. I am able to ping6 on all the interfaces.
Try to configure also the Ethernet layer yourself and see if it is working-
echo_a = Ether(src=YOUR_MAC, dst=33:33:00:01:00:03) / IPv6(src=src_a_global, dst=dst_a_global, nh=58) / ICMPv6EchoRequest(data='aaaa')
a = srp1(echo_a, iface=IFACE_A)
Also- I had some problems myself using IPv6 with multiple interfaces (using regular socket instead of Scapy, and Windows), take a look to see if you can find something relevant (I couldn't think of anything particular, but maybe it will help anyway)-
Windows doesn't receive multicast IPv6 packets from all interfaces
Sending IPv6 multicast packets through a specific network interface

Resources