shadow1ng/fscan · error

wrong size

Error message

wrong size

What it means

ReadInteger supports only INTEGER content lengths of 1, 2, 3, or 4 bytes (mapping to uint8, uint16, 3-byte, uint32). Any other decoded length falls to the default branch and this error is returned. It means the integer field is encoded with an unexpected size.

Source

Thrown at libs/grdp/protocol/t125/ber/ber.go:122

		return 0, errors.New("Bad integer tag")
	}
	size, _ := ReadLength(r)
	switch size {
	case 1:
		num, _ := core.ReadUInt8(r)
		return int(num), nil
	case 2:
		num, _ := core.ReadUint16BE(r)
		return int(num), nil
	case 3:
		integer1, _ := core.ReadUInt8(r)
		integer2, _ := core.ReadUint16BE(r)
		return int(integer2) + (int(integer1) << 16), nil
	case 4:
		num, _ := core.ReadUInt32BE(r)
		return int(num), nil
	default:
		return 0, errors.New("wrong size")
	}
}

func WriteInteger(n int, w io.Writer) {
	WriteUniversalTag(TAG_INTEGER, false, w)
	if n <= 0xff {
		WriteLength(1, w)
		core.WriteUInt8(uint8(n), w)
	} else if n <= 0xffff {
		WriteLength(2, w)
		core.WriteUInt16BE(uint16(n), w)
	} else {
		WriteLength(4, w)
		core.WriteUInt32BE(uint32(n), w)
	}
}

func WriteOctetstring(str string, w io.Writer) {

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Inspect the captured bytes to see the actual length; confirm whether it is a genuine encoder difference or desync
  2. Fix the upstream desync first — a bogus length here usually traces to earlier misparse
  3. Extend the switch to handle the server's integer size (e.g. 8-byte via ReadUint64BE) if it is intentional
  4. Retry if a transient network corruption is suspected

Example fix

// before
default:
    return 0, errors.New("wrong size")

// after
default:
    return 0, fmt.Errorf("wrong size: BER INTEGER length %d not in 1..4", size)
Defensive patterns

Strategy: try-catch

Validate before calling

// read the length yourself and reject impossible integer sizes early
length, _ := ber.ReadLength(r)
if length == 0 || length > 4 {
    return fmt.Errorf("unsupported INTEGER length %d", length)
}

Try / catch

n, err := ber.ReadInteger(r)
if err != nil {
    if strings.Contains(err.Error(), "wrong size") {
        // likely desync; log surrounding bytes and resync or abort
    }
    return err
}

Prevention

When it happens

Trigger: ReadDomainParameters or ReadConnectResponse reading an INTEGER whose BER length is 0 or >4 bytes — e.g. a 5+ byte integer or a zero-length integer.

Common situations: Desynced streams producing bogus length values; nonstandard encoders emitting 8-byte integers for large values; corrupted responses in transit.

Related errors


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