shadow1ng/fscan · error

oracle authentication protocol internal error

Error message

oracle authentication protocol internal error

What it means

When the server uses PBKDF2-based (O5LOGON variant) authentication, it supplies AUTH_PBKDF2_CSK_SALT, which must be exactly 32 bytes (base64/encoding aside, the decoded value length is validated). Any other length means the server's authentication response is malformed for this protocol and the client refuses to derive keys from it.

Source

Thrown at plugins/services/oracle_raw.go:1308

			for i := 0; i < dictLen; i++ {
				key, val, num, err := s.getKeyVal()
				if err != nil {
					return nil, err
				}
				switch string(key) {
				case "AUTH_SESSKEY":
					if auth.eServerSessKey == "" {
						auth.eServerSessKey = string(val)
					}
				case "AUTH_VFR_DATA":
					if auth.salt == "" {
						auth.salt = string(val)
						auth.verifierType = num
					}
				case "AUTH_PBKDF2_CSK_SALT":
					auth.pbkdf2ChkSalt = string(val)
					if len(auth.pbkdf2ChkSalt) != 32 {
						return nil, errors.New("oracle authentication protocol internal error")
					}
				case "AUTH_PBKDF2_VGEN_COUNT":
					auth.pbkdf2VgenCount, _ = strconv.Atoi(string(val))
					if auth.pbkdf2VgenCount < 4096 || auth.pbkdf2VgenCount > 100000000 {
						auth.pbkdf2VgenCount = 4096
					}
				case "AUTH_PBKDF2_SDER_COUNT":
					auth.pbkdf2SderCount, _ = strconv.Atoi(string(val))
					if auth.pbkdf2SderCount < 3 || auth.pbkdf2SderCount > 100000000 {
						auth.pbkdf2SderCount = 3
					}
				}
			}
		default:
			err := s.readMsg(msg)
			if err != nil {
				return nil, err
			}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Check server version/patch level against versions the plugin supports; upgrade the plugin if your server is newer
  2. If using Advanced Authentication / CMU or third-party auth adapters, test with standard password-based auth to isolate the mismatch
  3. Log the actual salt length and value to confirm decoding is correct, then report an upstream issue if the server legitimately differs
  4. Verify AUTH_PBKDF2_VGEN_COUNT and related params in the same response for overall consistency

Example fix

// before
auth.pbkdf2ChkSalt = string(val)
if len(auth.pbkdf2ChkSalt) != 32 {
	return nil, errors.New("oracle authentication protocol internal error")
}
// after
auth.pbkdf2ChkSalt = string(val)
if len(auth.pbkdf2ChkSalt) != 32 {
	return nil, fmt.Errorf("oracle authentication protocol internal error: salt length %d, want 32", len(auth.pbkdf2ChkSalt))
}
Defensive patterns

Strategy: type-guard

Validate before calling

// inspect auth params before finish(): log salt length during diagnosis
for k, v := range authParams {
	if k == "AUTH_PBKDF2_CSK_SALT" {
		log.Printf("pbkdf2 salt len=%d", len(v))
	}
}

Type guard

func validPbkdf2Salt(s string) bool { return len(s) == 32 }

Try / catch

auth, err := parseAuthResponse(resp)
if err != nil && strings.Contains(err.Error(), "authentication protocol internal error") {
	return fmt.Errorf("PBKDF2 salt length unexpected; check server version/auth adapter compatibility: %w", err)
}

Prevention

When it happens

Trigger: Parsing the auth response during oracleRawAuth: the AUTH_PBKDF2_CSK_SALT key/value pair decodes to a string/value whose length is not 32.

Common situations: Oracle server version emitting a different PBKDF2 salt length than the plugin expects; authentication plugins/extensions (e.g. CMU, third-party auth adapters) altering the salt; encoding/padding mishandling in the value.

Understand the failure class

Related errors


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