2022年2月18日 星期五

Wireshark Dissector WSGD 2022

https://wintermade.it/blog/posts/how-to-write-generic-dissectors-in-wireshark.html

2022-02-16


OS

Ubuntu 20 using apt-get install wireshark with version 3.2

Windows 10 with Wireshark 3.6.2 64 bit

C:\Program Files\Wireshark\plugins\3.6\epan\

Or Linux

sudo cp generic.so /usr/lib/x86_64-linux-gnu/wireshark/plugins/3.2/epan

sudo cp custom.wsgd /usr/lib/x86_64-linux-gnu/wireshark/plugins/3.2/epan

sudo cp custom.fdesc /usr/lib/x86_64-linux-gnu/wireshark/plugins/3.2/epan


# udp_server.py

import socketserver

class CustomHandler(socketserver.DatagramRequestHandler):
def handle(self):
data = self.request[0].strip()
print(data)

if __name__ == "__main__":
print("server starting")
serv = socketserver.UDPServer(("127.0.0.1", 8756), CustomHandler)
serv.serve_forever()


udp_client.py

import socket
import struct
import random
import string
import time

HOST, PORT = "localhost", 8756

# SOCK_DGRAM is the socket type to use for UDP sockets
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# refer to `pydoc struct`
HEADER_STRUCT = "".join([
">", # network byte order
"L", # counter
"B", # message size
"B", # message type (0: word, 1: number)
])

PAYLOAD_WORD_TYPE = HEADER_STRUCT + "".join([
"B", # word length
"100s", # string (at most 100 characters)
])
word_struct = struct.Struct(PAYLOAD_WORD_TYPE)

PAYLOAD_NUMBER_TYPE = HEADER_STRUCT + "".join([
"B", # number
"B", # 0: even, 1: odd
"B", # unsigned char
"H", # unsigned short
"I", # unsigned int
"Q", # unsigned long long
])
number_struct = struct.Struct(PAYLOAD_NUMBER_TYPE)

msg_counter = 0
for _ in range(3):
msg_counter += 1

# prepare data to send
if random.random() < 0.99:
num = random.choice(range(256))
is_even = num & 1
ui8 = pow(2,8)-1 # 255
ui16 = pow(2,16)-1 # 65535
ui32 = pow(2,32)-1 # 4294967295
i64 = pow(2,63)-1 # 9223372036854775807 ok
i64 = pow(2,63) # 9223372036854775808 become -9223372036854775808:int64
data = number_struct.pack(msg_counter, 2, 1, num, is_even, ui8, ui16, ui32, i64)
#data = number_struct.pack(msg_counter, 2, 1, num, is_even)
else:
string_len = random.choice(range(100))
the_string = bytes("".join(random.choice(string.ascii_letters+" ") for i in range(string_len)), "ascii")
data = word_struct.pack(msg_counter, 101, 0, string_len, the_string)

# send the message
sock.sendto(data, (HOST, PORT))

# wait 200ms
time.sleep(0.2)

# file custom.wsgd

# protocol metadata

PROTONAME Custom Protocol over UDP

PROTOSHORTNAME Custom

PROTOABBREV custom


# conditions on which the dissector is applied:

# the protocol will be applied on all UDP messages with port = 8756

PARENT_SUBFIELD udp.port

PARENT_SUBFIELD_VALUES 8756


# the name of the header structure

MSG_HEADER_TYPE                    T_custom_header

# field which permits to identify the message type.

MSG_ID_FIELD_NAME                  msg_id

# the main message type - usually it is a fake message, built of one

#    of the possible messages

MSG_MAIN_TYPE                      T_custom_switch(msg_id)


# this token marks the end of the protocol description

PROTO_TYPE_DEFINITIONS


# refer to the description of the data format

include custom.fdesc;



# file custom.fdesc

# here, we define an enumerated type to list the type of messages

#   defined in our protocol

enum8 T_custom_msg_type

{

    word_message   0

    number_message 1

}


# here, we define the structure of the header.

# The header (the same for each message type) must...

struct T_custom_header

{

    # ... define the order of the data

    byte_order big_endian;

    uint32 counter;

    uint8  size_after_header;

    # ... contain the field defined as MSG_ID_FIELD_NAME

    T_custom_msg_type msg_id;

}


struct T_word_message

{

    T_custom_header header;

    uint8           word_len;

    # array of characters

    char[word_len]  word;

    # "word" messages will always have some unused trailing bytes:

    #   they can be marked as raw(*) - the size is calculated at runtime

    raw(*)          spare;

}


struct T_number_message

{

    T_custom_header header;

    uint8           number;

    bool8           is_even;

uint8           uint8;

uint16           uint16;

uint32           uint32;

int64{min=0:max=9223372036854775807}           int64;

}


# T_custom_switch is the main message (as defined in the protocol description)

# according to the parameter msg_id (of type T_custom_msg_type), we define

# the main message to be defined by a single message: either T_word_message or T_number_message.

switch T_custom_switch T_custom_msg_type

{

case T_custom_msg_type::word_message :   T_word_message "";

case T_custom_msg_type::number_message : T_number_message "";

}

Result














more

Multicast

Ubuntu
# route add -net 224.0.0.0 netmask 240.0.0.0 dev lo
# ifconfig lo multicast

# multicast_server.py

import socket
import struct

MCAST_GRP = '224.1.1.1'
MCAST_PORT = 8756
IS_ALL_GROUPS = True

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if IS_ALL_GROUPS:
# on this port, receives ALL multicast groups
sock.bind(('', MCAST_PORT))
else:
# on this port, listen ONLY to MCAST_GRP
sock.bind((MCAST_GRP, MCAST_PORT))
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)

sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

while True:
# For Python 3, change next line to "print(sock.recv(10240))"
print(sock.recv(10240))

# multicast_client.py

import socket
import struct
import random
import string
import time

# Ubuntu: add a new route
# route add -net 224.0.0.0 netmask 240.0.0.0 dev lo
# ifconfig lo multicast

MCAST_GRP = '224.1.1.1'
MCAST_PORT = 8756
# regarding socket.IP_MULTICAST_TTL
# ---------------------------------
# for all packets sent, after two hops on the network the packet will not
# be re-sent/broadcast (see https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html)
MULTICAST_TTL = 2

# refer to `pydoc struct`
HEADER_STRUCT = "".join([
">", # network byte order
"L", # counter
"B", # message size
"B", # message type (0: word, 1: number)
])

PAYLOAD_WORD_TYPE = HEADER_STRUCT + "".join([
"B", # word length
"100s", # string (at most 100 characters)
])
word_struct = struct.Struct(PAYLOAD_WORD_TYPE)

PAYLOAD_NUMBER_TYPE = HEADER_STRUCT + "".join([
"B", # number
"B", # 0: even, 1: odd
"B", # unsigned char
"H", # unsigned short
"I", # unsigned int
"Q", # unsigned long long
])
number_struct = struct.Struct(PAYLOAD_NUMBER_TYPE)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL)

msg_counter = 0
for _ in range(3):
msg_counter += 1

# prepare data to send
if random.random() < 0.99:
num = random.choice(range(256))
is_even = num & 1
ui8 = pow(2,8)-1 # 255
ui16 = pow(2,16)-1 # 65535
ui32 = pow(2,32)-1 # 4294967295
i64 = pow(2,63)-1 # 9223372036854775807 ok
i64 = pow(2,63) # 9223372036854775808 become -9223372036854775808:int64
data = number_struct.pack(msg_counter, 2, 1, num, is_even, ui8, ui16, ui32, i64)
#data = number_struct.pack(msg_counter, 2, 1, num, is_even)
else:
string_len = random.choice(range(100))
the_string = bytes("".join(random.choice(string.ascii_letters+" ") for i in range(string_len)), "ascii")
data = word_struct.pack(msg_counter, 101, 0, string_len, the_string)

# send the message
sock.sendto(data, (MCAST_GRP, MCAST_PORT))

# wait 200ms
time.sleep(0.2)

Wireshark (multicast)





















more







沒有留言:

張貼留言

2023 Promox on Morefine N6000 16GB 512GB

2023 Promox on Morefine N6000 16GB 512GB Software Etcher 100MB (not but can be rufus-4.3.exe 1.4MB) Proxmox VE 7.4 ISO Installer (1st ISO re...