Handshake frames manipulation - python

I intend to create a fake AP in order to send the frames received from the client to the real AP and,
of course, the frames received from the real AP to the client... all passing through the fake AP.
I will use hostapd to create the fake AP and scapy to sniff and manipulate the packets (changing only source and destination).
Basically, using python, this is what I'm going to do:
Client->FakeAP->RealAP
1) sniff the packet
2) change source and destination (src=FakeAP, dst=RealAP)
3) send the packet to the Real AP
RealAP->FakeAP->Client
1) sniff the packet
2) change source and destination (src=FakeAP, dst=Client)
3) send the packet to the Client
Here's the code:
from scapy.all import *
def manipulateAndSend(pkt):
pkt[Ether].src= new_src_mac
pkt[Ether].dst= new_dst_mac
pkt[IP].src= new_src_ip
pkt[IP].dst= new_dst_ip
send(pkt)
sniff(iface="wlan0", prn=manipulateAndSend, filter="tcp", store=0)
My two questions are:
1) In hostapd I'm going to set a "whatever" WPA key, so how can I avoid to reject the authentication?
2) How can I edit the IP src and dst of the packet if the IP association starts after the authentication is complete?

Related

Ethernet header removal using scapy (python)

I am trying to work with pcap files. For a preprocessing phase, I am trying to remove an ethernet header using scapy but not sure if this is the right way. Any ideas would like much appreciated. Thanks
I am working on Jupyter notebook and I use python and scapy to read pcap files.
Packet summary:
'Ether / IP / UDP 131.XXX:XXX:XXX:netbios_ns > 131.XXX:XXX:XXX:netbios_ns / NBNSQueryRequest'
Tried:
pk1= ['Ether / IP / UDP 131.XXX:XXX:XXX:netbios_ns > 131.XXX:XXX:XXX:netbios_ns / NBNSQueryRequest']
pkt2=pk1['NBNSQueryRequest']
pk1[Ether].remove_payload()
pk1 /=pkt2
If I understand correctly your question you can access the payload by doing the following:
pk1[1]
pk1.payload
Assuming you have a Packet object with the following layers:
pkt = Ether()/IP()/ICMP()
The packet would look something like this:
print(repr(pkt))
# <Ether type=IPv4 |<IP frag=0 proto=icmp |<ICMP |>>>
pkt is actually an ethernet packet with all the other layers encapsulated as it's payload, so you can just use:
pkt = pkt.payload
# Or
pkt = pkt[Ether].payload
And you'll end up with:
print(repr(pkt))
# <IP frag=0 proto=icmp |<ICMP |>>
You may open capture file in Wireshark, go to File menu, then "Export PDU" and specify a filter of what do you want to export.

Send a packet of data literally via UDP in Python

I want to my UDP data packet to have literately this information for example:
data = "83053163021478010102010370020000000000"
I'm using the follow code to send it which works fine(I can see it going out on wireshark):
listener = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
listener.sendto(data, (IP, PORT))
When I look at the data packet in wireshark i want the (wireshark)data packet == data. How do I declare/convert the data type to make this happen.
I think this should do the trick:
import codecs
data = codecs.decode("83053163021478010102010370020000000000", "hex_codec")
Then you can send data same as you are doing now.
ref: How to create python bytes object from long hex string?

scapy sniff and decode diameter

I am trying to do scapy/python sniffer for Diameter messages and parse Diameter part to get AVP's from Raw.load.
After some fails I get back to basic python/scapy script like this:
from scapy.all import *
def pkt_diam(pkt):
raw = pkt.getlayer(Raw).load
print raw
# pkt.show()
sniff(iface="eth0", filter="port 3868", store=0, prn=pkt_diam)
By printing raw.load I have received just some AVP's but very unreadable. If I use
pkt.show()
I receive whole packet, Ethernet, IP, TCP and Raw part but Raw.load is almost unusable.
###[ Raw ]###
load = '\x01\x00\x00\xec#\x00\x01/\x01\x00\x00\x00\x07K\x12\xca\x07K\x12\xca\x00\x00\x01\x07#\x00\x00 00000001;000001;61de2650\x00\x00\x01\x04#\x00\x00 \x00\x00\x01\n#\x00\x00\x0c\x00\x00(\xaf\x00\x00\x01\x02#\x00\x00\x0c\x01\x00\x00\x00\x00\x00\x01\x15#\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x01\x08#\x00\x00\x1dtest.a-server.org\x00\x00\x00\x00\x00\x01(#\x00\x00\x14a-server.org\x00\x00\x01)#\x00\x00 \x00\x00\x01\n#\x00\x00\x0c\x00\x00(\xaf\x00\x00\x01*#\x00\x00\x0c\x00\x00\x13\x89\x00\x00\x02t\x80\x00\x008\x00\x00(\xaf\x00\x00\x01\n#\x00\x00\x0c\x00\x00(\xaf\x00\x00\x02u\x80\x00\x00\x10\x00\x00(\xaf\x00\x00\x00\x01\x00\x00\x02v\x80\x00\x00\x10\x00\x00(\xaf\x00\x00\x00\x05'
I need some help to parse and decode Diameter Raw.load message.
Thx in advance
The best way to do it is to define the Diameter header yourself, following the link that I just gave you which is the section of the main Scapy documentation that details the step-by-step guide on how to build your own protocol type (header).
Once you have the Diameter() header defined correctly, dissecting the Diameter packets will become a breeze.
The wikipedia page on the Diameter protocol seems to be a very good reference regarding the Diameter packet header.
As part of the current Scapy pull requests https://bitbucket.org/secdev/scapy/pull-requests/ , number #109 provides support for the Diameter layer (parsing and generation).
Download the latest Scapy sources and the diameter.py file which should be placed in the 'contribution' directory (this file will not fully work with the current 2.3.1 Scapy version)
scapy is very useful.
from scapy.all import *
packets = rdpcap('/path/to/rx.pcap')
def generatePacket():
'''
Generate a packet.
'''
IP()/TCP()/DiamG()
def dissectPacket():
'''
dissect a packet.
'''
packet[0][DiamG]
The above shows the idea. and you can use print(repr(packet[0][DiamG])) to see result. Of course in order to check the packet is a Diameter packet, you might want to check at first like:
x = packet[0]
while x.payload:
x = x.payload
if x.name == 'Diameter' # it has diameter message.
# dissect it like above.
And how to ensemble and send a Diameter packet, one can check:
building diameter message

How to send raw Frame using python

I have a raw ethernet Frame that i want to send
How should i do that? i tried to send hex values of a frame but i still cant control packet header that contains src/dst address and ports
import socket
# the public network interface
HOST = socket.gethostbyname(socket.gethostname())
addr = ('46.165.204.237', 10000)
# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))
netpacket = '\xDE\xB0\x7B\xE5\xA7\xCD\x4C\x17\xEB\x07\x0D\xBC\x08\x00\x45\x00\x00\x92\x68\x94\x40\x00\x78\x06\xDC\x94\x2E\xA5\xCC\xED\xC0\xA8\x01\x02\x27\x10\x07\xC8\x04\xD7\xEA\xEA\xC3\x2A\x4E\xA2\x50\x18\x01\x02\x39\xB0\x00\x00\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\x22\x31\x2E\x30\x22\x3F\x3E\x3C\x50\x61\x63\x6B\x65\x74\x3E\x3C\x6F\x70\x65\x72\x61\x74\x69\x6F\x6E\x3E\x33\x3C\x2F\x6F\x70\x65\x72\x61\x74\x69\x6F\x6E\x3E\x3C\x64\x61\x74\x61\x3E\x33\x24\x30\x24\x30\x24\x30\x24\x30\x24\x30\x3C\x2F\x64\x61\x74\x61\x3E\x3C\x65\x78\x74\x64\x61\x74\x61\x3E\x3C\x2F\x65\x78\x74\x64\x61\x74\x61\x3E\x3C\x2F\x50\x61\x63\x6B\x65\x74\x3E'
#netpaket = netpacket.encode('UTF-8')
s.sendto(netpacket.encode('UTF-8'), addr)
Is there in Python a function like sendRaw() or sendRawFrame()?
I know scapy can handle this, but i need to do that many many times, and every time with various payload data. How scapy can be automated? I mean python script that launch scapy creates packet with some payload and send it.
scapy.py
packet1 = IP(dst='46.165.204.237')/TCP(sport=1992, dport=10000)/'<?xml version="1.0"?><Packet><operation>99</operation><data><![CDATA[8 fast]]></data><extdata><![CDATA[]]></extdata></Packet>.'
send(packet1)
The goal for it is to send packet from a port that already in use. If there a better solution for that problem?
Offtopic: maybe someone knows how to send packets through the Open socket id in windows (not only in python)?
You can provide Scapy with raw input by using the Raw layer.
netpacket = Raw('\xDE\xB0...')
To send packets at the ethernet layer - see the documentation for sendp.
sendp(netpacket, iface="eth1")

Reading data from Simulink into Python over UDP

I want to send data from a Simulink model (running in real time) to a Python script (also running in real time. I am using Simulink's built-in "UDP Send" block, which works, but I don't know how to decode the data I'm getting. This is what my python script looks like:
import sys, struct
from socket import *
SIZE = 1024 # packet size
hostName = gethostbyname('0.0.0.0')
mySocket = socket( AF_INET, SOCK_DGRAM )
mySocket.bind((hostName,5002))
repeat = True
while repeat:
(data,addr) = mySocket.recvfrom(SIZE)
data = struct.unpack('d',data)
print data
I've suspected that the data stream should be something like a double, but while it's giving me numbers they aren't meaningful:
If simulink sends a constant "1", I get an output of "3.16e-322"
If Simulink sends a constant "2", I get an output of "3.038e-319"
Any ideas?
Turns out my network was reversing the packet bits. The solution was to read it in as bit-reversed:
data = struct.unpack('!d',data)
I have no clue why this happens over some networks and not others. Can someone comment on a way to tell if I need to use bit-reversal?
The problem occurs when the sender and receiver has different byte order.
See sys.byteorder.
Best practice should be to always convert to network order when sending and convert again when receiving.

Categories