shadow1ng/fscan · error
ANO: %w
Error message
ANO: %w
What it means
oracleRawAuth wraps any failure of s.advancedNegotiation() with the "ANO: %w" prefix. Advanced Negotiation Options (ANO) is an optional phase of the Oracle TNS/Two-Task handshake (gated by bits in acfl0/acfl1); failure means the client and server could not agree on ANO services such as encryption, data integrity, or compression.
Source
Thrown at plugins/services/oracle_raw.go:120
if err != nil {
return err
}
defer conn.Close()
s := &oracleSession{
conn: conn,
version: 317,
sessionDataUnit: 0x200000,
transportDataUnit: 0x200000,
clrChunkSize: 0x40,
timeout: timeout,
}
if err := s.connect(ctx, host, port, serviceName); err != nil {
return err
}
if s.acfl0&1 != 0 && s.acfl0&4 == 0 && s.acfl1&8 == 0 {
if err := s.advancedNegotiation(); err != nil {
return fmt.Errorf("ANO: %w", err)
}
}
nego, err := s.protocolNegotiation()
if err != nil {
return err
}
if err := s.dataTypeNegotiation(nego); err != nil {
return err
}
return s.authenticate(nego, host, port, serviceName, username, password)
}
func (s *oracleSession) connect(ctx context.Context, host string, port int, serviceName string) error {
connectData := oracleConnectData(host, port, serviceName)
packetLen := 70 + len(connectData)
if len(connectData) > 230 {
packetLen = 70
}View on GitHub (pinned to 95cc12e753)
Solutions
- Read the wrapped inner error for the specific ANO failure (e.g. ora-N code from errorIndex 439)
- Disable required encryption/checksum on the server (SQLNET.ENCRYPTION_SERVER=REJECTED) or implement the needed ANO service
- Align client with the server's Oracle version's ANO behavior
- Retry against a listener without ANO enforcement to isolate the cause
Example fix
// server-side sqlnet.ora before SQLNET.ENCRYPTION_SERVER = REQUIRED // after SQLNET.ENCRYPTION_SERVER = REJECTED # allow clients without ANO encryption support
Defensive patterns
Strategy: try-catch
Validate before calling
// detect ANO requirement before full auth:
// after connect, inspect s.acfl0/acfl1 flags
if s.acfl0&1 != 0 && s.acfl0&4 == 0 && s.acfl1&8 == 0 {
log.Println("server requires ANO; lightweight client must support negotiated services")
} Type guard
func isANOError(err error) bool { return err != nil && strings.HasPrefix(err.Error(), "ANO: ") } Try / catch
err := oracleRawAuth(ctx, host, port, svc)
if isANOError(err) {
// unwrap inner cause, adjust server SQLNET encryption/checksum policy or retry without ANO
return fmt.Errorf("ANO negotiation failed: %w", errors.Unwrap(err))
} Prevention
- Check SQLNET.ENCRYPTION_SERVER / CRYPTO_CHECKSUM_SERVER settings on the target before scanning
- Keep the client's ANO service list aligned with the server's Oracle version
- Treat 'ANO: '-prefixed errors as configuration mismatches, not credential failures
When it happens
Trigger: oracleRawAuth connects, sees acfl0&1 set (ANO requested) with acfl0&4==0 and acfl1&8==0, calls advancedNegotiation, and the server's ANO response contains an error code or malformed service data.
Common situations: Server requires Oracle Native Encryption/Checksum that the lightweight client cannot negotiate; version mismatch between client's ANO implementation and server; MITM or middlebox corrupting the ANO exchange.
Related errors
- short oracle accept packet
- oracle advanced negotiation error ora-%d
- oracle advanced negotiation type mismatch: %d
- oracle data type negotiation expected message 2, got %d
- oracle authentication failed
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/9f2e6d727431279c.
Report an issue: GitHub.