add some tighter bounds checking in MSSQL scanner, and if there is an uncaught panic, log the body that caused it
This commit is contained in:
parent
e7e7be1f6f
commit
6618920234
|
@ -11,7 +11,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
logrus "github.com/sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/zmap/zgrab2"
|
||||
)
|
||||
|
||||
|
@ -401,6 +401,9 @@ func (options PreloginOptions) Encode() ([]byte, error) {
|
|||
for _, ik := range sortedKeys {
|
||||
k := PreloginOptionToken(ik)
|
||||
v := options[k]
|
||||
if len(cursor) < 5 {
|
||||
return nil, fmt.Errorf("encode: size mismatch (options.Size()=%d)", options.Size())
|
||||
}
|
||||
cursor[0] = byte(k)
|
||||
if offset > 0xffff {
|
||||
return nil, ErrTooLarge
|
||||
|
@ -411,6 +414,9 @@ func (options PreloginOptions) Encode() ([]byte, error) {
|
|||
offset += len(v)
|
||||
cursor = cursor[5:]
|
||||
}
|
||||
if len(cursor) < 1 {
|
||||
return nil, fmt.Errorf("encode: size mismatch (options.Size()=%d, len(sortedKeys)=%d)", options.Size(), len(sortedKeys))
|
||||
}
|
||||
// Write the terminator after the last PL_OPTION header
|
||||
// (and just before the first value)
|
||||
cursor[0] = 0xff
|
||||
|
@ -421,6 +427,9 @@ func (options PreloginOptions) Encode() ([]byte, error) {
|
|||
// returned in rest.
|
||||
// If body can't be decoded as a PRELOGIN body, returns nil, nil, ErrInvalidData
|
||||
func decodePreloginOptions(body []byte) (result *PreloginOptions, rest []byte, err error) {
|
||||
if len(body) < 1 {
|
||||
return nil, nil, ErrInvalidData
|
||||
}
|
||||
cursor := body[:]
|
||||
options := make(PreloginOptions)
|
||||
max := 0
|
||||
|
@ -506,7 +515,13 @@ func (options PreloginOptions) MarshalJSON() ([]byte, error) {
|
|||
|
||||
fedAuthRequired, hasFedAuthRequired := opts[PreloginFedAuthRequired]
|
||||
if hasFedAuthRequired {
|
||||
aux.FedAuthRequired = &fedAuthRequired[0]
|
||||
temp := uint8(0)
|
||||
if len(fedAuthRequired) > 0 {
|
||||
temp = fedAuthRequired[0]
|
||||
} else {
|
||||
logrus.Debugf("fedAuthRequired was present but empty (options=%#v)", options)
|
||||
}
|
||||
aux.FedAuthRequired = &temp
|
||||
}
|
||||
|
||||
nonce, hasNonce := opts[PreloginNonce]
|
||||
|
@ -632,6 +647,7 @@ func (connection *Connection) readPreloginPacket() (*TDSPacket, *PreloginOptions
|
|||
if packet.Type != TDSPacketTypeTabularResult {
|
||||
return packet, nil, &zgrab2.ScanError{Status: zgrab2.SCAN_APPLICATION_ERROR, Err: err}
|
||||
}
|
||||
defer zgrab2.LogPanic("Error decoding Prelogin packet %#v", packet.Body)
|
||||
plOptions, rest, err := decodePreloginOptions(packet.Body)
|
||||
if err != nil {
|
||||
return packet, nil, err
|
||||
|
|
17
utility.go
17
utility.go
|
@ -10,6 +10,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/zmap/zflags"
|
||||
"github.com/sirupsen/logrus"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
var parser *flags.Parser
|
||||
|
@ -209,3 +211,18 @@ func IsTimeoutError(err error) bool {
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
// LogPanic is intended to be called from within defer -- if there was no panic, it returns without
|
||||
// doing anything. Otherwise, it logs the stacktrace, the panic error, and the provided message
|
||||
// before re-raising the original panic.
|
||||
// Example:
|
||||
// defer zgrab2.LogPanic("Error decoding body '%x'", body)
|
||||
func LogPanic(format string, args...interface{}) {
|
||||
err := recover()
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
logrus.Errorf("Uncaught panic at %s: %v", string(debug.Stack()), err)
|
||||
logrus.Errorf(format, args...)
|
||||
panic(err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue