Documentation ¶
Overview ¶
Package modbus provides a zgrab2 module that scans for modbus. Default Port: 502 (TCP)
The --unit-id flag allows overriding the default value of 0 (the simulator for example does not respond at all to UnitID == 0; other servers may interpret it as a broadcast).
The --object-id flag allows reading a different object ID's information. The default of 0x00 is the VendorName, which is required.
The --request-id flag allows setting a custom request identifier (which the server will use in its response).
The --strict flag allows turning on new validity checks beyond those done in the original zgrab, to help rule out false matches.
The output is the same as the original ZGrab: a "modbus event" object, with either the parsed MEI response or the parsed exception info. The only addition is a "raw" field containing the raw response data.
Index ¶
- Constants
- Variables
- func RegisterModule()
- type Conn
- type ExceptionCode
- type ExceptionFunctionCode
- type ExceptionResponse
- type Flags
- type FunctionCode
- type MEIObject
- type MEIObjectID
- type MEIObjectSet
- type MEIResponse
- type ModbusEvent
- type ModbusRequest
- type ModbusResponse
- type Module
- type Scanner
- func (scanner *Scanner) GetName() string
- func (scanner *Scanner) GetTrigger() string
- func (scanner *Scanner) Init(flags zgrab2.ScanFlags) error
- func (scanner *Scanner) InitPerSender(senderID int) error
- func (scanner *Scanner) Protocol() string
- func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error)
Constants ¶
const ( // FunctionCodeMEI identifies the MEI read function. FunctionCodeMEI = FunctionCode(0x2B) )
Variables ¶
var ModbusFunctionEncapsulatedInterface = FunctionCode(0x2B)
ModbusFunctionEncapsulatedInterface identifies the MEI read function.
Functions ¶
Types ¶
type Conn ¶
Conn wraps the connection state (more importantly, it provides the interface used by the old zgrab code, so that it could be taken over as-is).
func (*Conn) GetModbusResponse ¶
func (c *Conn) GetModbusResponse() (*ModbusResponse, error)
GetModbusResponse reads the response from the server and does some minimal parsing.
func (*Conn) MarshalRequest ¶
func (c *Conn) MarshalRequest(r *ModbusRequest) (data []byte, err error)
MarshalRequest marshals the request for transport to the server.
type ExceptionCode ¶
type ExceptionCode byte
ExceptionCode represents the exception description codes.
type ExceptionFunctionCode ¶
type ExceptionFunctionCode byte
ExceptionFunctionCode represents the function code corresponding to an exception -- that is, with the high bit set.
func (ExceptionFunctionCode) FunctionCode ¶
func (e ExceptionFunctionCode) FunctionCode() FunctionCode
FunctionCode strips the high bit off of the exception function code, to get the function for which the server is responding.
type ExceptionResponse ¶
type ExceptionResponse struct { // ExceptionFunction is the function to which the server is responding -- namely, the value of the FunctionCode in // the response with the high bit masked off. ExceptionFunction FunctionCode `json:"exception_function"` // ExceptionType is the type code representing the exception. // For details see e.g. section 7 of http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf ExceptionType byte `json:"exception_type"` }
ExceptionResponse wraps the exception returned by the server.
type Flags ¶
type Flags struct { zgrab2.BaseFlags // Protocols that support TLS should include zgrab2.TLSFlags UnitID uint8 `long:"unit-id" description:"The UnitID / Station ID to probe"` ObjectID uint8 `long:"object-id" description:"The ObjectID of the object to be read." default:"0x00"` Strict bool `long:"strict" description:"If set, perform stricter checks on the response data to get fewer false positives"` RequestID uint16 `long:"request-id" description:"Override the default request ID." default:"0x5A47"` Verbose bool `long:"verbose" description:"More verbose logging, include debug fields in the scan results"` }
Flags holds the command-line configuration for the modbus scan module. Populated by the framework.
type FunctionCode ¶
type FunctionCode byte
FunctionCode identifies the Modbus function being queried.
func (FunctionCode) ExceptionFunctionCode ¶
func (c FunctionCode) ExceptionFunctionCode() ExceptionFunctionCode
ExceptionFunctionCode gets the code that the server would return in an exception to the given function code.
func (FunctionCode) IsException ¶
func (c FunctionCode) IsException() bool
IsException checks if the given function code is an exception (i.e. its high bit is set).
type MEIObject ¶
type MEIObject struct { // OID is the object identifier. OID MEIObjectID // Value is the value for that object identifier. Value string }
MEIObject wraps the ID/value pair in the 0x2B/0x0E response.
func (*MEIObject) MarshalJSON ¶
MarshalJSON encodes the identifier as its friendly name.
type MEIObjectID ¶
type MEIObjectID int
MEIObjectID is the numeric identifier used by the server to identify different data.
const ( // OIDVendor identifies the vendor name. Mandatory ASCII String, category = basic. OIDVendor MEIObjectID = 0 // OIDProductCode identifies the product code. Mandatory ASCII String, category = basic. OIDProductCode MEIObjectID = 1 // OIDRevision identifies the MajorMinorRevision. Mandatory ASCII String, category = basic. OIDRevision MEIObjectID = 2 // OIDVendorURL identifies the vendor URL. Optional ASCII String, category = regular. OIDVendorURL MEIObjectID = 3 // OIDProductName identifies the product name. Optional ASCII String, category = regular. OIDProductName MEIObjectID = 4 // OIDModelName identifies the model name. Optional ASCII String, category = regular. OIDModelName MEIObjectID = 5 // OIDUserApplicationName identifies the user application name. Optional ASCII String, category = regular. OIDUserApplicationName MEIObjectID = 6 )
func (*MEIObjectID) Name ¶
func (m *MEIObjectID) Name() string
Name maps the object ID to its friendly name; if the ID is not on the list, it returns "oid_$(id)".
type MEIObjectSet ¶
type MEIObjectSet []MEIObject
MEIObjectSet wraps the list of object ID/value pairs, encoding them as a dict of ID name -> value
func (*MEIObjectSet) MarshalJSON ¶
func (ms *MEIObjectSet) MarshalJSON() ([]byte, error)
MarshalJSON encodes the object ID list as a map of { "obj.OID.Name()": obj.Value }
type MEIResponse ¶
type MEIResponse struct { // ConformityLevel specifies the confirmity level of the device and the type of supported access. // Valid values include 0x01, 0x02, 0x03, for basic, regular, extended stream access, and // 8x81, 0x82, 0x83 for basic, regular, extended stream/individual access. ConformityLevel int `json:"conformity_level"` // MoreFollows specifies whether more data follows. Strictly should be 00 or FF, but we take any nonzero number // to mean that more data follows. MoreFollows bool `json:"more_follows"` // NextObjectID gives the next object ID if MoreFollows is set, otherwise it should be 0x00. NextObjectID int `json:"next_object_id"` // ObjectCount gives the number of items returned. ObjectCount int `json:"object_count"` // Objects is a set of object ID/value pairs returned by the server. Objects MEIObjectSet `json:"objects,omitempty"` }
MEIResponse is the parsed data field from the 0x2B/0x0E response.
type ModbusEvent ¶
type ModbusEvent struct { // Length is the data length the server claimed to return in the header. Should be len(Response) + 1 (the function // code is included) Length int `json:"length"` // UnitID is the unit ID for which the server is responding. If request unit ID was nonzero, should match that. UnitID int `json:"unit_id"` // Function is the response function code. The high bit indicates the presence of an exception (set -> exception). Function FunctionCode `json:"function_code"` // Response is the response data (not including the function code). Response []byte `json:"raw_response,omitempty"` // MEIResponse is the parsed response; it is present if the response was decoded successfully and there was no // exception. MEIResponse *MEIResponse `json:"mei_response,omitempty"` // ExceptionResponse is the parsed exception; it is present if the response was decoded successfully and there was // an exception (i.e. the high bit of Function is set). ExceptionResponse *ExceptionResponse `json:"exception_response,omitempty"` // Raw is the full raw response from the server, including the header. Raw []byte `json:"raw,omitempty"` }
ModbusEvent is the response object. Either MEIResponse or ExceptionResponse will be set.
type ModbusRequest ¶
type ModbusRequest struct { // UnitID is the target unit ID. 0 can get special treatment (ignored, invalid, or treated as broadcast). UnitID int // FunctionCode identifies the function for the server to execute. Function FunctionCode // Deta is the payload for the request, its format depends on the FunctionCode. Data []byte }
ModbusRequest wraps the Modbus ApplicationDataUnit (ADU).
type ModbusResponse ¶
type ModbusResponse struct { // Length is the number of bytes the server says it will return. Length int // UnitID identifies the unit this response pertains to. UnitID int // Function is the function code returned by the server (which may have the high bit set to indicate an exception). Function FunctionCode // Data is payload, its format depends on the function code. Should be Length - 1 bytes. Data []byte // Raw is the actual data returned by the server, including the header. Raw []byte }
ModbusResponse wraps the data returned by the server in response to the ModbusRequest.
func (*ModbusResponse) IsException ¶
func (m *ModbusResponse) IsException() bool
IsException returns true if this response indicates an exception has occurred.
type Module ¶
type Module struct { }
Module implements the zgrab2.Module interface.
func (*Module) Description ¶
Description returns an overview of this module.
func (*Module) NewFlags ¶
func (module *Module) NewFlags() interface{}
NewFlags returns a default Flags object.
func (*Module) NewScanner ¶
func (module *Module) NewScanner() zgrab2.Scanner
NewScanner returns a new Scanner instance.
type Scanner ¶
type Scanner struct {
// contains filtered or unexported fields
}
Scanner implements the zgrab2.Scanner interface.
func (*Scanner) GetTrigger ¶
GetTrigger returns the Trigger defined in the Flags.
func (*Scanner) InitPerSender ¶
InitPerSender initializes the scanner for a given sender.
func (*Scanner) Scan ¶
Scan probes for a modbus service. It connects to the configured TCP port (default 502) and sends a packet with:
UnitID = <flags.UnitID, default 0> FunctionCode = 0x2B: Encapsulated Interface Transport) MEI Type = 0x0E: Read Device Info Category = 0x01: Basic ObjectID = <flags.ObjectID, default 0: VendorName>
If the response is not a valid modbus response to this packet, then fail with a SCAN_PROTOCOL_ERROR. Otherwise, return the parsed response and status (SCAN_SUCCESS or SCAN_APPLICATION_ERROR)