shadow1ng/fscan · error

authentication failed: %s

Error message

authentication failed: %s

What it means

After sending the SASL PLAIN token, the plugin expected AUTH_SUCCESS or READY but got an ERROR frame, meaning the server rejected the credentials. The server's message body is wrapped as 'authentication failed: %s'.

Source

Thrown at plugins/services/cassandra.go:142

	if opcode == cqlOpAuthChl {
		if cred.Username == "" && cred.Password == "" {
			return &AuthResult{Success: false, ErrorType: ErrorTypeAuth, Error: fmt.Errorf("authentication required")}
		}
		// SASL PLAIN: \x00username\x00password
		saslToken := []byte("\x00" + cred.Username + "\x00" + cred.Password)
		if err := cqlSend(conn, cqlOpAuthRsp, saslToken); err != nil {
			state.IncrementTCPFailedPacketCount()
			return &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}
		}
		opcode, body, err = cqlRecv(conn)
		if err != nil {
			state.IncrementTCPFailedPacketCount()
			return &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}
		}
		// AUTH_SUCCESS → 认证成功
		// ERROR → 认证失败
		if opcode == cqlOpError {
			return &AuthResult{Success: false, ErrorType: ErrorTypeAuth, Error: fmt.Errorf("authentication failed: %s", string(body))}
		}
		if opcode != cqlOpAuthOk && opcode != cqlOpReady {
			return &AuthResult{Success: false, ErrorType: ErrorTypeAuth, Error: fmt.Errorf("unexpected opcode: %d", opcode)}
		}
	}

	// Step 4: 发送测试查询
	queryBody := cqlLongString("SELECT cluster_name FROM system.local")
	// 添加 consistency level (ONE=1)
	queryBody = append(queryBody, 0x00, 0x01) // flags=0, consistency=ONE
	if err := cqlSend(conn, cqlOpQuery, queryBody); err != nil {
		state.IncrementTCPFailedPacketCount()
		return &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}
	}
	opcode, body, err = cqlRecv(conn)
	if err != nil {
		state.IncrementTCPFailedPacketCount()
		return &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Check the embedded server message to confirm it is a bad-credentials error, then use a valid username/password pair.
  2. Verify the credential source/wordlist targets the correct cluster; default creds may have been rotated.
  3. If the credential is expected to be valid, confirm the user exists and is not locked (system_auth.roles).
Defensive patterns

Strategy: retry

Try / catch

res := doCassandraAuth(conn, cred, state)
if !res.Success && res.ErrorType == ErrorTypeAuth && strings.HasPrefix(res.Error.Error(), "authentication failed") {
    log.Printf("bad credentials for %s: %v", target, res.Error)
    // do not retry with the same credential
}

Prevention

When it happens

Trigger: doCassandraAuth sends cqlOpAuthRsp with the SASL token, reads the reply, and the opcode is cqlOpError — Cassandra's standard response to bad username/password.

Common situations: Wrong password for a real account; testing against a cluster where the default cassandra/cassandra credentials were changed; account locked or user dropped; brute-force attempt legitimately denied by the server.

Understand the failure class

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/4674a1cf9b0770a4. Report an issue: GitHub.