Skip to content

Commit

Permalink
WIP: Working on the Wirego Remote in python.
Browse files Browse the repository at this point in the history
  • Loading branch information
Neb committed Jan 14, 2025
1 parent 2757058 commit 32f9ab2
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 1 deletion.
2 changes: 1 addition & 1 deletion examples/minimal/wirego_minimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (WiregoMinimalExample) GetDetectionFilters() []wirego.DetectionFilter {
return filters
}

// GetDissectorFilterHeuristics returns a list of protocols on top of which detection heuristic
// GetDetectionHeuristicsParents returns a list of protocols on top of which detection heuristic
// should be called.
func (WiregoMinimalExample) GetDetectionHeuristicsParents() []string {
//We want to apply our detection heuristic on all tcp payloads
Expand Down
113 changes: 113 additions & 0 deletions wirego_remote/python/wirego.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later

from abc import ABC, abstractmethod
from dataclasses import dataclass
from enum import IntEnum
from typing import NewType
from typing import List
from typing import Optional

__title__ = "Wirego Remote"
__description__ = "Python class for Wirego remote"
__author__ = "Benoit Girard"
__email__ = "[email protected]"
__license__ = 'GPL-2.0-or-later'
__copyright__ = 'Copyright (c) 2024 Benoit Girard'

# FieldId type (just overloading int type)
FieldId = NewType('FieldId', int)

#ValueType defines a type of data supported by Wireshark
class ValueType(IntEnum):
ValueTypeNone = 0x01
ValueTypeBool = 0x02
ValueTypeUInt8 = 0x03
ValueTypeInt8 = 0x04
ValueTypeUInt16 = 0x05
ValueTypeInt16 = 0x06
ValueTypeUInt32 = 0x07
ValueTypeInt32 = 0x08
ValueTypeCString = 0x09
ValueTypeString = 0x10

#DisplayMode tells Wireshark how to display a field
class DisplayMode(IntEnum):
DisplayModeNone = 0x01
DisplayModeDecimal = 0x02
DisplayModeHexadecimal = 0x03

#DetectionFilterType defines the type of a declared detection filter
class DetectionFilterType(IntEnum):
DetectionFilterTypeInt = 0x01
DetectionFilterTypeStr = 0x02

@dataclass
class WiregoField:
wirego_field_id: FieldId
name: str
filter: str
value_type: ValueType
display_mode: DisplayMode


@dataclass
class DetectionFilter:
filter_type: DetectionFilterType
name: str
value_int: int
value_str: str

@dataclass
class DissectField:
wirego_field_id: FieldId
offset: int
length: int
sub_fields: List['DissectField']

@dataclass
class DissectResult:
protocol: str
info: str
fields: List[DissectField]


class WiregoListener(ABC):

@abstractmethod
def get_name(self) -> str:
pass

@abstractmethod
def get_filter(self) -> str:
pass

@abstractmethod
def get_fields(self) -> List[WiregoField]:
pass

@abstractmethod
def get_detection_filters(self) -> List[DetectionFilter]:
pass

@abstractmethod
def get_detection_heuristics_parents(self) -> List[str]:
pass

@abstractmethod
def detection_heuristic(packetNumber: int, src: str, dst: str, stack: str, packet: bytes) -> bool:
pass

@abstractmethod
def dissect_packet(packetNumber: int, src: str, dst: str, stack: str, packet: bytes) -> DissectResult:
pass


class Wirego:

def __init__(self, wglistener: WiregoListener):
print("init")
self.wglistener = wglistener
print(wglistener.get_fields())
print(wglistener.get_detection_filters())

83 changes: 83 additions & 0 deletions wirego_remote/python/wirego_minimal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import wirego
from typing import List
from enum import IntEnum

print("Wirego remote Python example")

class FieldEnum(IntEnum):
FieldIdCustom1 = 0x01
FieldIdCustom2 = 0x02
FieldIdCustomWithSubFields = 0x03

class WiregoMinimal(wirego.WiregoListener):

# This function shall return the plugin name
def get_name(self):
return "Wirego Minimal Example"

# This function shall return the wireshark filter
def get_filter(self):
return "wgminexample"

# GetFields returns the list of fields descriptor that we may eventually return
# when dissecting a packet payload
def get_fields(self):
return [
wirego.WiregoField(FieldEnum.FieldIdCustom1, "Custom1", "wirego.custom01", wirego.ValueType.ValueTypeUInt8, wirego.DisplayMode.DisplayModeHexadecimal),
wirego.WiregoField(FieldEnum.FieldIdCustom1, "Custom2", "wirego.custom02", wirego.ValueType.ValueTypeUInt16, wirego.DisplayMode.DisplayModeDecimal),
wirego.WiregoField(FieldEnum.FieldIdCustomWithSubFields, "Custom With Subs", "wirego.custom_subs", wirego.ValueType.ValueTypeUInt32, wirego.DisplayMode.DisplayModeHexadecimal),
]

# get_detection_filters returns a wireshark filter that will select which packets
# will be sent to your dissector for parsing.
# Two types of filters can be defined: Integers or Strings
def get_detection_filters(self):
return [
wirego.DetectionFilter(wirego.DetectionFilterType.DetectionFilterTypeInt, "udp.port", 137, ""),
wirego.DetectionFilter(wirego.DetectionFilterType.DetectionFilterTypeStr, "bluetooth.uuid", 0, "1234"),
]

# get_detection_heuristics_parents returns a list of protocols on top of which detection heuristic
# should be called.
def get_detection_heuristics_parents(self):
return [
"udp",
"http",
]

def detection_heuristic(packetNumber: int, src: str, dst: str, stack: str, packet: bytes) -> bool:
#All packets starting with 0x00 should be passed to our dissector (super advanced heuristic)
if (len(packet) != 0) and (packet[0] == 0x00):
return True
return False

#dissect_packet provides the packet payload to be parsed.
def dissect_packet(packetNumber: int, src: str, dst: str, stack: str, packet: bytes) -> wirego.DissectResult:
#This string will appear on the packet being parsed
protocol = "Protocol name example"

#This (optional) string will appear in the info section
info = "Info example pkt ", packetNumber

fields: List[wirego.DissectField]

#Add a few fields and refer to them using our own "internalId"
if len(packet) > 6:
fields.append(wirego.DissectField(FieldEnum.FieldIdCustom1, 0, 2))
fields.append(wirego.DissectField(FieldEnum.FieldIdCustom2, 2, 4))

#Add a field with two sub field
if len(packet) > 10:
subField1 = wirego.DissectField(FieldEnum.FieldIdCustom1, 6, 2)
subField2 = wirego.DissectField(FieldEnum.FieldIdCustom1, 8, 2)
field = wirego.DissectField(FieldEnum.FieldIdCustomWithSubFields, 6, 4, [subField1, subField2])
fields.append(field)

return wirego.DissectResult(protocol, info, fields)

# Create our listener
tl = WiregoMinimal()

# Instanciate wirego
wg = wirego.Wirego(tl)

0 comments on commit 32f9ab2

Please sign in to comment.