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
Related
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.
I'm trying to read and write data from an RFID tag using python whit this module:
https://es.aliexpress.com/item/32573423210.html
I can connect successfully whit serial but I don't know how to read any tag, because the datasheet from pr9200(the reader that I am working) use this:
Image for pr9200 operation It's like a raw packet whit only hex address that I need to send to the module for it works
my code on python is this:
import serial
ser = serial.Serial(port = "COM27", baudrate=115200, bytesize=8, parity='N', stopbits=1)
while(ser.is_open == True):
rfidtag = ''
incomingByte = ser.read(21)
print(incomingByte)
for i in incomingByte:
rfidtag = rfidtag + hex(i)
Some comments to jump start your coding:
-What you need to do is send a command to your device to ask it to start sending readings in auto mode. To do that you need to use ser.write(command). You can find a good template here.
-To prepare the command you just need to take the raw bytes (those hex values you mentioned) and put them together as, for instance a bytearray.
-The only minor hurdle remaining is to calculate the CRC. There are some nice methods here at SO, just search CRC 16 CCITT.
-Be aware that after writing you can not start immediately waiting for readings, you have to wait first for the device to acknowledge the command. Hint: read 9 bytes.
-Lastly, take a new count of the bytes you will receive for each tag. I think they are 22 instead of 21.
You can use pyembedded python library for this which can give you the tag id.
from pyembedded.rfid_module.rfid import RFID
rfid = RFID(port='COM3', baud_rate=9600)
print(rfid.get_id())
https://pypi.org/project/pyembedded/
I am trying to write a python script using scapy(not pyshark) library to live capture the packet and extract the information. Any idea how to use scapy(jython/python) to analyze sip/rtp packet?
To make it more clearly, I had a sample code to analyse the rtp packet which use Pyshark as following:
import pyshark
import re
cap = pyshark.LiveCapture(interface='en0', display_filter='sip')
for i in cap:
sip= str(i[3])
print sip
if re.search('sendonly',sip) != None:
print ‘yes'
Can this code be transferred to Scapy instead of Pyshark with the same function?
Kenneth,
To start with you need some packet capture - you can do this in scapy - or using Wireshark etc. I now assume that you have a file in PCAP (or PCAPNG) format. I have also assumed that in Wireshark you are not filtering - but recording everything.
So inside Scapy you will write something like this....
from scapy.all import *
packets = rdpcap('filename.pcap')
But I can not see a Layer definition for SIP inside Scapy - which means you will need to develop it yourself.
Do not panic - someone has already added that for themselves. Please have a look at https://github.com/cssaheel/dissectors/blob/master/sip.py
You should be well on your way
Your help is badly needed...
I'm trying to read data and print it to the python console from a load cell. My setup is as follow:
The load cell is a MD type from Eilersen connected to a load cell signal converter of type MCE2040 Seriel Communication Module also from Eilersen. The MCE2040 is connected to my PC through a USB to seriel connector like this link_http://www.usbgear.com/USB-COM-I-SI.html (I'm only allowed two links) one.
The load cell is connected to COM 1.
I have tried to run this snippet:
import serial
ser = serial.Serial(0) # open first serial port
print ser.portstr # check which port was really used
#ser.write("hello") # write a string
ser.close()
...and that prints 'COM1' to the console so I guess my connection should be okay.
My problem is that I don't know how to proceed. In the end I'd like to plot a graph of the incoming data and output a data file with time stamps, but for starters I'd like to print some load cell data to the console.
Any help will be highly appreciated. If further information is needed, please let me know.
Thx in advance.
Edit:
I have some documentation re MCE2040:
3.1 EVC Mode (without time stamp)
Specification: RS232/RS4422
Baudrate: 115200 bps
38400 bps (select with SW1.5)
Data bits: 7
Parity: Even
Stop bits: 1
Protocol: EVC protocol described below (Transmit Only)
3.1.1 EVC Protocol Format
After each sample period a new weight telegram is transmitted. The transmitted telegram has the following format:
<LF>WWWWWWWW<CR>
Each telegram contains a line feed character, a weight result and a carriage return character. The telegram contains:
<LF> Line Feed character (ASCII 0Ah).
WWWWWWWW Weight value for the loadcell. The value is an 8 byte ASCII hex number with MSB first.
<CR> Carriage Return character (ASCII 0Dh).
I was able to get some output from the following code:
import serial
ser = serial.Serial(0, baudrate=115000 ,timeout=100)
print ser.portstr
x = ser.read(50)
print x
ser.close()
print 'close'
Output:
COM1
ÆÆÆÆA0·5
ÆÆÆÆA0·6
ÆÆÆÆA0·5
ÆÆÆÆA0·±
ÆÆÆÆA0·±
close
First of all make sure it's really your com port, since COM1 is used by a lot of computers i'm not sure it's your com port.
You can use a simple wire to loop back info by connecting TX to RX at the USB to Serial converter, it will result in an echo (you will read what you write) it's a very simple way to verify that you are talking with the right com port.
Regarding how to continue:
Useful basic commands:
ser.write("command") with this command you send to the device some command.
ser.read(n) is for read n bytes from the device
ser.readline() will read line until it reached \n (new line)
Steps:
Send a command to your device.
Read all the data by some end byte (Frame Synchronization).
Parse data to structure (list or something like that..)
Plot it to graph.
Useful Links:
pyserial docs
tips for reading serial
plotly for graphs in python
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.