mongodb: Use OP_QUERY for buildinfo for wire proto < 6 (#330)

This commit is contained in:
dabdine 2021-10-13 03:15:25 -07:00 committed by GitHub
parent c9a9ac1df0
commit a1fba22c6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -41,31 +41,6 @@ func (scan *scan) Close() {
defer scan.close()
}
// getCommandMsg returns a mongodb message containing the specified BSON-encoded command.
// metdata and commandArgs expected to be BSON byte arrays.
func getCommandMsg(database string, commandName string, metadata []byte, commandArgs []byte) []byte {
dblen := len(database) + 1
cnlen := len(commandName) + 1
mdlen := len(metadata)
calen := len(commandArgs)
msglen := MSGHEADER_LEN + dblen + cnlen + len(metadata) + len(commandArgs)
out := make([]byte, msglen)
// msg header
binary.LittleEndian.PutUint32(out[0:], uint32(msglen))
binary.LittleEndian.PutUint32(out[12:], OP_COMMAND)
// command msg
idx := MSGHEADER_LEN
copy(out[idx:idx+dblen], []byte(database))
idx += dblen
copy(out[idx:idx+cnlen], []byte(commandName))
idx += cnlen
copy(out[idx:idx+mdlen], metadata)
idx += mdlen
copy(out[idx:idx+calen], commandArgs)
return out
}
// getIsMasterMsg returns a mongodb message containing isMaster command.
// https://docs.mongodb.com/manual/reference/command/isMaster/
func getIsMasterMsg() []byte {
@ -78,21 +53,15 @@ func getIsMasterMsg() []byte {
return query_msg
}
// getBuildInfoCommandMsg returns a mongodb message containing a command to retrieve MongoDB build info.
func getBuildInfoCommandMsg() []byte {
metaData, err := bson.Marshal(bson.M{"buildInfo": 1})
// getBuildInfoQuery returns a mongodb message containing a command to retrieve MongoDB build info.
func getBuildInfoQuery() []byte {
query, err := bson.Marshal(bson.M{"buildinfo": 1})
if err != nil {
// programmer error
log.Fatalf("Invalid BSON: %v", err)
}
commandArgs, err := bson.Marshal(bson.M{})
if err != nil {
// programmer error
log.Fatalf("Invalid BSON: %v", err)
}
// "test" collection gleaned from tshark
command_msg := getCommandMsg("test", "buildInfo", metaData, commandArgs)
return command_msg
query_msg := getOpQuery("admin.$cmd", query)
return query_msg
}
// getOpQuery returns a mongodb OP_QUERY message containing the specified BSON-encoded query.
@ -191,7 +160,7 @@ func (scanner *Scanner) Init(flags zgrab2.ScanFlags) error {
f, _ := flags.(*Flags)
scanner.config = f
scanner.isMasterMsg = getIsMasterMsg()
scanner.buildInfoCommandMsg = getBuildInfoCommandMsg()
scanner.buildInfoCommandMsg = getBuildInfoQuery()
scanner.buildInfoOpMsg = getBuildInfoOpMsg()
return nil
}
@ -313,14 +282,12 @@ func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, inter
var resplen_offset int
var resp_offset int
// Gleaned from wireshark - if "MaxWireVersion" is less than 7, then
// "build info" command should be sent in an OP_COMMAND with the query sent
// and response retrieved at "metadata" offset. At 7 and above, should
// be sent as an OP_MSG in the "section" field, and response is at "body" offset
if result.IsMaster.MaxWireVersion < 7 {
// See: https://github.com/mongodb/specifications/blob/master/source/message/OP_MSG.rst
// "OP_MSG is only available in MongoDB 3.6 (maxWireVersion >= 6) and later."
if result.IsMaster.MaxWireVersion < 6 {
query = scanner.buildInfoCommandMsg
resplen_offset = 4
resp_offset = 0
resp_offset = 20
} else {
query = scanner.buildInfoOpMsg
resplen_offset = 5