mssql

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: 11 Imported by: 0

Documentation

Overview

Package mssql provides the zgrab2 scanner module for the MSSQL protocol. Default Port: 1433 (TCP)

The --encrypt-mode flag allows setting an explicit client encryption mode (the default is ENCRYPT_ON). Note: only ENCRYPT_NOT_SUP will skip the TLS handshake, since even ENCRYPT_OFF uses TLS for the login step.

The scan performs a PRELOGIN and if possible does a TLS handshake.

The output is the the server version and instance name, and if applicable the TLS output.

Index

Constants

View Source
const (
	// TDSStatusNormal is a "Normal" message
	TDSStatusNormal uint8 = 0x00

	// TDSStatusEOM is an End of message (EOM). The packet is the last packet in
	// the whole request.
	TDSStatusEOM = 0x01

	// TDSStatusIgnore: Ignore this event (0x01 MUST also be set).
	// Client-to-server.
	TDSStatusIgnore = 0x02

	// TDSStatusResetConnection reset this connection before processing event.
	// Only set for event types Batch, RPC, or Transaction Manager request.
	// This status bit MUST NOT be set in conjunction with
	// the RESETCONNECTIONSKIPTRAN bit.
	// Client-to-server.
	TDSStatusResetConnection = 0x08

	// Reset the connection before processing event but do not modify the
	// transaction state. This status bit MUST NOT be set in conjunction with
	// the RESETCONNECTION bit.
	// Client-to-server.
	TDSStatusResetConnectionSkipTran = 0x10
)

https://msdn.microsoft.com/en-us/library/dd358342.aspx

View Source
const (
	// TDSPacketTypeSQLBatch identifies a SQL batch.
	TDSPacketTypeSQLBatch TDSPacketType = 0x01

	// TDSPacketTypePreTDS7Login is the packet type for clients using "legacy"
	// pre-TDS7 logins.
	TDSPacketTypePreTDS7Login = 0x02

	// TDSPacketTypeRPC identifies an RPC packet.
	TDSPacketTypeRPC = 0x03

	// TDSPacketTypeTabularResult identifies a tabular result.
	TDSPacketTypeTabularResult = 0x04

	// TDSPacketTypeAttentionSignal identifies an attention signal.
	// Packet does not contain data.
	TDSPacketTypeAttentionSignal = 0x06

	// TDSPacketTypeBulkLoadData identifies a bulk-load-data packet.
	TDSPacketTypeBulkLoadData = 0x07

	// TDSPacketTypeFederatedAuthToken identifies a federated authentication
	// token.
	TDSPacketTypeFederatedAuthToken = 0x08

	// TDSPacketTypeTransactionManagerRequest identifies a transaction manager
	// request.
	TDSPacketTypeTransactionManagerRequest = 0x0E

	// TDSPacketTypeTDS7Login identifies a TDS7 login.
	TDSPacketTypeTDS7Login = 0x10

	// TDSPacketTypeSSPI identifies an SSPI packet.
	TDSPacketTypeSSPI = 0x11

	// TDSPacketTypePrelogin identifies a PRELOGIN packet.
	TDSPacketTypePrelogin = 0x12
)
View Source
const (
	// PreloginVersion is the VERSION token. Its value is the concatenation of
	// { major, minor, build >> 8, build & 0xff }.
	PreloginVersion PreloginOptionToken = 0x00

	// PreloginEncryption is the ENCRYPTION token. It is a single byte that
	// specifies what encryption options the client/server support (see
	// EncryptionMode)
	PreloginEncryption = 0x01

	// PreloginInstance is the INSTOPT token. Its value is the null-terminated
	// instance name.
	PreloginInstance = 0x02

	// PreloginThreadID is the THREADID token. Its value is the server's
	// internal thread ID for the connection, an unsigned long.
	PreloginThreadID = 0x03

	// PreloginMARS is the MARS token. Its value is a single byte specifying
	// whether the sender is requesting MARS support.
	PreloginMARS = 0x04

	// PreloginTraceID is the TRACEID token. Its value is the concatenation of
	// the server's GUID for the client (16 bytes), the server's activity GUID
	// (16 bytes) and the sequence ID (unsigned long).
	PreloginTraceID = 0x05

	// PreloginFedAuthRequired is the FEDAUTHREQUIRED token. Its value is a
	// byte representing whether the sender requires federated authentication.
	PreloginFedAuthRequired = 0x06

	// PreloginNonce is the NONCEOPT token. Its value is a 32-byte nonce.
	PreloginNonce = 0x07

	// PreloginTerminator is the TERMINATOR token. It is not an actual tag, but
	// a standalone marker.
	PreloginTerminator = 0xFF
)
View Source
const (
	// EncryptModeUnknown is not a valid ENCRYPTION value
	EncryptModeUnknown EncryptMode = 0xff

	// EncryptModeOff means that encryption will only be used for login
	EncryptModeOff = 0x00

	// EncryptModeOn means that encryption will be used for the entire session
	EncryptModeOn = 0x01

	// EncryptModeNotSupported means that the client/server does not support
	// encryption
	EncryptModeNotSupported = 0x02

	// EncryptModeRequired is sent by the server when the client sends
	// EncryptModNotSupported but the server requires it
	EncryptModeRequired = 0x03
)

