shadow1ng/fscan · error
bad BER tags
Error message
bad BER tags
What it means
ReadDomainParameters expects the server's MCS Connect Response to contain DomainParameters encoded as a BER SEQUENCE (0x30 universal tag, constructed). If ber.ReadUniversalTag(TAG_SEQUENCE, constructed=true) fails, the byte stream is not the expected BER structure. This means the MCS layer payload is malformed or out of sync.
Source
Thrown at libs/grdp/protocol/t125/mcs.go:109
numPriorities, minThoughput, maxHeight, maxMCSPDUsize, protocolVersion}
}
func (d *DomainParameters) BER() []byte {
buff := &bytes.Buffer{}
ber.WriteInteger(d.MaxChannelIds, buff)
ber.WriteInteger(d.MaxUserIds, buff)
ber.WriteInteger(d.MaxTokenIds, buff)
ber.WriteInteger(1, buff)
ber.WriteInteger(0, buff)
ber.WriteInteger(1, buff)
ber.WriteInteger(d.MaxMCSPDUsize, buff)
ber.WriteInteger(2, buff)
return buff.Bytes()
}
func ReadDomainParameters(r io.Reader) (*DomainParameters, error) {
if !ber.ReadUniversalTag(ber.TAG_SEQUENCE, true, r) {
return nil, errors.New("bad BER tags")
}
d := &DomainParameters{}
ber.ReadLength(r)
d.MaxChannelIds, _ = ber.ReadInteger(r)
d.MaxUserIds, _ = ber.ReadInteger(r)
d.MaxTokenIds, _ = ber.ReadInteger(r)
ber.ReadInteger(r)
ber.ReadInteger(r)
ber.ReadInteger(r)
d.MaxMCSPDUsize, _ = ber.ReadInteger(r)
ber.ReadInteger(r)
return d, nil
}
/**
* @see http://www.itu.int/rec/T-REC-T.125-199802-I/en page 25
* @param userData {Buffer}View on GitHub (pinned to 95cc12e753)
Solutions
- Confirm the target speaks RDP on that port and that security negotiation (e.g. NLA/CredSSP) does not divert the handshake before MCS.
- Hex-dump the received buffer (mcs.go already logs it) and verify the byte at the failure offset is 0x30.
- Check earlier parsing steps (ReadApplicationTag, ReadEnumerated, ReadInteger) consumed the exact byte counts; a wrong length earlier desynchronizes the reader.
- Return the underlying byte/tag value in the error message to ease diagnosis.
Example fix
// before
if !ber.ReadUniversalTag(ber.TAG_SEQUENCE, true, r) {
return nil, errors.New("bad BER tags")
}
// after
b, _ := core.PeekByte(r)
if !ber.ReadUniversalTag(ber.TAG_SEQUENCE, true, r) {
return nil, fmt.Errorf("bad BER tags: expected SEQUENCE(0x30), got 0x%02x", b)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Peek the first byte of the response before parsing MCS layers:
func looksLikeBERSequence(b []byte) bool { return len(b) > 0 && b[0] == 0x30 } Try / catch
mcs.On("error", func(err error) {
if strings.Contains(err.Error(), "bad BER tags") {
// peer is not speaking RDP/T.125 — abort or retry against correct host/port
}
}) Prevention
- Verify the target port actually serves RDP before running the client.
- Handle NLA/CredSSP negotiation before entering the MCS layer.
- Hex-log responses during development to catch desync early.
When it happens
Trigger: Called from ReadConnectResponse when parsing the server's MCS Connect Response: the first universal tag after result and calledConnectId is not a constructed SEQUENCE, i.e. the server response bytes deviate from T.125 BER encoding.
Common situations: The peer is not an RDP server (wrong port, HTTP banner server); a middlebox/proxy rewrites the response; a previous packet framed incorrectly so the reader is misaligned; servers that negotiate NLA and never send a plain MCS Connect Response at this point.
Related errors
- invalid expected BER tag
- invalid ber tag
- Bad integer tag
- NODE_RDP_PROTOCOL_T125_MCS_BAD_HEADER
- Invalid expected MCS opcode receive data
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/d372513663067984.
Report an issue: GitHub.