ntp

package
v0.1.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 10, 2023 License: Apache-2.0, ISC Imports: 10 Imported by: 0

Documentation

Overview

Package ntp provides a zgrab2 module that probes for the NTP service. NOTE: unlike most modules, this scans on UDP.

The default scan does a standard get time request.

Passing the monlist flag will check for the DDoS-amplifying MONLIST command.

The results of the scan are the version number and the time returned by the server, and if verbose results are enabled, the entire parsed response packet(s).

For more details on NTP, see https://tools.ietf.org/html/rfc5905.

Index

Constants

View Source
const (
	// NoWarning is a LeapIndicator that indicates that there is no problem
	NoWarning LeapIndicator = 0

	// ExtraSecond is a LeapIndicator that indicates that the last minute has 61 seconds
	ExtraSecond = 1

	// MissingSecond is a LeapIndicator that indicates that the last minute has 59 seconds
	MissingSecond = 2

	// Unknown is a LeapIndicator that indicates an unknown alarm condition
	Unknown = 3
)
View Source
const (
	// Reserved is a reserved AssociationMode
	Reserved AssociationMode = 0

	// SymmetricActive is an AssociationMode indicating that the service is in the active symmetric mode
	SymmetricActive = 1

	// SymmetricPassive is an AssociationMode indicating that the service is in the passive symmetric mode
	SymmetricPassive = 2

	// Client is an AssociationMode indicating that the caller is a client
	Client = 3

	// Server is an AssociationMode indicating that the packet is to be interpreted as a server
	Server = 4

	// Broadcast is an AssociationMode indicating that the this is a broadcast packet
	Broadcast = 5

	// Control is an AssociationMode reserved for NTP control messages
	Control = 6

	// Private is an AssociationMode reserved for private use
	Private = 7
)
View Source
const (
	// ImplUniv corresponds to the IMPL_UNIV constant
	ImplUniv ImplNumber = 0

	// ImplXNTPDOld corresponds to the IMPL_XNTPD_OLD constant
	ImplXNTPDOld = 2

	// ImplXNTPD corresponds to the IMPL_XNTPD constant
	ImplXNTPD = 3
)

Constants from ntp/include/ntp_request.h

View Source
const (
	// ReqPeerList corresponds to the REQ_PEER_LIST constant
	ReqPeerList RequestCode = 0

	// ReqPeerListSum  corresponds to the REQ_PEER_LIST_SUM constant
	ReqPeerListSum = 1

	// ReqPeerInfo  corresponds to the REQ_PEER_INFO constant
	ReqPeerInfo = 2

	// ReqPeerStats  corresponds to the REQ_PEER_STATS constant
	ReqPeerStats = 3

	// ReqSysInfo  corresponds to the REQ_SYS_INFO constant
	ReqSysInfo = 4

	// ReqSysStats  corresponds to the REQ_SYS_STATS constant
	ReqSysStats = 5

	// ReqIOStats  corresponds to the REQ_IO_STATS constant
	ReqIOStats = 6

	// ReqMemStats  corresponds to the REQ_MEM_STATS constant
	ReqMemStats = 7

	// ReqLoopInfo  corresponds to the REQ_LOOP_INFO constant
	ReqLoopInfo = 8

	// ReqTimerStats  corresponds to the REQ_TIMER_STATS constant
	ReqTimerStats = 9

	// ReqConfig  corresponds to the REQ_CONFIG constant
	ReqConfig = 10

	// ReqUnconfig  corresponds to the REQ_UNCONFIG constant
	ReqUnconfig = 11

	// ReqSetSysFlag  corresponds to the REQ_SET_SYS_FLAG constant
	ReqSetSysFlag = 12

	// ReqClrSysFlag  corresponds to the REQ_CLR_SYS_FLAG constant
	ReqClrSysFlag = 13

	// ReqMonitor  corresponds to the REQ_MONITOR constant
	ReqMonitor = 14

	// ReqNoMonitor  corresponds to the REQ_NOMONITOR constant
	ReqNoMonitor = 15

	// ReqGetRestrict  corresponds to the REQ_GET_RESTRICT constant
	ReqGetRestrict = 16

	// ReqResAddFlags  corresponds to the REQ_RES_ADD_FLAGS constant
	ReqResAddFlags = 17

	// ReqResSubFlags  corresponds to the REQ_RES_SUB_FLAGS constant
	ReqResSubFlags = 18

	// ReqUnrestrict  corresponds to the REQ_UNRESTRICT constant
	ReqUnrestrict = 19

	// ReqMonGetList  corresponds to the REQ_MON_GETLIST constant
	ReqMonGetList = 20

	// ReqResetStats  corresponds to the REQ_RESET_STATS constant
	ReqResetStats = 21

	// ReqResetPeer  corresponds to the REQ_RESET_PEER constant
	ReqResetPeer = 22

	// ReqRereadKeys  corresponds to the REQ_REREAD_KEYS constant
	ReqRereadKeys = 23

	// ReqDoDirtyHack  corresponds to the REQ_DO_DIRTY_HACK constant
	ReqDoDirtyHack = 24

	// ReqDontDirtyHack  corresponds to the REQ_DONT_DIRTY_HACK constant
	ReqDontDirtyHack = 25

	// ReqTrustKey  corresponds to the REQ_TRUST_KEY constant
	ReqTrustKey = 26

	// ReqUntrustKey  corresponds to the REQ_UNTRUST_KEY constant
	ReqUntrustKey = 27

	// ReqAuthInfo  corresponds to the REQ_AUTH_INFO constant
	ReqAuthInfo = 28

	// ReqTraps  corresponds to the REQ_TRAPS constant
	ReqTraps = 29

	// ReqAddTrap  corresponds to the REQ_ADD_TRAP constant
	ReqAddTrap = 30

	// ReqClrTrap  corresponds to the REQ_CLR_TRAP constant
	ReqClrTrap = 31

	// ReqRequestKey  corresponds to the REQ_REQUEST_KEY constant
	ReqRequestKey = 32

	// ReqControlKey  corresponds to the REQ_CONTROL_KEY constant
	ReqControlKey = 33

	// ReqGetCtlStats  corresponds to the REQ_GET_CTLSTATS constant
	ReqGetCtlStats = 34

	// ReqGetLeapInfo  corresponds to the REQ_GET_LEAPINFO constant
	ReqGetLeapInfo = 35

	// ReqGetClockInfo  corresponds to the REQ_GET_CLOCKINFO constant
	ReqGetClockInfo = 36

	// ReqSetClkFudge  corresponds to the REQ_SET_CLKFUDGE constant
	ReqSetClkFudge = 37

	// ReqGetKernel  corresponds to the REQ_GET_KERNEL constant
	ReqGetKernel = 38

	// ReqGetClkBugInfo  corresponds to the REQ_GET_CLKBUGINFO constant
	ReqGetClkBugInfo = 39

	// ReqSetPrecision  corresponds to the REQ_SET_PRECISION constant
	ReqSetPrecision = 41

	// ReqMonGetList1  corresponds to the REQ_MON_GETLIST_1 constant
	ReqMonGetList1 = 42

	// ReqHostnameAssocID  corresponds to the REQ_HOSTNAME_ASSOCID constant
	ReqHostnameAssocID = 43

	// ReqIfStats  corresponds to the REQ_IF_STATS constant
	ReqIfStats = 44

	// ReqIfReload  corresponds to the REQ_IF_RELOAD constant
	ReqIfReload = 45
)
View Source
const (
	// InfoErrorOkay corresponds to the INFO_OKAY constant
	InfoErrorOkay InfoError = 0

	// InfoErrorImpl corresponds to the INFO_ERR_IMPL constant
	InfoErrorImpl = 1

	// InfoErrorReq corresponds to the INFO_ERR_REQ constant
	InfoErrorReq = 2

	// InfoErrorFmt corresponds to the INFO_ERR_FMT constant
	InfoErrorFmt = 3

	// InfoErrorNoData corresponds to the INFO_ERR_NODATA constant
	InfoErrorNoData = 4

	// InfoErrorUnknown5 has no corresponding constant (it is the unused value 5)
	InfoErrorUnknown5 = 5

	// InfoErrorUnknown6 has no corresponding constant (it is the unused value 6)
	InfoErrorUnknown6 = 6

	// InfoErrorAuth corresponds to the INFO_ERR_AUTH constant
	InfoErrorAuth = 7
)

Variables