Variables

View Source
var (
	// ErrTooLarge is returned when a size is larger than 64k.
	ErrTooLarge = errors.New("data too large")

	// ErrBufferTooSmall is returned when a buffer is smaller than necessary.
	ErrBufferTooSmall = errors.New("buffer too small")

	// ErrInvalidData is returned when we receive data from the server that
	// cannot be interpreted as a valid packet.
	ErrInvalidData = errors.New("received invalid data")

	// ErrNoServerEncryption is returned if the client requires encryption but
	// the server does not support it.
	ErrNoServerEncryption = errors.New("server doesn't support encryption")

	// ErrServerRequiresEncryption is returned if the server requires encryption
	// but the client does not support it.
	ErrServerRequiresEncryption = errors.New("server requires encryption")

	// ErrInvalidState is returned when attempting to take an action that is not
	// allowed in the current state of the connection.
	ErrInvalidState = errors.New("operation cannot be performed in this state")
)

Functions

func RegisterModule

func RegisterModule()

RegisterModule is called by modules/mssql.go's init()

Types

type Connection

type Connection struct {

	// PreloginOptions contains the values returned by the server in the
	// PRELOGIN call, once it has happened.
	PreloginOptions *PreloginOptions
	// contains filtered or unexported fields
}

Connection wraps the state of a single MSSQL connection. NOT thread safe, due e.g. to the state (e.g. messageType) in tdsConnection.

func NewConnection

func NewConnection(conn net.Conn) *Connection

NewConnection creates a new MSSQL connection using the given raw socket connection to the database.

func (*Connection) Close

func (connection *Connection) Close() error

Close closes / resets any resources associated with the connection, and returns the first error (if any) that it encounters.

func (*Connection) Handshake

func (connection *Connection) Handshake(flags *Flags) (EncryptMode, error)

Handshake performs the initial handshake with the MSSQL server. First sends the PRELOGIN packet to the server and reads the response. Then, if necessary, does a TLS handshake. Returns the ENCRYPTION value from the response to PRELOGIN.

func (*Connection) Login

func (connection *Connection) Login()

Login sends the LOGIN packet. Called after Handshake(). If self.getEncryptMode() == EncryptModeOff, disables TLS afterwards. NOTE: Not currently implemented.

func (*Connection) SendTDSPacket

func (connection *Connection) SendTDSPacket(packetType uint8, body []byte) error

SendTDSPacket sends a TDS packet with the given type and body. NOTE - sets tdsConn.messageType to packetType and leaves it there.

type EncryptMode

type EncryptMode byte

EncryptMode is defined at https://msdn.microsoft.com/en-us/library/dd357559.aspx

func (EncryptMode) MarshalJSON

func (mode EncryptMode) MarshalJSON() ([]byte, error)

MarshalJSON ensures that the EncryptMode is encoded in the string format.

func (EncryptMode) String

func (mode EncryptMode) String() string

String returns a string representation of the EncryptMode.

type Flags

type Flags struct {
	zgrab2.BaseFlags
	zgrab2.TLSFlags
	EncryptMode string `` /* 160-byte string literal not displayed */
	Verbose     bool   `long:"verbose" description:"More verbose logging, include debug fields in the scan results"`
}

Flags defines the command-line configuration options for the module.

func (*Flags) Help

func (flags *Flags) Help() string

Help returns the help string for this module.

func (*Flags) Validate

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

Validate does nothing in this module.

type Module

type Module struct {
}

Module is the implementation of zgrab2.Module for the MSSQL protocol.

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 default Flags instance to be populated by the command line flags.

func (*Module) NewScanner

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

NewScanner returns a new Scanner instance.

type PreloginOption

type PreloginOption []byte

PreloginOption values are stored as byte arrays; actual types are specified in the docs

type PreloginOptionToken

type PreloginOptionToken uint8

PreloginOptionToken represents a PL_OPTION_TOKEN value, defined at https://msdn.microsoft.com/en-us/library/dd357559.aspx.

type PreloginOptions

type PreloginOptions map[PreloginOptionToken]PreloginOption

PreloginOptions maps the token to the value for that option

func (PreloginOptions) Encode

func (options PreloginOptions) Encode() ([]byte, error)

Encode returns the encoding of the PRELOGIN body as described in https://msdn.microsoft.com/en-us/library/dd357559.aspx.

func (PreloginOptions) GetByteOption

func (options PreloginOptions) GetByteOption(token PreloginOptionToken) (byte, error)

GetByteOption returns a single-byte PRELOGIN option for the given token. If there is no value for that token present, or if the value is not exactly one byte long, returns an ErrInvalidData.

func (PreloginOptions) GetUint16Option

func (options PreloginOptions) GetUint16Option(token PreloginOptionToken) (uint16, error)

GetUint16Option returns a big-endian uint16 PRELOGIN option for the given token. If there is no value for that token present, or if the value is not exactly two bytes long, returns an ErrInvalidData.

func (PreloginOptions) GetVersion

func (options PreloginOptions) GetVersion() *ServerVersion

GetVersion decodes the VERSION response value if present; if not (or it is invalid), returns nil.

func (PreloginOptions) HeaderSize

func (options PreloginOptions) HeaderSize() int

HeaderSize calculates the length of the PRELOGIN_OPTIONs, i.e. the number of bytes before the payload starts. Each PRELOGIN_OPTION is a 1-byte token, a 2-byte length and a 2-byte offset, and each is followed by a single-byte TERMINATOR, giving 5 * len(*self) + 1.

func (PreloginOptions) MarshalJSON

func (options PreloginOptions) MarshalJSON() ([]byte, error)

MarshalJSON puts the map[PreloginOptionToken]PreloginOption into a more database-friendly format.

func (PreloginOptions) Size

func (options PreloginOptions) Size() int

Size returns the total size of the PRELOGIN packet body (so not including the TDSPacket header). Specifically, it is the header size + the size of all of the values.

type ScanResults

type ScanResults struct {
	// Version is the version returned by the server in the PRELOGIN response.
	// Its format is "MAJOR.MINOR.BUILD_NUMBER".
	Version string `json:"version,omitempty"`

	// InstanceName is the value of the INSTANCE field returned by the server
	// in the PRELOGIN response. Using a pointer to distinguish between the
	// server returning an empty name and no name being returned.
	InstanceName *string `json:"instance_name,omitempty"`

	// PreloginOptions are the raw key-value pairs returned by the server in
	// response to the PRELOGIN call. Debug only.
	PreloginOptions *PreloginOptions `json:"prelogin_options,omitempty" zgrab:"debug"`

	// EncryptMode is the mode negotiated with the server.
	EncryptMode *EncryptMode `json:"encrypt_mode,omitempty"`

	// TLSLog is the shared TLS handshake/scan log.
	TLSLog *zgrab2.TLSLog `json:"tls,omitempty"`
}

ScanResults contains detailed information about each step of the MySQL handshake, and can be encoded to JSON.

type Scanner

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

Scanner is the implementation of zgrab2.Scanner for the MSSQL protocol.

func (*Scanner) GetName

func (scanner *Scanner) GetName() string

GetName returns the configured scanner name.

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 initializes the Scanner instance with the given command-line flags.

func (*Scanner) InitPerSender

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

InitPerSender does nothing in this module.

func (*Scanner) Protocol

func (s *Scanner) Protocol() string

Protocol returns the protocol identifer for the scanner.

func (*Scanner) Scan

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

Scan performs the MSSQL scan. 1. Open a TCP connection to the target port (default 1433). 2. Send a PRELOGIN packet to the server. 3. Read the PRELOGIN response from the server. 4. If the server encrypt mode is EncryptModeNotSupported, break. 5. Perform a TLS handshake, with the packets wrapped in TDS headers. 6. Decode the Version and InstanceName from the PRELOGIN response

type ServerVersion

type ServerVersion struct {
	Major       uint8  `json:"major"`
	Minor       uint8  `json:"minor"`
	BuildNumber uint16 `json:"build_number"`
}

ServerVersion is a direct representation of the VERSION PRELOGIN token value.

func (*ServerVersion) String

func (version *ServerVersion) String() string

String returns the dotted-decimal representation of the ServerVersion: "MAJOR.MINOR.BUILD_NUMBER".

type TDSHeader

type TDSHeader struct {
	// Type is the TDSPacketType.
	Type uint8

	// Status is a bit field indicating message state.
	Status uint8

	// "Length is the size of the packet including the 8 bytes in the packet
	// header. It is the number of bytes from the start of this header to the
	// start of the next packet header. Length is a 2-byte, unsigned short int
	// and is represented in network byte order (big-endian). Starting with TDS
	// 7.3, the Length MUST be the negotiated packet size when sending a packet
	// from client to server, unless it is the last packet of a request (that
	// is, the EOM bit in Status is ON), or the client has not logged in."
	Length uint16

	// SPID is the process ID on the server for the current connection.
	// Provided for debugging purposes (e.g. identify which server thread sent
	// the packet).
	SPID uint16

	// Called PacketID in the docs. Incremented (modulo 256) each time a packet
	// is sent. Allegedly ignored by the server.
	SequenceNumber uint8

	// "This 1 byte is currently not used. This byte SHOULD be set to 0x00 and
	// SHOULD be ignored by the receiver."
	Window uint8
}

TDSHeader is an 8-byte structure prepended to all TDS packets. See https://msdn.microsoft.com/en-us/library/dd340948.aspx for details.

func (*TDSHeader) Encode

func (header *TDSHeader) Encode() []byte

Encode returns the encoding of the header as a byte slice.

type TDSPacket

type TDSPacket struct {
	TDSHeader
	Body []byte
}

TDSPacket is a header followed by the body. Length is calculated from the start of the packet, NOT the start of the body.

func (*TDSPacket) Encode

func (packet *TDSPacket) Encode() ([]byte, error)

Encode returns the encoded packet: header + body. Updates the header's length to match the actual body length.

type TDSPacketType

type TDSPacketType uint8

TDSPacketType represents the Type entry in the TDSPacket. Values are defined at https://msdn.microsoft.com/en-us/library/dd304214.aspx.

Jump to

Keyboard shortcuts

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