shadow1ng/fscan · error
ReadApplicationTag invalid data
Error message
ReadApplicationTag invalid data
What it means
ReadApplicationTag parses a BER application-class tag. When the requested tag number exceeds 30 it needs the multi-byte long tag form, so the first byte must equal (CLASS_APPL|PC_CONSTRUCT)|TAG_MASK (0x6F). Any other byte means the data is not a valid high-numbered application tag.
Source
Thrown at libs/grdp/protocol/t125/ber/ber.go:160
WriteLength(len(str), w)
core.WriteBytes([]byte(str), w)
}
func WriteBoolean(b bool, w io.Writer) {
bb := uint8(0)
if b {
bb = uint8(0xff)
}
WriteUniversalTag(TAG_BOOLEAN, false, w)
WriteLength(1, w)
core.WriteUInt8(bb, w)
}
func ReadApplicationTag(tag uint8, r io.Reader) (int, error) {
bb, _ := core.ReadUInt8(r)
if tag > 30 {
if bb != (CLASS_APPL|PC_CONSTRUCT)|TAG_MASK {
return 0, errors.New("ReadApplicationTag invalid data")
}
bb, _ := core.ReadUInt8(r)
if bb != tag {
return 0, errors.New("ReadApplicationTag bad tag")
}
} else {
if bb != (CLASS_APPL|PC_CONSTRUCT)|(TAG_MASK&tag) {
return 0, errors.New("ReadApplicationTag invalid data2")
}
}
return ReadLength(r)
}
func WriteApplicationTag(tag uint8, size int, w io.Writer) {
if tag > 30 {
core.WriteUInt8((CLASS_APPL|PC_CONSTRUCT)|TAG_MASK, w)
core.WriteUInt8(tag, w)
WriteLength(size, w)View on GitHub (pinned to 95cc12e753)
Solutions
- Capture and hex-dump the CONNECT_RESPONSE; check the first byte of the application tag field against 0x6F
- Confirm the target is a genuine RDP server and the port is not answered by another service
- Trace upstream parsing to find where the byte alignment went wrong and fix that parser
- Check whether the server sent a negotiation failure PDU instead of the expected response
Example fix
// before
if bb != (CLASS_APPL|PC_CONSTRUCT)|TAG_MASK {
return 0, errors.New("ReadApplicationTag invalid data")
}
// after
if bb != (CLASS_APPL|PC_CONSTRUCT)|TAG_MASK {
return 0, fmt.Errorf("ReadApplicationTag invalid data: expected 0x6F, got 0x%02X", bb)
} Defensive patterns
Strategy: validation
Validate before calling
// verify the application tag byte before calling ReadApplicationTag
expected := byte((ber.CLASS_APPL | ber.PC_CONSTRUCT) | ber.TAG_MASK)
if buf[pos] != expected {
return fmt.Errorf("no long-form application tag at offset %d: got 0x%02X, want 0x%02X", pos, buf[pos], expected)
} Try / catch
n, err := ber.ReadApplicationTag(101, r)
if err != nil {
if strings.Contains(err.Error(), "invalid data") {
return fmt.Errorf("response is not the expected T.125 CONNECT_RESPONSE: %w", err)
}
return err
} Prevention
- Check the server's negotiation result byte before parsing CONNECT_RESPONSE
- Hex-dump responses on failure to spot misalignment immediately
- Confirm port 3389 is answered by an RDP server, not a proxy or other service
When it happens
Trigger: ReadConnectResponse calling ReadApplicationTag with tag > 30 (e.g. tag 101 for the T.125 CONNECT_RESPONSE) when the first stream byte is not 0x6F — the field is misaligned or absent.
Common situations: Non-RDP services answering on 3389; desync from mismatched X.224 negotiation; TLS interception or proxy altering the response bytes; servers answering with an error PDU instead of CONNECT_RESPONSE where the application tag is expected.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- ReadApplicationTag bad tag
- ReadApplicationTag invalid data2
- invalid ber tag
- enumerate size is wrong, get %v, expect 1
- BER length may be 1 or 2
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/e07545922c6d1541.
Report an issue: GitHub.