View Source
var (
	// ErrInvalidLeapIndicator is returned if an invalid LeapIndicator is found
	ErrInvalidLeapIndicator = errors.New("leap indicator not valid")

	// ErrInvalidVersion is returned if an invalid version number is found
	ErrInvalidVersion = errors.New("version number not valid")

	// ErrInvalidMode is returned if an invalid mode identifier is found
	ErrInvalidMode = errors.New("mode not valid")

	// ErrInvalidStratum is returned if an invalid stratum identifier is found
	ErrInvalidStratum = errors.New("stratum invalid")

	// ErrInvalidReferenceID is returned if an invalid reference ID is found (i.e. it contains non-ASCII characters)
	ErrInvalidReferenceID = errors.New("reference ID contained non-ASCII characters")

	// ErrBufferTooSmall is returned if a buffer is not large enough to contain the input
	ErrBufferTooSmall = errors.New("buffer too small")

	// ErrInvalidHeader is returned if the header cannot be interpreted as a valid NTP header
	ErrInvalidHeader = errors.New("invalid header data")

	// ErrInvalidResponse is returned if the response cannot be interpreted as a valid NTP response
	ErrInvalidResponse = errors.New("invalid response")

	// ErrInvalidRequestCode is returned if an invalid RequestCode is found
	ErrInvalidRequestCode = errors.New("request code invalid")
)

Functions

func RegisterModule

func RegisterModule()

RegisterModule registers the module with zgrab2

Types

type AssociationMode

type AssociationMode uint8

AssociationMode is a three-bit value, whose values are defined in figure 9 of https://tools.ietf.org/html/rfc5905

type Flags

type Flags struct {
	zgrab2.BaseFlags
	zgrab2.UDPFlags
	Verbose       bool   `long:"verbose" description:"More verbose logging, include debug fields in the scan results"`
	Version       uint8  `long:"version" description:"The version number to pass to the Server." default:"3"`
	LeapIndicator uint8  `long:"leap-indicator" description:"The LI value to pass to the Server. Default 3 (Unknown)"`
	SkipGetTime   bool   `long:"skip-get-time" description:"If set, don't request the Server time"`
	MonList       bool   `long:"monlist" description:"Perform a ReqMonGetList request"`
	RequestCode   string `long:"request-code" description:"Specify a request code for MonList other than ReqMonGetList" default:"REQ_MON_GETLIST"`
}

Flags holds the command-line flags for the scanner.

func (*Flags) Help

func (cfg *Flags) Help() string

Help returns the module's help string

func (*Flags) Validate

func (cfg *Flags) Validate(args []string) error

Validate checks that the flags are valid

type ImplNumber

type ImplNumber uint8

ImplNumber is an 8-bit value used in Private packets

func (ImplNumber) MarshalJSON

func (num ImplNumber) MarshalJSON() ([]byte, error)

MarshalJSON gives the #define name, or "UNKNOWN (0x##)"

type InfoError

type InfoError uint8

InfoError is a 3-bit integer, values taken from ntp_request.h

func (InfoError) Error

func (err InfoError) Error() string

Error implements the error interface (returns the #define name, or "UNKNOWN (0x##)")

func (InfoError) MarshalJSON

func (err InfoError) MarshalJSON() ([]byte, error)

MarshalJSON gives the #define name, or "UNKNOWN (0x##)"

type LeapIndicator

type LeapIndicator uint8

LeapIndicator is a two-bit field, whose values are defined in figure 9 of https://tools.ietf.org/html/rfc5905

type Module

type Module struct {
}

Module is the zgrab2 module implementation

func (*Module) Description

func (module *Module) Description() string

Description returns an overview of this module.

func (*Module) NewFlags

func (module *Module) NewFlags() interface{}

NewFlags returns a flags instant to be populated with the command line args

func (*Module) NewScanner

func (module *Module) NewScanner() zgrab2.Scanner

NewScanner returns a new NTP scanner instance

type NTPHeader

type NTPHeader struct {
	// LeapIndicator is the the top two bits of the first byte
	LeapIndicator LeapIndicator `json:"leap_indicator"`

	// Version is bits 5..3 of the first byte
	Version uint8 `json:"version"`

	// The mode is the lowest three bits of the first byte
	Mode AssociationMode `json:"mode"`

	// Stratum is defined in figure 11: values > 16 are Reserved
	Stratum uint8 `json:"stratum"`

	// Poll: 8-bit signed integer representing the maximum interval between
	// successive messages, in log2 seconds.
	Poll int8 `json:"poll"`

	// Precision: 8-bit signed integer representing the precision of the system clock, in log2 seconds.
	Precision int8 `json:"precision"`

	// Root Delay: Total round-trip delay to the reference clock
	RootDelay NTPShort `json:"root_delay"`

	// Root Dispersion: Total dispersion to the reference clock
	RootDispersion NTPShort `json:"root_dispersion"`

	// Reference ID (refid): 32-bit code identifying the particular Server or reference clock.
	ReferenceID ReferenceID `json:"reference_id,omitempty"`

	// Reference Timestamp: Time when the system clock was last set or corrected
	ReferenceTimestamp NTPLong `json:"reference_timestamp,omitempty"`

	// Origin Timestamp (org): Time at the Client when the request departed for the Server
	OriginTimestamp NTPLong `json:"origin_timestamp,omitempty"`

	// Receive Timestamp (rec): Time at the Server when the request arrived from the Client
	ReceiveTimestamp NTPLong `json:"receive_timestamp,omitempty"`

	// Transmit Timestamp (xmt): Time at the Server when the response left for the Client
	TransmitTimestamp NTPLong `json:"transmit_timestamp,omitempty"`
}

NTPHeader is defined in figure 8 of RFC5905

func (*NTPHeader) Encode

func (header *NTPHeader) Encode() ([]byte, error)

Encode returns the encoding of the header according to RFC5905

func (*NTPHeader) ValidateSyntax

func (header *NTPHeader) ValidateSyntax() error

ValidateSyntax checks that the header's values are within range and make semantic sense

type NTPLong

type NTPLong struct {
	Seconds  uint32 `json:"seconds"`
	Fraction uint32 `json:"fraction"`
}

NTPLong is a 64-bit fixed-length number defined in figure 3 of RFC5905

func (*NTPLong) Decode

func (when *NTPLong) Decode(buf []byte) error

Decode populates the values of this NTPShort with the first 8 bytes of buf

func (*NTPLong) Encode

func (when *NTPLong) Encode() []byte

Encode encodes the NTPShort according to RFC5905 -- upper 32 bits the seconds, lower 32 bits the fractional seconds (big endian)

func (*NTPLong) GetNanos

func (when *NTPLong) GetNanos() uint64

GetNanos gets the number of nanoseconds represented by when.Fraction

func (*NTPLong) GetTime

func (when *NTPLong) GetTime() time.Time

GetTime gets the absolute time.Time corresponding to when

func (*NTPLong) SetNanos

func (when *NTPLong) SetNanos(nanos int)

SetNanos sets when.Fraction to the binary fractional value corresponding to nanos nanoseconds

func (*NTPLong) SetTime

func (when *NTPLong) SetTime(t time.Time)

SetTime sets the absolute time.Time

type NTPShort

type NTPShort struct {
	Seconds  uint16 `json:"seconds"`
	Fraction uint16 `json:"fraction"`
}

NTPShort a 32-bit struct defined in figure 3 of RFC5905.

func (*NTPShort) Decode

func (when *NTPShort) Decode(buf []byte) error

Decode populates the values of this NTPShort with the first 4 bytes of buf

func (*NTPShort) Encode

func (when *NTPShort) Encode() []byte

Encode encodes the NTPShort according to RFC5905 -- upper 16 bits the seconds, lower 16 bits the fractional seconds (big endian)

func (*NTPShort) GetDuration

func (when *NTPShort) GetDuration() time.Duration

GetDuration gets the time.Duration corresponding to when

func (*NTPShort) GetNanos

func (when *NTPShort) GetNanos() uint32

GetNanos gets the number of nanoseconds represented by when.Fraction

func (*NTPShort) SetDuration

func (when *NTPShort) SetDuration(d time.Duration)

SetDuration sets the Seconds and Fraction to match the given duration

func (*NTPShort) SetNanos

func (when *NTPShort) SetNanos(nanos int)

SetNanos sets when.Fraction to the binary fractional value corresponding to nanos nanoseconds

type PrivatePacketHeader

type PrivatePacketHeader struct {
	IsResponse           bool            `json:"is_response"`
	HasMore              bool            `json:"has_more"`
	Version              uint8           `json:"version"`
	Mode                 AssociationMode `json:"mode"`
	IsAuthenticated      bool            `json:"is_authenticated"`
	SequenceNumber       uint8           `json:"sequence_number"`
	ImplementationNumber ImplNumber      `json:"implementation_number"`
	RequestCode          RequestCode     `json:"request_code"`
	Error                InfoError       `json:"error"`
	NumItems             uint16          `json:"num_items"`
	MBZ                  uint8           `json:"mbz"`
	ItemSize             uint16          `json:"item_size"`
}

PrivatePacketHeader represents a header for a mode-7 packet, roughly corresponding to struct resp_pkt in ntp_request.h

func (*PrivatePacketHeader) Encode

func (header *PrivatePacketHeader) Encode() ([]byte, error)

Encode encodes the packet header as a struct resp_pkt

type ReferenceID

type ReferenceID [4]byte

ReferenceID is defined in RFC5905 as a 32-bit code whose interpretation depends on the stratum field

func (ReferenceID) MarshalJSON

func (id ReferenceID) MarshalJSON() ([]byte, error)

MarshalJSON ensures that it is marshalled like a slice, not an array

type RequestCode

type RequestCode uint8

RequestCode is an 8-bit value used in Private packets, from ntp/include/ntp_request.h

func (RequestCode) MarshalJSON

func (code RequestCode) MarshalJSON() ([]byte, error)

MarshalJSON gives the #define name, or "UNKNOWN (0x##)"

type Results

type Results struct {
	// Version is the version number returned in the get time response header.
	// Absent if --skip-get-time is set.
	Version *uint8 `json:"version,omitempty"`

	// Time is the time returned by the server (specifically, the
	// ReceiveTimestamp) in response to the get time call. Converted into a
	// standard golang time.
	// Absent if --skip-get-time is set.
	Time *time.Time `json:"time,omitempty"`

	// TimeResponse is the full header returned by the get time call.
	// Absent if --skip-get-time is set. Debug only.
	TimeResponse *NTPHeader `json:"time_response,omitempty" zgrab:"debug"`

	// MonListResponse is the raw data returned by the call to monlist.
	// Only present if --monlist is set.
	MonListResponse []byte `json:"monlist_response,omitempty"`

	// MonListHeader is the header returned by the call to monlist.
	// Only present if --monlist is set. Debug only.
	MonListHeader *PrivatePacketHeader `json:"monlist_header,omitempty" zgrab:"debug"`
}

Results is the struct that is returned to the zgrab2 framework from Scan()

type Scanner

type Scanner struct {
	// contains filtered or unexported fields
}

Scanner holds the state for a single scan

func (*Scanner) GetName

func (scanner *Scanner) GetName() string

GetName returns the module's name

func (*Scanner) GetTime

func (scanner *Scanner) GetTime(sock net.Conn) (*NTPHeader, error)

GetTime sends a "Client" packet to the Server and reads / returns the response

func (*Scanner) GetTrigger

func (scanner *Scanner) GetTrigger() string

GetTrigger returns the Trigger defined in the Flags.

func (*Scanner) Init

func (scanner *Scanner) Init(flags zgrab2.ScanFlags) error

Init initialized the scanner

func (*Scanner) InitPerSender

func (scanner *Scanner) InitPerSender(senderID int) error

InitPerSender initializes the scanner for a given sender

func (*Scanner) MonList

func (scanner *Scanner) MonList(sock net.Conn, result *Results) (zgrab2.ScanStatus, error)

MonList does a ReqMonGetList call to the Server and populates result with the output

func (*Scanner) Protocol

func (s *Scanner) Protocol() string

Protocol returns the protocol identifer for the scanner.

func (*Scanner) Scan

func (scanner *Scanner) Scan(t zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error)

Scan scans the configured server with the settings provided by the command line arguments as follows:

  1. If SkipGetTime is not set, send a GetTime packet to the server and read the response packet into the result.
  2. If MonList is set, send a MONLIST packet to the server and read the response packet into the result.

The presence of an NTP service at the target can be inferred by a non-nil result -- if the service does not return any data or if the response is not a valid NTP packet, then the result will be nil. The presence of a DDoS-amplifying target can be inferred by result.MonListReponse being present.

func (*Scanner) SendAndReceive

func (scanner *Scanner) SendAndReceive(impl ImplNumber, req RequestCode, body []byte, sock net.Conn) (*PrivatePacketHeader, []byte, error)

SendAndReceive is a rough version of ntpdc.c's doquery(), except it only supports a single packet response

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL