Documentation
¶
Overview ¶
Package quic implements QUIC protocol analysis for both gQUIC and IETF QUIC. The gQUIC parsing is based on patterns from https://github.com/0x4D31/quick
Index ¶
Constants ¶
This section is empty.
Variables ¶
var Decoder = &decoder.StreamDecoder{ Type: types.Type_NC_QUICClientHello, Name: serviceQUIC, Description: "QUIC ClientHello extraction for JA4 fingerprinting (supports IETF QUIC and gQUIC)", PostInit: func(d *decoder.StreamDecoder) error { var err error quicLog, _, err = logging.InitZapLogger( decoderconfig.Instance.Out, "quic", decoderconfig.Instance.Debug, ) return err }, CanDecode: func(client, server []byte) bool { if len(client) >= 5 { if IsIETFQUICPacket(client) { quicLog.Debug("QUIC traffic detected - IETF QUIC", zap.Int("clientLen", len(client)), zap.Int("serverLen", len(server)), ) return true } if IsGQUICPacket(client) { quicLog.Debug("QUIC traffic detected - gQUIC", zap.Int("clientLen", len(client)), zap.Int("serverLen", len(server)), ) return true } } quicLog.Debug("QUIC CanDecode check failed", zap.Int("clientLen", len(client)), zap.Int("serverLen", len(server)), ) return false }, DeInit: func(sd *decoder.StreamDecoder) error { return quicLog.Sync() }, Factory: &quicReader{}, Typ: core.UDP, }
Decoder for QUIC protocol analysis and writing audit records to disk.
Functions ¶
func CanDecodeQUIC ¶
CanDecodeQUIC provides a public check for QUIC detection. This can be used by other parts of the system.
func GetQUICVersionString ¶
GetQUICVersionString returns a human-readable version string for QUIC versions.
func IsGQUICPacket ¶
IsGQUICPacket checks if the payload looks like a gQUIC packet. gQUIC packets can have two forms: 1. Long form with version (handshake): contains "Qxxx" version string 2. Short form without version (after handshake): identified by public flags pattern
func IsIETFQUICPacket ¶
IsIETFQUICPacket checks if the payload looks like an IETF QUIC packet. Note: RFC 9287 allows "greasing" the fixed bit (setting it to 0 randomly), so short header detection may have false negatives for greased packets. For comprehensive detection, connection tracking context would be needed.
Types ¶
type GQUICClientHello ¶
type GQUICClientHello struct {
Version string // QUIC version (e.g., "Q043", "Q046")
CID []byte // Connection ID (8 bytes for gQUIC)
SNI string // Server Name Indication
UAID string // User Agent ID (e.g., "Chrome/74.0.3729.131 Intel Mac OS X 10_14_4")
Tags []string // Tags in order for fingerprinting
TagValues map[string]string // Tag values
PacketNum int // Packet number
FrameType byte // Frame type
StreamID int // Stream ID
DataLength int // Data length
RawMAC []byte // Message Authentication Hash
}
GQUICClientHello represents parsed gQUIC CHLO data.
func ParseGQUICClientHello ¶
func ParseGQUICClientHello(payload []byte) (*GQUICClientHello, error)
ParseGQUICClientHello parses a gQUIC packet and extracts CHLO information. Based on patterns from https://github.com/0x4D31/quick
gQUIC versions (Q043, Q044, Q046, Q050) use a different packet format than IETF QUIC. The format consists of: - Public Flags (1 byte) - Connection ID (8 bytes, optional based on flags) - Version (4 bytes, optional based on flags) - Packet Number (1-6 bytes based on flags) - Payload containing CHLO message
type IETFQUICClientHello ¶
type IETFQUICClientHello struct {
Version uint32 // QUIC version
DCID []byte // Destination Connection ID
SCID []byte // Source Connection ID
Token []byte // Token (for address validation)
PacketNumber int64
// Embedded TLS ClientHello data
TLSVersion uint16 // TLS version from ClientHello
Random []byte // TLS random (32 bytes)
SessionID []byte // Session ID
CipherSuites []uint16 // Cipher suites offered
CompressionMethods []byte // Compression methods
Extensions []uint16 // Extension types
SNI string // Server Name Indication
ALPNs []string // ALPN protocols
SupportedGroups []uint16 // Supported elliptic curves
SignatureAlgs []uint16 // Signature algorithms
SupportedVersions []uint16 // TLS supported versions extension
// QUIC Transport Parameters (RFC 9000 Section 18.2)
// Extension type: 0x39 for QUIC v1 (RFC 9001), 0x57 for QUIC v2 (RFC 9369)
MaxIdleTimeout uint64 // 0x01
MaxUDPPayloadSize uint64 // 0x03
InitialMaxData uint64 // 0x04
InitialMaxStreamDataBidiLocal uint64 // 0x05
InitialMaxStreamDataBidiRemote uint64 // 0x06
InitialMaxStreamDataUni uint64 // 0x07
InitialMaxStreamsBidi uint64 // 0x08
InitialMaxStreamsUni uint64 // 0x09
AckDelayExponent uint64 // 0x0a (default: 3)
MaxAckDelay uint64 // 0x0b (default: 25ms)
DisableActiveMigration bool // 0x0c
ActiveConnectionIDLimit uint64 // 0x0e (default: 2)
InitialSourceConnectionID []byte // 0x0f
}
IETFQUICClientHello represents parsed IETF QUIC Initial packet data.
func ParseIETFQUICInitial ¶
func ParseIETFQUICInitial(payload []byte) (*IETFQUICClientHello, error)
ParseIETFQUICInitial parses an IETF QUIC Initial packet and extracts the ClientHello. This requires decrypting the packet header and payload using the Initial secret.