mongodb

package
v0.783.0 Latest Latest
Warning

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

Go to latest
Published: Jun 29, 2026 License: AGPL-3.0 Imports: 4 Imported by: 0

Documentation

Overview

Package mongodb decodes MongoDB wire protocol messages per the MongoDB documentation ("MongoDB Wire Protocol"). Runs on TCP/27017 (default mongod), TCP/27018 (mongos sharded router), TCP/27019 (config servers). Compatible with FerretDB (Postgres-backed MongoDB-compatible proxy) and DocumentDB (AWS MongoDB-compatible) which use the same wire format.

Operationally, MongoDB is a **high-value NoSQL pentest target** with an exposure profile similar to Redis — many historical deployments (Mongo 2.x / 3.x) defaulted to "no auth, bind to 0.0.0.0" and Shodan still finds tens of thousands of unauthenticated MongoDB instances on TCP/27017. Modern MongoDB (4.x+) defaults to localhost-only binding + SCRAM-SHA-256 auth, but the wire format remains the same.

The wire format leaks:

  • **MongoDB version + auth-mechanism enumeration via `isMaster` / `hello` command** — every client sends an `isMaster` (legacy) or `hello` (modern, MongoDB 5.0+) command immediately after TCP connect to discover server topology + supported SASL mechanisms. The server reply includes `maxWireVersion`, `topologyVersion`, `setName` (replica-set name disclosure), `primary`/`hosts` (replica-set topology disclosure), `me` (server's own hostname), and **`saslSupportedMechs`** — an array of mechanism names: `SCRAM-SHA-1` (legacy weak — offline- crackable via hashcat mode 31700), `SCRAM-SHA-256` (modern default), `PLAIN` (cleartext — typically used for LDAP-backed auth), `MONGODB-X509` (client cert auth), `GSSAPI` (Kerberos), `MONGODB-AWS` (AWS IAM auth), `MONGODB-OIDC` (OAuth2/OIDC auth). The decoder surfaces the command name; the response saslSupportedMechs array is surfaced as part of the BSON command argument walker.

  • **Database + collection namespace disclosure** — OP_QUERY (legacy) carries `fullCollectionName` as a null-terminated string in the form `<database>.<collection>` or `<database>.$cmd` for command requests. OP_MSG (modern) carries the database as a top-level `$db` field in the BSON command document. Both forms reveal the target database + collection in cleartext.

  • **Authentication exchange via `saslStart` / `saslContinue`** — SCRAM-SHA-1 / SCRAM-SHA-256 / PLAIN / MONGODB-X509 / GSSAPI authentication uses a multi-step command exchange:

  • `saslStart { mechanism: "SCRAM-SHA-256", payload: BinData(0, <client-first-message>) }`

  • Server responds with `conversationId` + `payload` (server-first-message with nonce + iteration count).

  • `saslContinue { conversationId: 1, payload: BinData(0, <client-final-message>) }`

  • Server responds with `done: true`/`false`.

    The decoder surfaces the command + mechanism name + `payload_bytes` LENGTH only (privacy-preserving — the SCRAM payload is a structured BinData blob containing the client nonce + salted password proof; offline-crackable with hashcat mode 24100 for SCRAM-SHA-1 / 24200 for SCRAM-SHA-256 once captured).

  • **Dangerous-command detection** — flags each of:

  • `createUser` / `updateUser` / `dropUser` — credential management (creating new accounts is a backdoor primitive).

  • `dropDatabase` / `dropCollection` — data destruction.

  • `listDatabases` / `listCollections` — enumeration (often pre-attack recon).

  • `find` / `aggregate` with `$where` / `$expr` operators — historical server-side JavaScript RCE primitive (removed in MongoDB 4.4 but legacy versions still deployed).

  • `runCommand { eval: ... }` — direct server-side JavaScript execution (REMOVED in 4.4 but legacy 3.x / 4.0 / 4.2 still deployed).

  • `shutdown` / `replSetStepDown` — operational destructive commands.

  • **Build info disclosure via `buildInfo`** — server reply includes `version` (e.g. `7.0.4`), `gitVersion`, `buildEnvironment`, `modules` (`enterprise`, `subscription`, etc.), `openssl` version, `storageEngines`. Canonical MongoDB version-fingerprint for CVE selection.

Wrap-vs-native judgement

Native. The MongoDB wire protocol is publicly documented;
the 16-byte header is a fixed struct, little-endian. OP_MSG
body is a flag-prefixed section list with kind-discriminated
body / document-sequence sections. OP_QUERY body has fixed
fields + a cstring fullCollectionName + BSON query. BSON
parsing is a length-prefixed element walker. Full BSON
value decoding (recursive doc/array walk, ObjectId / Binary
subtypes / Decimal128) is out of scope; the decoder extracts
the command name + key arguments (`$db`, `mechanism`,
`saslSupportedMechs`) as needed.

What this package covers

  • **16-byte header walker**: messageLength (4 LE — total including header) / requestID (4 LE) / responseTo (4 LE) / opCode (4 LE).

  • **12-entry opCode name table**: 1 OP_REPLY (legacy server reply) / 1000 OP_MSG_DEPRECATED (very old) / 2001 OP_UPDATE (legacy) / 2002 OP_INSERT (legacy) / 2004 OP_QUERY (legacy but still used for the initial isMaster / hello probe by every driver) / 2005 OP_GET_MORE (legacy) / 2006 OP_DELETE (legacy) / 2007 OP_KILL_CURSORS (legacy) / 2010 OP_COMMAND (server-internal) / 2011 OP_COMMANDREPLY (server-internal) / 2012 OP_COMPRESSED (Snappy/zlib/zstd wrapped) / 2013 OP_MSG (modern, MongoDB 3.6+ default).

  • **OP_MSG body walker**: flagBits (4 LE) + section[]. Section discriminator: 0 = Body (single BSON document), 1 = Document Sequence (cstring identifier + BSON docs until the end of the message). The decoder walks the first Body section's BSON document to extract the `command_name` (BSON convention: first element).

  • **OP_QUERY body walker**: flags (4 LE) / fullCollectionName (cstring — e.g. `admin.$cmd` or `mydb.users`) / numberToSkip (4 LE) / numberToReturn (4 LE) / query (BSON document). Surfaces `full_collection_name` cleartext.

  • **BSON document walker**: 4-byte LE length (includes self) + elements. Each element: 1-byte type tag + cstring name + type-dependent value. Terminated by 0x00. Surfaces top-level field names + key value types.

  • **18-entry BSON element-type name table** (per BSON spec): 0x01 double / 0x02 string / 0x03 embedded document / 0x04 array / 0x05 binary / 0x07 ObjectId / 0x08 boolean / 0x09 UTC datetime / 0x0A null / 0x0B regex / 0x0D JavaScript / 0x0E symbol / 0x0F JavaScript with scope / 0x10 int32 / 0x11 timestamp / 0x12 int64 / 0x13 decimal128 / 0xFF min key / 0x7F max key.

  • **Command classification** flagging:

  • `isMaster` / `hello` (version + auth-mechanism enumeration probe — always sent on connect).

  • `buildInfo` (version disclosure).

  • `saslStart` / `saslContinue` (auth exchange; surfaces `sasl_mechanism` + `payload_bytes` length only).

  • `createUser` / `updateUser` / `dropUser` (credential management — backdoor primitive).

  • `dropDatabase` / `dropCollection` (data destruction).

  • `listDatabases` / `listCollections` (enumeration).

  • `find` / `insert` / `update` / `delete` / `aggregate` (DB operations — surfaced for visibility).

  • `eval` / `$where` / `$expr` (server-side JavaScript — historical RCE primitive, removed in MongoDB 4.4 but legacy 3.x / 4.0 / 4.2 deployments still exposed).

  • `shutdown` / `replSetStepDown` (operational destructive).

  • **`$db` field extraction** from OP_MSG BSON body — the modern MongoDB convention places the target database name as a top-level `$db` string field in command requests. Surfaced as `database`.

What this package does NOT cover (deliberately out of scope)

  • **Full BSON value parsing** — recursive embedded document / array traversal beyond the top-level command name + `$db` + `mechanism` + `payload` length. Each BSON value type has its own length-prefixed binary format; a general BSON walker is a separate decoder concern.
  • **BSON Binary subtypes** — 0x00 generic / 0x01 function / 0x02 binary-old / 0x03 UUID-old / 0x04 UUID / 0x05 MD5 / 0x06 encrypted (CSFLE) / 0x07 compressed / 0x80+ user-defined. Surfaced as raw length only.
  • **OP_COMPRESSED decompression** — opCode 2012 wraps an inner message compressed with Snappy / zlib / zstd (compressorId selects); the decoder identifies the opCode but does NOT decompress. Operators should feed the decompressed inner bytes for analysis.
  • **TLS handshake** — MongoDB 3.0+ supports TLS (was SSL in 2.x); handle the TLS strip first.
  • **SDAM topology messages** — MongoDB drivers use periodic `hello` / `isMaster` probes for server discovery + topology monitoring; the decoder surfaces individual messages but does not track topology state.
  • **Change Streams oplog format** — `aggregate { pipeline: [{$changeStream: ...}] }` returns a cursor of oplog entries; the per-entry format is collection-defined.
  • **GridFS file storage format** — the `fs.files` / `fs.chunks` collection convention is a higher-level abstraction over ordinary collections.
  • **Per-driver client metadata fields** — drivers send a `client` field in isMaster/hello with driver name + version + platform + os info; surfaced as ordinary BSON content.
  • **CSFLE (Client-Side Field-Level Encryption)** — when enabled, sensitive fields are encrypted client-side before transmission; the wire format carries opaque BinData subtype 6 (encrypted) values.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Result

type Result struct {
	TotalBytes int `json:"total_bytes"`

	MessageLength int    `json:"message_length"`
	RequestID     uint32 `json:"request_id"`
	ResponseTo    uint32 `json:"response_to"`
	OpCode        int    `json:"op_code"`
	OpCodeName    string `json:"op_code_name"`

	// OP_MSG flag bits + section count
	MsgFlagBits  uint32 `json:"msg_flag_bits,omitempty"`
	MsgSections  int    `json:"msg_sections,omitempty"`
	HasChecksum  bool   `json:"has_checksum,omitempty"`
	MoreToCome   bool   `json:"more_to_come,omitempty"`
	ExhaustAllow bool   `json:"exhaust_allowed,omitempty"`

	// OP_QUERY
	FullCollectionName string `json:"full_collection_name,omitempty"`
	NumberToSkip       int32  `json:"number_to_skip,omitempty"`
	NumberToReturn     int32  `json:"number_to_return,omitempty"`

	// Extracted from BSON command body
	CommandName string `json:"command_name,omitempty"`
	Database    string `json:"database,omitempty"`

	// Command classification
	IsHelloProbe       bool   `json:"is_hello_probe"`
	IsSASLAuth         bool   `json:"is_sasl_auth"`
	SASLMechanism      string `json:"sasl_mechanism,omitempty"`
	SASLPayloadBytes   int    `json:"sasl_payload_bytes,omitempty"`
	IsDangerousCommand bool   `json:"is_dangerous_command"`
	DangerousFlag      string `json:"dangerous_command_flag,omitempty"`
}

Result is the structured decode of a MongoDB wire-protocol message.

func Decode

func Decode(hexStr string) (*Result, error)

Decode parses a MongoDB wire-protocol message from a hex string.

Jump to

Keyboard shortcuts

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