shadow1ng/fscan · error

short oracle ncharset negotiation

Error message

short oracle ncharset negotiation

What it means

Immediately after parsing the server charset, protocolNegotiation computes an offset (6 + numArray[5] + numArray[6]) to locate the server NCHARSET field, which needs 5 readable bytes at that offset. If numArray is shorter than offset+5, the NCHARSET cannot be extracted and the library aborts the handshake.

Source

Thrown at plugins/services/oracle_raw.go:1014

	if charsetElem > 0 {
		if _, err = s.getBytes(charsetElem * 5); err != nil {
			return nil, err
		}
	}
	len1, err := s.getInt(2, false, true)
	if err != nil {
		return nil, err
	}
	numArray, err := s.getBytes(len1)
	if err != nil {
		return nil, err
	}
	if len(numArray) < 11 {
		return nil, errors.New("short oracle charset negotiation")
	}
	offset := int(6 + numArray[5] + numArray[6])
	if len(numArray) < offset+5 {
		return nil, errors.New("short oracle ncharset negotiation")
	}
	serverNCharset := int(binary.BigEndian.Uint16(numArray[offset+3 : offset+5]))
	len2, err := s.getByte()
	if err != nil {
		return nil, err
	}
	compileCaps, err := s.getBytes(int(len2))
	if err != nil {
		return nil, err
	}
	len3, err := s.getByte()
	if err != nil {
		return nil, err
	}
	runtimeCaps, err := s.getBytes(int(len3))
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Check server Oracle version/patch level for known accept-packet layout differences and update the plugin accordingly
  2. Capture the accept packet (tcpdump) and compare byte layout with a known-good client session
  3. Rule out transport truncation (retry, test direct connection without proxy)
  4. If reproducible against a specific server version, file an upstream issue with the packet dump

Example fix

// before
offset := int(6 + numArray[5] + numArray[6])
if len(numArray) < offset+5 {
	return nil, errors.New("short oracle ncharset negotiation")
}
// after
offset := int(6 + numArray[5] + numArray[6])
if len(numArray) < offset+5 {
	return nil, fmt.Errorf("short oracle ncharset negotiation: need %d bytes, got %d", offset+5, len(numArray))
}
Defensive patterns

Strategy: try-catch

Try / catch

if err != nil && strings.Contains(err.Error(), "short oracle ncharset negotiation") {
	return fmt.Errorf("server accept-data shorter than its own offsets; check server version/patch and proxy handling: %w", err)
}

Prevention

When it happens

Trigger: protocolNegotiation() during oracleRawAuth: len(numArray) < (6 + numArray[5] + numArray[6] + 5), i.e. the variable-length sections claimed by the accept-data array extend past its actual size.

Common situations: Server accept packet with unusually large substructure fields (bytes 5/6) relative to actual data — often a protocol-version mismatch; truncated transport frame; desynchronized parsing from a previous step.

Related errors


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