Documentation ¶
Overview ¶
Package redis provides a zgrab2 Module that probes for redis services. The default port for redis is TCP 6379, and it is a cleartext protocol defined at https://redis.io/topics/protocol. Servers can be configured to require (cleartext) password authentication, which is omitted from our probe by default (pass --password <your password> to supply one). Further, admins can rename commands, so even if authentication is not required we may not get the expected output. However, we should always get output in the expected format, which is fairly distinct. The probe sends a sequence of commands and checks that the response is well-formed redis data, which should be possible whatever the configuration.
Index ¶
- Constants
- Variables
- func IsNullValue(data RedisValue) bool
- func RegisterModule()
- type BulkString
- type Connection
- type ErrorMessage
- type Flags
- type Integer
- type Module
- type NullType
- type RedisArray
- type RedisType
- type RedisValue
- type Result
- type Scanner
- func (scanner *Scanner) GetName() string
- func (scanner *Scanner) GetPort() uint
- func (scanner *Scanner) GetTrigger() string
- func (scanner *Scanner) Init(flags zgrab2.ScanFlags) error
- func (scanner *Scanner) InitPerSender(senderID int) error
- func (s *Scanner) Protocol() string
- func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error)
- func (scanner *Scanner) StartScan(target *zgrab2.ScanTarget) (*scan, error)
- type SimpleString
Constants ¶
const ( // TypeSimpleString identifies Simple String (string) values TypeSimpleString RedisType = "simple string" // TypeError identifiers Error (string) values TypeError = "error" // TypeInteger identifiers Integer (int64) values TypeInteger = "integer" // TypeBulkString identifies Bulk String ([]byte) values TypeBulkString = "bulk string" // TypeArray identifies Array ([]RedisValue) types TypeArray = "array" )
Variables ¶
var ( // ErrInvalidData is returned when the server returns data that cannot be // interpreted as a valid Redis value. ErrInvalidData = errors.New("invalid data") // ErrWrongType is returned when one identifier is expected but another is // found. ErrWrongType = errors.New("wrong type specifier") // ErrBadLength is returned when an invalid length value is found (e.g. a // negative length or longer than expected). ErrBadLength = errors.New("bad length") )
Functions ¶
func IsNullValue ¶
func IsNullValue(data RedisValue) bool
IsNullValue checks if the value is the Redis NullValue (that is, it is a NullType)
Types ¶
type BulkString ¶
type BulkString []byte
BulkString type -- a binary-safe string with a given length
func (BulkString) Encode ¶
func (str BulkString) Encode() []byte
Encode returns the encoding of this value ("$<base10Length>\r\n<value>\r\n")
func (BulkString) Type ¶
func (BulkString) Type() RedisType
Type identifies this instance as a BulkStringType
type Connection ¶
type Connection struct {
// contains filtered or unexported fields
}
Connection holds the state for a single connection within a scan
func (*Connection) ReadRedisValue ¶
func (conn *Connection) ReadRedisValue() (RedisValue, error)
ReadRedisValue reads a RedisValue of any type from the connection. The next read will return the first byte following the value's terminal LF. If the first byte is not a recognized type identifier, ErrInvalidData is returned.
func (*Connection) SendCommand ¶
func (conn *Connection) SendCommand(cmd string, args ...string) (RedisValue, error)
SendCommand sends the given command+args to the server, then reads/returns the server's response.
func (*Connection) SendInlineCommand ¶
func (conn *Connection) SendInlineCommand(cmd string, args ...string) (RedisValue, error)
SendInlineCommand sends the given command with the inline encoding, and then reads/returns the server's response.
func (*Connection) WriteRedisValue ¶
func (conn *Connection) WriteRedisValue(value RedisValue) error
WriteRedisValue writes the encoded value to the connection.
type ErrorMessage ¶
type ErrorMessage string
ErrorMessage type -- a string, where the first word can optionally be interpreted as an error identifier. See https://redis.io/topics/protocol#resp-errors
func (ErrorMessage) Encode ¶
func (err ErrorMessage) Encode() []byte
Encode returns the encoding of the error message ("-<error message>\r\n")
func (ErrorMessage) ErrorMessage ¶
func (err ErrorMessage) ErrorMessage() string
ErrorMessage returns the "message": if there is a prefix, return everything after it; otherwise, return the whole error string.
func (ErrorMessage) ErrorPrefix ¶
func (err ErrorMessage) ErrorPrefix() string
ErrorPrefix returns the first word of the error message, which can be interpreted as a sort of error code.
func (ErrorMessage) Type ¶
func (ErrorMessage) Type() RedisType
Type identifies this instance as a TypeError
type Flags ¶
type Flags struct { zgrab2.BaseFlags // TODO: Take a JSON/YAML file with a list of custom commands to execute? // TODO: Take a JSON/YAML file with mappings for command names? AuthCommand string `long:"auth-command" default:"AUTH" description:"Override the command used to authenticate. Ignored if no password is set."` Password string `long:"password" description:"Set a password to use to authenticate to the server. WARNING: This is sent in the clear."` DoInline bool `long:"inline" description:"Send commands using the inline syntax"` Verbose bool `long:"verbose" description:"More verbose logging, include debug fields in the scan results"` }
Flags contains redis-specific command-line flags.
type Integer ¶
type Integer int64
Integer type -- an int64; "the returned integer is guaranteed to be in the range of a signed 64 bit integer" See https://redis.io/topics/protocol#resp-integers
type Module ¶
type Module struct { }
Module implements the zgrab2.Module interface
func (*Module) NewFlags ¶
func (module *Module) NewFlags() interface{}
NewFlags provides an empty instance of the flags that will be filled in by the framework
func (*Module) NewScanner ¶
NewScanner provides a new scanner instance
type NullType ¶
type NullType []byte
NullType -- a special type for the NullValue. Represented on the wire as a bulk string with -1 length.
NullValue is a global NullType instance. Should not be used for comparisons (use IsNullValue).
type RedisArray ¶
type RedisArray []RedisValue
RedisArray type -- an array of other RedisValues. See https://redis.io/topics/protocol#resp-arrays
func (RedisArray) Encode ¶
func (array RedisArray) Encode() []byte
Encode returns the encoding of the array, e.g. "*<base10Size>\r\n<element 1><element 2>..."
func (RedisArray) Type ¶
func (RedisArray) Type() RedisType
Type identifies this instance as a TypeArray
type RedisValue ¶
RedisValue is implemented by any redis that can be returned by the server
type Result ¶
type Result struct { // Commands is the list of commands actually sent to the server, serialized // in inline format (e.g. COMMAND arg1 "arg 2" arg3) Commands []string `json:"commands,omitempty" zgrab:"debug"` // RawCommandOutput is the output returned by the server for each command sent; // the index in RawCommandOutput matches the index in Commands. RawCommandOutput [][]byte `json:"raw_command_output,omitempty" zgrab:"debug"` // PingResponse is the response from the server, should be the simple string // "PONG". // NOTE: This is invoked *before* calling AUTH, so this may return an auth // required error even if --password is provided. PingResponse string `json:"ping_response,omitempty"` // InfoResponse is the response from the INFO command: "Lines can contain a // section name (starting with a # character) or a property. All the // properties are in the form of field:value terminated by \r\n." InfoResponse string `json:"info_response,omitempty"` // QuitResponse is the response from the QUIT command -- should be the // simple string "OK" even when authentication is required, unless the // QUIT command was renamed. QuitResponse string `json:"quit_response,omitempty"` // NonexistentResponse is the response to the non-existent command; even if // auth is required, this may give a different error than existing commands. NonexistentResponse string `json:"nonexistent_response,omitempty"` // AuthResponse is only included if --password is set. AuthResponse string `json:"auth_response,omitempty"` // Version is read from the InfoResponse (the field "server_version"), if // present. Version string `json:"version,omitempty"` }
Result is the struct that is returned by the scan. If authentication is required, most responses can have the value "(error: NOAUTH Authentication required.)"
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 ¶
func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error)
Scan executes the following commands: 1. PING 2. (only if --password is provided) AUTH <password> 3. INFO 4. NONEXISTENT 5. QUIT The responses for each of these is logged, and if INFO succeeds, the version is scraped from it.
type SimpleString ¶
type SimpleString string
SimpleString type -- must not contain \r or \n. https://redis.io/topics/protocol#resp-simple-strings
func (SimpleString) Encode ¶
func (str SimpleString) Encode() []byte
Encode returns the SimpleString encoding of the value ("+<string value>\r\n").
func (SimpleString) Type ¶
func (SimpleString) Type() RedisType
Type identifies this instance as a TypeSimpleString