shadow1ng/fscan · error
invalid SCRAM iteration count
Error message
invalid SCRAM iteration count
What it means
The i= attribute of the SCRAM server-first message is the PBKDF2 iteration count. If it is not a positive integer (strconv.Atoi fails or it is <= 0), the plugin rejects it as an invalid iteration count.
Source
Thrown at plugins/services/mongodb.go:519
func buildMongoSCRAMClientFinal(username, password, clientFirstBare, serverFirst string) (string, error) {
attrs := parseSCRAMAttributes(serverFirst)
serverNonce := attrs["r"]
saltB64 := attrs["s"]
iterText := attrs["i"]
if serverNonce == "" || saltB64 == "" || iterText == "" {
return "", fmt.Errorf("invalid SCRAM server-first payload")
}
clientNonce := scramAttr(clientFirstBare, "r")
if clientNonce == "" || !strings.HasPrefix(serverNonce, clientNonce) {
return "", fmt.Errorf("invalid SCRAM nonce")
}
salt, err := base64.StdEncoding.DecodeString(saltB64)
if err != nil {
return "", fmt.Errorf("invalid SCRAM salt: %w", err)
}
iterations, err := strconv.Atoi(iterText)
if err != nil || iterations <= 0 {
return "", fmt.Errorf("invalid SCRAM iteration count")
}
clientFinalWithoutProof := "c=biws,r=" + serverNonce
authMessage := clientFirstBare + "," + serverFirst + "," + clientFinalWithoutProof
digest := md5.Sum([]byte(username + ":mongo:" + password))
saltedPassword := pbkdf2.Key([]byte(fmt.Sprintf("%x", digest)), salt, iterations, sha1.Size, sha1.New)
clientKey := mongoHMAC(saltedPassword, []byte("Client Key"))
storedKey := sha1.Sum(clientKey)
clientSignature := mongoHMAC(storedKey[:], []byte(authMessage))
proof := make([]byte, len(clientKey))
for i := range clientKey {
proof[i] = clientKey[i] ^ clientSignature[i]
}
return clientFinalWithoutProof + ",p=" + base64.StdEncoding.EncodeToString(proof), nil
}
func parseSCRAMAttributes(payload string) map[string]string {
attrs := make(map[string]string)View on GitHub (pinned to 95cc12e753)
Solutions
- Inspect the i= value in the server-first payload for non-numeric content
- Verify the server is a standard mongod emitting a positive integer iteration count
- Consider clamping/validating the iteration count range before use to reject absurd values
- Retry against a known-good MongoDB instance to isolate whether the target is misbehaving
Example fix
// before
iterations, err := strconv.Atoi(iterText)
if err != nil || iterations <= 0 {
return "", fmt.Errorf("invalid SCRAM iteration count")
}
// after
iterations, err := strconv.Atoi(iterText)
if err != nil || iterations <= 0 || iterations > 1<<24 {
return "", fmt.Errorf("invalid SCRAM iteration count: %q", iterText)
} Defensive patterns
Strategy: validation
Validate before calling
it, err := strconv.Atoi(scramAttr(serverFirst, "i"))
if err != nil || it <= 0 || it > 1<<24 {
return fmt.Errorf("iteration count out of accepted range")
} Type guard
func isValidIterationCount(s string) bool {
n, err := strconv.Atoi(s)
return err == nil && n > 0 && n <= 1<<24
} Try / catch
if _, err := buildMongoSCRAMClientFinal(u, p, cfb, serverFirst); err != nil && strings.Contains(err.Error(), "iteration count") {
log.Warnf("target reported unusable iteration count: %v", err)
return
} Prevention
- Bound-check i= against sane SCRAM ranges (1k–10M)
- Fingerprint the server before trusting its SCRAM parameters
- Log the raw i= value on failure to identify hostile targets
When it happens
Trigger: iterText is empty at this point only if attributes were partially present, or contains non-numeric text (e.g. '10000x', negative, or 0) — usually from a malformed or hostile server-first payload.
Common situations: Honeypot/fake MongoDB returning junk i= values; corrupted payload; extremely old or custom servers with non-numeric iteration fields.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- invalid SCRAM server-first payload
- invalid SCRAM salt: %w
- authentication failed: %s
- invalid saslStart response
- invalid SCRAM nonce
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/e181482d57721549.
Report an issue: GitHub.