Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modbus packet not being parsed correctly in 2.6.0 #4573

Open
jpinedaa opened this issue Oct 21, 2024 · 6 comments
Open

modbus packet not being parsed correctly in 2.6.0 #4573

jpinedaa opened this issue Oct 21, 2024 · 6 comments

Comments

@jpinedaa
Copy link

Brief description

packets that were being correctly parsed as modbus in 2.5.0 are now not being recognized as Read Holding Registers Response in 2.6.0

Scapy version

2.6.0

Python version

3.10

Operating system

Ubuntu 22.04.4 LTS

Additional environment information

No response

How to reproduce

import sys
from scapy.contrib.modbus import *
from scapy.utils import rdpcap

pcap_file = sys.argv[1]
print(f"Reading pcap file: {pcap_file}")
packets = rdpcap(filename=pcap_file, count=1000)
print(packets[32].show2(dump=True))

with provided pcap file

Actual result

Reading pcap file: error.pcap
###[ cooked linux v2 ]###
proto = IPv4
reserved = 0
ifindex = 4
lladdrtype= 0x1
pkttype = unicast-to-another-host
lladdrlen = 6
src = b',\xcfg,\xe2?'
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 307
id = 18082
flags = DF
frag = 0
ttl = 64
proto = tcp
chksum = 0xd998
src = 10.1.2.168
dst = 10.1.2.225
\options \
###[ TCP ]###
sport = 502
dport = 58136
seq = 499266911
ack = 1928828226
dataofs = 8
reserved = 0
flags = PA
window = 249
chksum = 0x7860
urgptr = 0
options = [('NOP', None), ('NOP', None), ('Timestamp', (3747823981, 2872918422))]
###[ ModbusADU ]###
transId = 0x0
protoId = 0x0
len = 249
unitId = 0x1
###[ Raw ]###
load =
b'\x03\xf6\x02\xbd\x00\x99\x00\x02\x00\x01\x00\x03\x00\x01\x00\x00\x00\x00\xff\xff\xff\xff\x03\xd0\x03\xd1\x00\x00\x03\xe7
x00\x0c\x139\x0b\x19\x00\x00\xeaL\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\xff\xf6\x02&\x02\x8a\x01\xf4\x01\x90\x01\xa4\x01E\x01F\x00\x00\x03\xe7\x00\x04
\x13;\x0b\x1b\x00\x00\x00\x00\x00\x00\xa9[\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\x00\x00\x00\x00
x00\x00\x12\xf8\x01E\x01F\x00\x00\x03\xe7\x00\x04\x137\x0b\x19\x00\x00\x00\x00\x00\x00\xa9\x14\x00\x00\x00\x00\x00\x00
x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\x00\x00\x00\x00\x00\x13\x0c\x01E\x01F\x00\x00\x03\xe7\x00\x04\x139\x0b\x17
\x00\x00\x00\x00\x00\x00\xa9R\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x
13\x04\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfd\x00\x00\xff\xfd\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff'

Expected result

Reading pcap file: error.pcap
###[ cooked linux v2 ]###
proto = IPv4
reserved = 0
ifindex = 4
lladdrtype= 0x1
pkttype = unicast-to-another-host
lladdrlen = 6
src = ',\xcfg,\xe2?'
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 307
id = 18082
flags = DF
frag = 0
ttl = 64
proto = tcp
chksum = 0xd998
src = 10.1.2.168
dst = 10.1.2.225
\options \
###[ TCP ]###
sport = 502
dport = 58136
seq = 499266911
ack = 1928828226
dataofs = 8
reserved = 0
flags = PA
window = 249
chksum = 0x7860
urgptr = 0
options = [('NOP', None), ('NOP', None), ('Timestamp', (3747823981, 2872918422))]
###[ ModbusADU ]###
transId = 0x0
protoId = 0x0
len = 249
unitId = 0x1
###[ Read Holding Registers Response ]###
funcCode = 0x3
byteCount = 246
registerVal= [701, 153, 2, 1, 3, 1, 0, 0, 65535, 65535, 976, 977, 0, 999, 12, 4921, 2841, 0, 59980, 0, 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0,
0, 0, 65526, 550, 650, 500, 400, 420, 325, 326, 0, 999, 4, 4923, 2843, 0, 0, 0, 43355, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 4856, 325, 326, 0,
999, 4, 4919, 2841, 0, 0, 0, 43284, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 4876, 325, 326, 0, 999, 4, 4921, 2839, 0, 0, 0, 43346, 0, 0, 0, 0, 0, 0, 0,
127, 0, 0, 0, 4868, 65535, 65535, 65535, 65535, 65535, 65533, 0, 65533, 0, 0, 0, 0, 65535]

Related resources

error.zip

@satveerbrar
Copy link
Contributor

ModbusPDU03ReadHoldingRegistersResponse Packet identifies as a Raw after MayEnd implementation in Jun 26, 2023. Field.py insert all RawVal as-is in packet string.

https://github.com/secdev/scapy/commit/dda902e829a51cc6237e253290c6871f30d7daf3

@satveerbrar
Copy link
Contributor

@gpotter2

This bug was introduced after implementing the safety mechanism max_list_count = 100.
Capture contains register values exceeding 100 which triggers this exception.

if len(val) > (self.max_count or conf.max_list_count): raise MaximumItemsCount( "Maximum amount of items reached in FieldListField: %s " "(defaults to conf.max_list_count)" % (self.max_count or conf.max_list_count) )

Issue resolved for the above capture by setting max_list_count = 123 as the capture includes 123 register Values

@satveerbrar
Copy link
Contributor

Modbus can write up to 123 registers in one packet according to this doc https://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf

image

@jpinedaa Please correct me if I am wrong.

@jpinedaa
Copy link
Author

jpinedaa commented Jan 7, 2025

@satveerbrar I think that's right, should the limit be changed in the repo then?

@satveerbrar
Copy link
Contributor

Yes, I'm planning to do that.
@gpotter2 Do you see any other potential side effects if we bump it to 123.
All unit tests passed with max_list_count = 123

@gpotter2
Copy link
Member

gpotter2 commented Jan 7, 2025

Yeah that sounds good.

The FieldListField and PacketListField have an attribute that allows overwriting the default value set in conf. I think that's the best

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants