credentials

package
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 9, 2026 License: BSD-3-Clause, GPL-3.0 Imports: 28 Imported by: 0

README

Credential Harvesters

Implemented Harvesters

✅ Basic Auth
  • FTP - plaintext credentials (port 21)
  • Telnet - plaintext credentials (port 23)
  • SMTP - Auth Plain, Auth Login, CRAM-MD5 (ports 25, 465, 587)
  • IMAP - Login, Authenticate Plain, CRAM-MD5 (port 143)
  • POP3 - USER/PASS, Auth Plain, Auth Login (ports 110, 995)
✅ HTTP Authentication
  • HTTP Basic Auth - base64 decoded credentials
  • HTTP Digest (Enhanced) - Full parameter extraction for Hashcat mode 11400
    • Extracts: username, realm, nonce, uri, qop, nc, cnonce, response, method
    • Format: username:realm:nonce:uri:nc:cnonce:qop:response
  • HTTP NTLM - base64-encoded NTLMSSP in HTTP Authorization headers
    • Scans entire session for Challenge and Response
    • Integrates with NTLMSSP harvester
✅ NTLMSSP
  • File: ntlmssp.go
  • Protocols: SMB, HTTP, IMAP, SMTP, LDAP
  • Supports: NTLMv1 and NTLMv2
  • Hashcat Modes:
    • 5500 (NTLMv1): username::domain:LM:NT:challenge
    • 5600 (NTLMv2): username::domain:challenge:NT:blob
  • Features:
    • Session-based state machine (Challenge → Response)
    • Extracts: username, domain, workstation, challenge, LM hash, NT hash
    • Auto-detects NTLMv1 vs NTLMv2
    • UTF-16LE decoding for strings
✅ Kerberos AS-REQ
  • File: kerberos_asreq.go
  • Protocol: Kerberos v5 (port 88)
  • Supports: etype 23 (RC4-HMAC-MD5)
  • Hashcat Mode: 7500
  • Format: $krb5pa$23$user$realm$$hash
  • Features:
    • Extracts pre-authentication hashes
    • Hash byte order switching (as per Kerberos spec)
    • Works with UDP and TCP (with 4-byte length prefix)
✅ Database Credentials
  • PostgreSQL (port 5432)
    • Plaintext authentication (user/password)
    • MD5 challenge-response (Hashcat mode 11100)
    • Database name extraction
  • MySQL (port 3306)
    • Native Password challenge-response (Hashcat mode 11200)
    • Server greeting and client auth parsing
    • Database name extraction
  • MongoDB (port 27017)
    • SCRAM-SHA-1 and SCRAM-SHA-256
    • SASL message parsing
    • Salt, iterations, and proof extraction
  • Redis (port 6379)
    • Simple AUTH command
    • RESP protocol format
    • Redis 6+ ACL authentication
✅ Directory Services
  • LDAP (ports 389, 636)
    • Simple Bind authentication (plaintext)
    • ASN.1 BER/DER parsing
    • Distinguished Name (DN) extraction
    • Username extraction from CN/UID
✅ Network Management
  • SNMP (ports 161, 162)
    • v1 and v2c community strings
    • ASN.1 structure parsing
    • Printable ASCII validation
✅ Remote Desktop
  • VNC (ports 5900-5902)
    • DES challenge-response (Hashcat mode 20200)
    • Apple Remote Desktop (ARD) detection
    • VNC MS Logon II (NTLM integration)
    • Entropy checking for challenge/response
  • TeamViewer (port 5938)
    • Remote desktop session detection
    • Authentication event tracking (AUTH_CHALLENGE, AUTH_RESPONSE, AUTH_RESULT)
    • Session ID and connection monitoring
    • Supports protocol versions 1.x and 2.x
✅ Network Discovery
  • mDNS (port 5353)
    • Multicast DNS hostname discovery
    • IP address to hostname mappings
    • Service discovery (SRV, TXT records)
    • Works with Bonjour/Avahi
  • NBNS (port 137)
    • NetBIOS Name Service
    • Windows computer name discovery
    • Workstation, Domain Controller, File Server identification
    • Node status response parsing
  • UPnP (port 1900)
    • Universal Plug and Play device discovery
    • Router, media server, IoT device identification
    • SSDP M-SEARCH and NOTIFY parsing
    • Device location and service type extraction
  • WSD (port 3702)
    • Web Services Discovery for Windows
    • SOAP/XML-based device discovery
    • Probe and ProbeMatch detection
    • Device type and address extraction
⚠️ Optional (Disabled by Default)
  • Credit Card Detection
    • Luhn algorithm validation
    • Card type identification (Visa, MasterCard, Amex, Discover, JCB, Diners)
    • Context extraction
    • NOTE: Can produce false positives

TODO: Requires ASN.1 Parsing

⏳ Kerberos AS-REP
  • Hashcat Modes: 18200 (etype 23), 19600 (etype 17), 19700 (etype 18)
  • Complexity: High - requires ASN.1 DER/BER decoder
  • Use Case: AS-REP roasting
⏳ Kerberos TGS-REP
  • Hashcat Modes: 13100 (etype 23), 19600 (etype 17), 19700 (etype 18)
  • Complexity: High - requires ASN.1 DER/BER decoder
  • Use Case: Kerberoasting service accounts

Test Data

Location: testdata/

  • 13 PCAP files from BruteShark project
  • Covers: NTLM, Kerberos, HTTP Digest, HTTP NTLM
  • All files verified readable

Usage

Harvesters run automatically during TCP session analysis. They are invoked by port mapping or by trying all harvesters on unknown ports.

Port Mapping
  • 21: FTP
  • 23: Telnet
  • 25, 465, 587: SMTP
  • 80, 8080: HTTP
  • 88: Kerberos
  • 110, 995: POP3
  • 137: NBNS
  • 143: IMAP
  • 161, 162: SNMP
  • 389, 636: LDAP
  • 445: SMB/NTLMSSP
  • 1900: UPnP/SSDP
  • 3306: MySQL
  • 3702: WSD
  • 5353: mDNS
  • 5432: PostgreSQL
  • 5900-5909: VNC
  • 5938: TeamViewer
  • 6379: Redis
  • 27017: MongoDB
Output Format

Credentials are stored in Credentials.ncap.gz with:

  • Timestamp
  • Service (protocol name)
  • Flow (connection identifier)
  • User
  • Password (plaintext or Hashcat format for hashes)
  • Notes (additional metadata)

Building

cd decoder/stream/credentials
go build
go test

Testing

# Run all tests
go test -v

# Run specific test
go test -v -run TestNTLMSSP

# Check test files
go test -v -run TestAllPCAPFilesExist

Implementation Notes

NTLMSSP
  • Searches for signature: NTLMSSP\x00
  • Challenge message type: 0x02
  • Auth message type: 0x03
  • Fields encoded as [length:2][maxlen:2][offset:4]
  • Strings are UTF-16LE encoded
Kerberos AS-REQ
  • AS-REQ message type: 0x0a
  • RC4 encryption type: 0x17
  • PA-DATA signatures: 0xa2 0x36 0x04 0x34 or 0xa2 0x35 0x04 0x33
  • Hash requires byte order switching (last 36 bytes, then first 16 bytes)
HTTP Digest
  • Parses Authorization header
  • Splits comma-separated key=value pairs
  • Strips quotes from values
  • Requires: username, response (minimum)

Future Enhancements

  1. UDP Packet Harvesting: Direct UDP packet analysis for Kerberos (currently only works on TCP)
  2. ASN.1 Parsing: Implement AS-REP and TGS-REP harvesters
  3. Hashcat Export: Dedicated export command for hash files
  4. WebUI Integration: Display hash-specific fields in credentials page
  5. Additional Protocols: LDAP, RDP, etc.

Documentation

Index

Constants

View Source
const (
	EtypeAES128CTS = 17 // AES128-CTS-HMAC-SHA1-96
	EtypeAES256CTS = 18 // AES256-CTS-HMAC-SHA1-96
	EtypeRC4HMAC   = 23 // RC4-HMAC
)

Kerberos encryption type constants

View Source
const (
	// DecoderName is the name for the credentials decoder
	DecoderName = "Credentials"
)

Variables

View Source
var Decoder = &decoder.AbstractDecoder{
	Name:        DecoderName,
	Description: "Credentials to authenticate to a service, like a username and password combination, or a token, api key, etc.",
	Type:        types.Type_NC_Credentials,
	PostInit: func(d *decoder.AbstractDecoder) (err error) {

		useHarvesters = true

		credLog, _, err = logging.InitZapLogger(
			decoderconfig.Instance.Out,
			"credentials",
			decoderconfig.Instance.Debug,
		)

		if err != nil {
			return err
		}

		// Load harvesters configuration
		var config *HarvestersConfigFile
		if decoderconfig.Instance.HarvestersConfigPath != "" {
			config, err = LoadHarvestersConfig(decoderconfig.Instance.HarvestersConfigPath)
			if err != nil {
				log.Printf("Failed to load harvesters config from %s: %v. Using default configuration.\n",
					decoderconfig.Instance.HarvestersConfigPath, err)
				config = nil
			}
		}

		if err := InitializeHarvesters(config); err != nil {
			return err
		}

		if decoderconfig.Instance.CustomRegex != "" {
			r, errCompile := regexp.Compile(decoderconfig.Instance.CustomRegex)
			if errCompile != nil {
				return errCompile
			}

			customRegexHarvester := Harvester{
				Name:        "Custom Regex",
				Description: "Custom regex pattern: " + decoderconfig.Instance.CustomRegex,
				HarvesterFunc: func(data []byte, ident string, ts time.Time) *types.Credentials {
					matches := r.FindSubmatch(data)
					if len(matches) > 1 {
						var notes strings.Builder
						for _, m := range matches {
							notes.WriteString(" " + string(m) + " ")
						}

						return &types.Credentials{
							Notes: notes.String(),
						}
					}

					return nil
				},
			}
			tcpConnectionHarvesters = append(tcpConnectionHarvesters, customRegexHarvester)
		}

		return nil
	},
	DeInit: func(sd *decoder.AbstractDecoder) error {
		return credLog.Sync()
	},
}

Decoder for protocol analysis and writing audit records to disk.

Functions

func InitBruteforceDetector added in v0.9.0

func InitBruteforceDetector(config *BruteforceConfig)

InitBruteforceDetector initializes the global bruteforce detector with custom config This should be called before any calls to GetBruteforceDetector for proper configuration

func InitializeHarvesters added in v0.9.0

func InitializeHarvesters(config *HarvestersConfigFile) error

InitializeHarvesters sets up the harvesters based on the provided configuration

func ResetCredStore added in v0.7.6

func ResetCredStore()

ResetCredStore clears the credentials deduplication store This should be called when resetting state between processing different files

func RunHarvesters

func RunHarvesters(banner []byte, transport gopacket.Flow, ident string, firstPacket time.Time, communityID string)

RunHarvesters will use the service probes to determine the service type based on the provided banner. The banner parameter contains at most HarvesterBannerSize bytes from the stream conversation, which is pre-truncated to prevent performance issues when processing large data streams (e.g., file transfers, database dumps, video streaming, etc.). The communityID parameter is the Corelight Community ID v1 for the connection, calculated once at the stream level and available for all harvesters to use for cross-tool correlation.

func SaveHarvestersConfig added in v0.9.0

func SaveHarvestersConfig(path string, config *HarvestersConfigFile) error

SaveHarvestersConfig saves harvester configuration to a YAML file

func WriteCredentials

func WriteCredentials(creds *types.Credentials)

WriteCredentials is a util that should be used to write credential audit to disk it will deduplicate the audit records to avoid repeating information on disk.

Types

type BruteforceAlert added in v0.9.0

type BruteforceAlert struct {
	Timestamp      time.Time
	SourceIP       string
	Service        string
	FailedAttempts int
	TargetServers  []string // Unique servers targeted
	Duration       time.Duration
	FirstAttempt   time.Time
	LastAttempt    time.Time
}

BruteforceAlert represents a detected bruteforce attack

func (*BruteforceAlert) String added in v0.9.0

func (a *BruteforceAlert) String() string

String returns a human-readable description of the alert

type BruteforceConfig added in v0.9.0

type BruteforceConfig struct {
	// FailureThreshold is the number of failed attempts before alerting
	FailureThreshold int `yaml:"failure_threshold"`
	// MeasurementInterval is the time window for counting failures
	MeasurementInterval time.Duration `yaml:"measurement_interval"`
	// PerSourceTracking tracks failures per source IP
	PerSourceTracking bool `yaml:"per_source_tracking"`
	// PerServiceTracking tracks failures per service type
	PerServiceTracking bool `yaml:"per_service_tracking"`
	// Enabled controls whether bruteforce detection is active
	Enabled bool `yaml:"enabled"`
}

BruteforceConfig holds configuration for bruteforce detection

func DefaultBruteforceConfig added in v0.9.0

func DefaultBruteforceConfig() *BruteforceConfig

DefaultBruteforceConfig returns default bruteforce detection settings Similar to Zeek's FTP/SSH bruteforce detection defaults

type BruteforceDetector added in v0.9.0

type BruteforceDetector struct {
	// contains filtered or unexported fields
}

BruteforceDetector tracks failed authentication attempts and detects bruteforce attacks Similar to Zeek's SumStats-based approach

func GetBruteforceDetector added in v0.9.0

func GetBruteforceDetector() *BruteforceDetector

GetBruteforceDetector returns the global bruteforce detector instance

func NewBruteforceDetector added in v0.9.0

func NewBruteforceDetector(config *BruteforceConfig) *BruteforceDetector

NewBruteforceDetector creates a new bruteforce detection instance

func (*BruteforceDetector) GetAlerts added in v0.9.0

func (d *BruteforceDetector) GetAlerts() []BruteforceAlert

GetAlerts returns all currently tracked alerts

func (*BruteforceDetector) GetStats added in v0.9.0

func (d *BruteforceDetector) GetStats() map[string]any

GetStats returns statistics about the detector

func (*BruteforceDetector) RecordFailure added in v0.9.0

func (d *BruteforceDetector) RecordFailure(sourceIP, targetIP, service, username string, ts time.Time)

RecordFailure records a failed authentication attempt This should be called whenever AuthSuccessSet is true and AuthSuccess is false

func (*BruteforceDetector) RecordSuccess added in v0.9.0

func (d *BruteforceDetector) RecordSuccess(sourceIP, targetIP, service, username string, ts time.Time)

RecordSuccess records a successful authentication (can be used to track password guessers who succeeded)

func (*BruteforceDetector) SetAlertCallback added in v0.9.0

func (d *BruteforceDetector) SetAlertCallback(cb func(BruteforceAlert))

SetAlertCallback sets the function to call when a bruteforce alert is generated

func (*BruteforceDetector) Stop added in v0.9.0

func (d *BruteforceDetector) Stop()

Stop stops the bruteforce detector and cleans up resources

type CustomHarvesterConfig added in v0.9.0

type CustomHarvesterConfig struct {
	Name        string         `yaml:"name" json:"name"`
	Description string         `yaml:"description,omitempty" json:"description,omitempty"`
	Enabled     bool           `yaml:"enabled" json:"enabled"`
	Ports       []int          `yaml:"ports" json:"ports"`
	Regex       string         `yaml:"regex" json:"regex"`
	Parameters  map[string]any `yaml:"parameters,omitempty" json:"parameters,omitempty"`
}

CustomHarvesterConfig represents configuration for a custom regex-based harvester

type Harvester added in v0.9.0

type Harvester struct {
	Name          string
	Description   string
	HarvesterFunc credentialHarvester
}

Harvester represents a credential harvester with its function and metadata

type HarvesterConfig added in v0.9.0

type HarvesterConfig struct {
	Name        string         `yaml:"name" json:"name"`
	Description string         `yaml:"description,omitempty" json:"description,omitempty"`
	Enabled     bool           `yaml:"enabled" json:"enabled"`
	Ports       []int          `yaml:"ports" json:"ports"`
	Parameters  map[string]any `yaml:"parameters,omitempty" json:"parameters,omitempty"`
}

HarvesterConfig represents the configuration for a single credential harvester

type HarvesterInfo added in v0.9.0

type HarvesterInfo struct {
	Name        string
	Description string
	Ports       []int
}

HarvesterInfo contains metadata about a credential harvester for API responses

func GetHarvesters added in v0.9.0

func GetHarvesters() []HarvesterInfo

GetHarvesters returns information about all registered credential harvesters including their names, descriptions, and associated port mappings

type HarvestersConfigFile added in v0.9.0

type HarvestersConfigFile struct {
	Harvesters       []HarvesterConfig       `yaml:"harvesters" json:"harvesters"`
	CustomHarvesters []CustomHarvesterConfig `yaml:"custom_harvesters,omitempty" json:"custom_harvesters,omitempty"`
}

HarvestersConfigFile represents the entire harvesters configuration file structure

func GetDefaultHarvestersConfig added in v0.9.0

func GetDefaultHarvestersConfig() *HarvestersConfigFile

GetDefaultHarvestersConfig returns the default harvester configuration

func GetHarvesterConfig added in v0.9.0

func GetHarvesterConfig() *HarvestersConfigFile

GetHarvesterConfig returns the current harvester configuration

func LoadHarvestersConfig added in v0.9.0

func LoadHarvestersConfig(path string) (*HarvestersConfigFile, error)

LoadHarvestersConfig loads harvester configuration from a YAML file

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL