Documentation
¶
Overview ¶
Package fingerprinters provides HTTP fingerprinting for JFrog Artifactory.
Detection Strategy ¶
JFrog Artifactory is a universal artifact repository manager that stores and manages software packages and dependencies. It's a critical infrastructure component that represents a security concern due to:
- Storage of proprietary software artifacts
- Access to internal source code and binaries
- Potential supply chain attack vector
- Often contains credentials and API tokens
Detection uses a two-pronged approach: 1. Passive: Check for Artifactory-specific response headers (X-JFrog-Version, X-Artifactory-Id, X-Artifactory-Node-Id) 2. Active: Query /artifactory/api/system/ping endpoint (no authentication required)
API Response Format ¶
The /artifactory/api/system/ping endpoint returns "OK" with headers:
X-JFrog-Version: Artifactory/7.136.0 83600900 X-Artifactory-Id: 82452a18829b4122b65e8033d68e59c338b0cc06 X-Artifactory-Node-Id: a0rnvpm6mmcdc-artifactory-primary-0
Format breakdown:
- X-JFrog-Version: "Artifactory/<VERSION> <REVISION>"
- X-Artifactory-Id: Unique instance identifier
- X-Artifactory-Node-Id: Node identifier for clustered deployments
Cloud vs On-Prem Differences ¶
Both cloud and on-prem instances:
- Use /artifactory/api/system/ping endpoint
- Ping endpoint works WITHOUT authentication
- Version information is provided in headers (X-JFrog-Version)
Cloud instances (e.g., jfrog.io):
- Use /artifactory/ prefix for all API endpoints
On-prem instances (e.g., port 8081):
- May use /api/ prefix directly for some endpoints
- Ping endpoint still requires /artifactory/ prefix
Port Configuration ¶
Artifactory typically runs on:
- 8081: Default Artifactory web port (on-prem)
- 8082: JFrog Platform Router port
- 443: HTTPS in production and cloud deployments
Example Usage ¶
fp := &ArtifactoryFingerprinter{}
if fp.Match(resp) {
result, err := fp.Fingerprint(resp, body)
if err == nil && result != nil {
fmt.Printf("Detected: %s version %s\n", result.Technology, result.Version)
}
}
Package fingerprinters provides HTTP fingerprinting for HashiCorp Consul.
Detection Strategy:
- Active probe: /v1/agent/self endpoint
- Required field: Config.Datacenter (Consul-specific)
- Version extraction: Config.Version with Enterprise (+ent) detection
- Ports: 8500 (HTTP), 8501 (HTTPS)
Package fingerprinters provides HTTP fingerprinting for Grafana.
Detection Strategy ¶
Grafana is an open-source analytics and monitoring platform. Exposed instances represent a security concern due to:
- Dashboard access with potentially sensitive data
- Data source configurations with credentials
- API key management
- Often exposed without authentication
Detection uses active probing:
- Active: Query /api/health endpoint (no authentication required)
- Response must contain all three fields: database, version, commit
API Response Format ¶
The /api/health endpoint returns JSON without authentication:
{
"commit": "abc123def456",
"database": "ok",
"version": "10.4.1"
}
Port Configuration ¶
Grafana typically runs on:
- 3000: Default Grafana HTTP port
- 443: HTTPS in production
Example Usage ¶
fp := &GrafanaFingerprinter{}
if fp.Match(resp) {
result, err := fp.Fingerprint(resp, body)
if err == nil && result != nil {
fmt.Printf("Detected: %s version %s\n", result.Technology, result.Version)
}
}
Package fingerprinters provides HTTP fingerprinting for Jaeger.
Detection Strategy ¶
Jaeger is a widely deployed distributed tracing system. Exposed instances represent a security concern due to:
- Access to application tracing data revealing system architecture
- Potential information disclosure about service dependencies
- Exposure of performance metrics and call patterns
- Query capabilities that could reveal sensitive information
- Administrative endpoints that may be exposed
Detection uses two approaches: 1. Passive HTML detection: Check for <title>Jaeger UI</title> in root response and extract version from embedded JAEGER_VERSION JSON 2. Active JSON detection: Query /api/services endpoint (no authentication required)
API Response Format ¶
The /api/services endpoint returns JSON without authentication:
{
"data": ["service-a", "service-b", "checkout", "frontend"],
"errors": null,
"limit": 0,
"offset": 0,
"total": 4
}
Fresh instances with no traced services may return:
{
"data": null,
"errors": null,
"limit": 0,
"offset": 0,
"total": 0
}
Or:
{
"data": [],
"errors": null,
"limit": 0,
"offset": 0,
"total": 0
}
Format breakdown:
- data: Array of service name strings, or null on fresh instances (required field)
- errors: Error field, typically null (required field to exist - distinguishes from other JSON APIs)
- total: Total count of services (required field)
- limit: Pagination limit (required field)
- offset: Pagination offset (required field)
Detection is based on the structural signature: the presence of all 5 fields (data, errors, total, limit, offset) uniquely identifies Jaeger's /api/services endpoint. No other common HTTP API returns this exact structure.
Port Configuration ¶
Jaeger typically runs on:
- 16686: Default Jaeger Query service HTTP port
- 443: HTTPS in production deployments
- 80: HTTP in some deployments
Example Usage ¶
fp := &JaegerFingerprinter{}
if fp.Match(resp) {
result, err := fp.Fingerprint(resp, body)
if err == nil && result != nil {
fmt.Printf("Detected: %s with %d services\n", result.Technology, result.Metadata["serviceCount"])
}
}
Package fingerprinters provides HTTP fingerprinting for Jenkins CI/CD.
Detection Strategy ¶
Jenkins is an open-source automation server used for CI/CD. It's a critical infrastructure component that represents a security concern due to:
- Script Console access (Groovy RCE)
- Build history with credentials
- Pipeline configurations with secrets
- Often exposed without authentication
Detection uses passive-only approach:
- Check for Jenkins-specific response headers (X-Jenkins, X-Hudson)
- Version extraction from X-Jenkins header (direct value, no parsing)
- X-Hudson header indicates legacy Hudson compatibility
Response Headers ¶
Jenkins sends identifying headers on all HTTP responses:
X-Jenkins: 2.541.1 X-Hudson: 1.395 X-Jenkins-Session: f55df8ea
Header breakdown:
- X-Jenkins: Version string (primary detection and version extraction)
- X-Hudson: Legacy Hudson compatibility version
- X-Jenkins-Session: Session identifier (not used for detection)
Port Configuration ¶
Jenkins typically runs on:
- 8080: Default Jenkins web port
- 443: HTTPS in production
- 8443: Alternative HTTPS port
Example Usage ¶
fp := &JenkinsFingerprinter{}
if fp.Match(resp) {
result, err := fp.Fingerprint(resp, body)
if err == nil && result != nil {
fmt.Printf("Detected: %s version %s\n", result.Technology, result.Version)
}
}
Package fingerprinters provides HTTP fingerprinting for Prometheus.
Detection Strategy ¶
Prometheus is a widely deployed monitoring and alerting system. Exposed instances represent a security concern due to:
- Access to infrastructure metrics and monitoring data
- Potential information disclosure about system architecture
- Query capabilities that could reveal sensitive information
- Administrative endpoints that may be exposed
Detection uses a two-pronged approach: 1. Passive: Check for Content-Type: application/json header (weak pre-filter) 2. Active: Query /api/v1/status/buildinfo endpoint (no authentication required)
API Response Format ¶
The /api/v1/status/buildinfo endpoint returns JSON without authentication:
{
"status": "success",
"data": {
"version": "2.45.0",
"revision": "abc123def456",
"branch": "HEAD",
"buildUser": "root@buildhost",
"buildDate": "20231215-08:42:32",
"goVersion": "go1.21.5"
}
}
Format breakdown:
- status: API response status (required, must be "success")
- data: Build information object (required)
- data.version: Prometheus version string (required for detection)
- data.goVersion: Go version used to build (required, distinguishes from other APIs)
- data.revision: Git commit hash (optional)
- data.branch: Git branch (optional)
- data.buildUser: User who built the binary (optional)
- data.buildDate: Build timestamp (optional)
Port Configuration ¶
Prometheus typically runs on:
- 9090: Default Prometheus HTTP API port
- 443: HTTPS in production deployments
Example Usage ¶
fp := &PrometheusFingerprinter{}
if fp.Match(resp) {
result, err := fp.Fingerprint(resp, body)
if err == nil && result != nil {
fmt.Printf("Detected: %s version %s\n", result.Technology, result.Version)
}
}
Package fingerprinters provides HTTP fingerprinting for QNAP NAS devices.
Detection Strategy ¶
QNAP NAS devices run QTS (QNAP Turbo Station) operating system, which is commonly found on customer attack surfaces. Detection of exposed NAS devices is critical because:
- Often contain sensitive business data and backups
- Frequently exposed to the internet for remote access
- Target for ransomware and data exfiltration
- May have admin interfaces exposed without authentication
- Historical vulnerabilities in QTS firmware
Detection uses active probing of the authLogin.cgi endpoint which returns identifying XML without requiring authentication. This endpoint is unique to QNAP devices.
Response Format ¶
The /cgi-bin/authLogin.cgi endpoint returns XML with device information:
<?xml version="1.0" encoding="UTF-8" ?> <QDocRoot version="1.0"> <firmware> <version><![CDATA[4.4.1]]></version> <number><![CDATA[1216]]></number> <build><![CDATA[20200214]]></build> </firmware> <hostname><![CDATA[NAS-NAME]]></hostname> <model> <displayModelName><![CDATA[TS-873U-RP]]></displayModelName> </model> </QDocRoot>
Response breakdown:
- <QDocRoot> - Root element unique to QNAP devices (primary detection)
- <firmware><version> - QTS version string (e.g., "4.4.1", "5.1.0")
- <firmware><number> - Build number (e.g., "1216")
- <firmware><build> - Build date in YYYYMMDD format
- <model><displayModelName> - Hardware model (e.g., "TS-873U-RP")
- <hostname> - Device hostname
Port Configuration ¶
QNAP NAS devices typically expose web interfaces on:
- 8080: HTTP (default)
- 443: HTTPS (default)
- 8081: Alternative HTTP port
Security Relevance ¶
QNAP devices are frequently targeted in attacks:
- CVE-2024-27130: SQL injection in Music Station
- CVE-2023-23368: Authentication bypass in QTS
- CVE-2021-28799: Hardcoded credentials
- Regular targets for Qlocker, eCh0raix ransomware
Detection helps identify exposed devices for vulnerability assessment and remediation.
Example Usage ¶
fp := &QNAPFingerprinter{}
// Probe /cgi-bin/authLogin.cgi endpoint
if fp.Match(resp) {
result, err := fp.Fingerprint(resp, body)
if err == nil && result != nil {
fmt.Printf("Detected: %s version %s\n", result.Technology, result.Version)
}
}
Package fingerprinters provides HTTP application fingerprinting. These fingerprinters detect applications running over HTTP and return technology/CPE metadata to attach to the HTTP service payload.
Package fingerprinters provides HTTP fingerprinting for SOAP APIs.
Detection Strategy ¶
SOAP (Simple Object Access Protocol) is an XML-based messaging protocol used for web service communication. Exposed SOAP endpoints represent a security concern due to:
- Potential information disclosure via WSDL service descriptions
- XML-based attack surface (XXE, SSRF, XML injection)
- Often exposed without authentication
- Legacy systems with known vulnerabilities
Detection uses two approaches:
- Passive: Check Content-Type headers and response body for SOAP envelope namespaces and WSDL definitions
- Active: Query ?wsdl endpoint to discover WSDL service descriptions
Detection Markers ¶
SOAP 1.1 responses contain the namespace:
http://schemas.xmlsoap.org/soap/envelope/
SOAP 1.2 responses contain the namespace:
http://www.w3.org/2003/05/soap-envelope
WSDL responses contain the namespace:
http://schemas.xmlsoap.org/wsdl/
SOAP 1.2 also uses the definitive Content-Type:
application/soap+xml
Port Configuration ¶
SOAP services typically run on standard HTTP/HTTPS ports:
- 80: HTTP
- 443: HTTPS
- 8080: Alternative HTTP
- 8443: Alternative HTTPS
Example Usage ¶
fp := &SOAPFingerprinter{}
if fp.Match(resp) {
result, err := fp.Fingerprint(resp, body)
if err == nil && result != nil {
fmt.Printf("Detected: %s (version: %s)\n", result.Technology, result.Metadata["soapVersion"])
}
}
Package fingerprinters provides HTTP fingerprinting for JetBrains TeamCity.
Detection Strategy ¶
JetBrains TeamCity is a CI/CD build management server. Exposed instances represent a security concern due to:
- Build configuration access with potentially sensitive environment variables
- Source code repository connection credentials
- Deployment pipeline secrets and API tokens
- Build agent access allowing code execution
Detection uses a two-pronged approach:
- Passive: Check for TeamCity-specific response headers (TeamCity-Node-Id, X-TC-CSRF-Token)
- Active: Query /app/rest/server endpoint (may require authentication)
API Response Format ¶
The /app/rest/server endpoint returns JSON (with Accept: application/json):
{
"version": "2023.11.4 (build 147571)",
"versionMajor": 2023,
"versionMinor": 11,
"buildNumber": "147571",
"buildDate": "20240301T000000+0000",
"internalId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"webUrl": "https://teamcity.example.com"
}
Or XML (default format):
<server version="2023.11.4 (build 147571)" buildNumber="147571"
internalId="a1b2c3d4-e5f6-7890-abcd-ef1234567890"
webUrl="https://teamcity.example.com"/>
Port Configuration ¶
TeamCity typically runs on:
- 8111: Default TeamCity HTTP port
- 443: HTTPS in production
- 8443: Alternative HTTPS port
Example Usage ¶
fp := &TeamCityFingerprinter{}
if fp.Match(resp) {
result, err := fp.Fingerprint(resp, body)
if err == nil && result != nil {
fmt.Printf("Detected: %s version %s\n", result.Technology, result.Version)
}
}
Package fingerprinters provides HTTP fingerprinting for UPnP services.
Detection Strategy ¶
UPnP (Universal Plug and Play) devices expose HTTP endpoints that serve XML device descriptions containing UPnP-specific schemas. Detection targets these HTTP responses.
Security relevance:
- UPnP devices may expose internal network topology
- SOAP control endpoints can allow device manipulation
- Often found on IoT devices with weak security
- Can be abused for SSRF or port mapping attacks
Detection uses passive approach on root HTTP response:
- Check for SERVER header containing "UPnP" (case-insensitive substring)
- Check response body for UPnP XML namespace (urn:schemas-upnp-org)
- Extract server string and UPnP version information
Response Headers ¶
UPnP devices typically include identifying headers:
SERVER: Linux/3.0 UPnP/1.0 IpBridge/1.16.0 Content-Type: text/xml; charset="utf-8"
Response Body ¶
UPnP device descriptions contain XML with UPnP namespace:
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion><major>1</major><minor>0</minor></specVersion>
<device>
<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>
<friendlyName>Philips hue</friendlyName>
</device>
</root>
Port Configuration ¶
UPnP HTTP endpoints typically run on:
- 2869: Windows UPnP Device Host
- 5000: Synology DSM, various UPnP devices
- 8080: Common alternative HTTP port
- 49152-65535: Dynamic ports advertised via SSDP
Example Usage ¶
fp := &UPnPFingerprinter{}
if fp.Match(resp) {
result, err := fp.Fingerprint(resp, body)
if err == nil && result != nil {
fmt.Printf("Detected: %s version %s\n", result.Technology, result.Version)
}
}
Package fingerprinters provides HTTP fingerprinting for HashiCorp Vault.
Detection Strategy ¶
HashiCorp Vault is the most widely deployed secrets management solution. Exposed instances represent a critical security concern due to:
- Storage of secrets and credentials
- Potential access to sensitive data if unsealed
- Cluster configuration information leakage
- Authentication and authorization bypass vulnerabilities
Detection uses a two-pronged approach: 1. Passive: Check for Cache-Control: no-store header (weak pre-filter) 2. Active: Query /v1/sys/health endpoint (no authentication required)
API Response Format ¶
The /v1/sys/health endpoint returns JSON without authentication:
{
"initialized": true,
"sealed": false,
"version": "1.12.3",
"cluster_name": "vault-cluster-7089ef9c",
"cluster_id": "9c5dcbaa-7361-202d-3dba-b235c6f7f443",
"enterprise": false
}
Format breakdown:
- version: Vault version string (required for detection)
- sealed: Whether the Vault is sealed (security critical)
- initialized: Whether Vault has been initialized
- cluster_name: Cluster identifier (optional)
- enterprise: Whether this is Vault Enterprise
Port Configuration ¶
Vault typically runs on:
- 8200: Default Vault HTTP API port
- 443: HTTPS in production deployments
Example Usage ¶
fp := &VaultFingerprinter{}
if fp.Match(resp) {
result, err := fp.Fingerprint(resp, body)
if err == nil && result != nil {
fmt.Printf("Detected: %s version %s\n", result.Technology, result.Version)
}
}
Package fingerprinters provides HTTP fingerprinting for WinRM.
Detection Strategy ¶
WinRM (Windows Remote Management) is a Microsoft implementation of WS-Management protocol for remote Windows system management. Detection identifies:
- WinRM endpoints via Microsoft-HTTPAPI/2.0 server header
- Probe /wsman endpoint (standard WS-Management path)
- 401 Unauthorized indicates auth-required WinRM instance
Port Configuration:
- 5985: HTTP (unencrypted WinRM)
- 5986: HTTPS (encrypted WinRM)
Example Usage ¶
fp := &WinRMFingerprinter{}
if fp.Match(resp) {
result, err := fp.Fingerprint(resp, body)
if err == nil && result != nil {
fmt.Printf("Detected: %s\n", result.Technology)
}
}
Index ¶
- func GetProbeEndpoints() map[string]string
- func Register(fp HTTPFingerprinter)
- type ActiveHTTPFingerprinter
- type AnyConnectFingerprinter
- type ArangoDBFingerprinter
- type ArtifactoryFingerprinter
- type BigIPFingerprinter
- type ChromaDBFingerprinter
- type ConsulFingerprinter
- type CouchDBFingerprinter
- type ElasticsearchFingerprinter
- type EtcdFingerprinter
- type FingerprintResult
- type FortiGateFingerprinter
- type GlobalProtectFingerprinter
- type GrafanaFingerprinter
- type HTTPFingerprinter
- type JaegerFingerprinter
- type JenkinsFingerprinter
- type KubernetesFingerprinter
- type NATSFingerprinter
- type PineconeFingerprinter
- type PrometheusFingerprinter
- type QNAPFingerprinter
- type SOAPFingerprinter
- type TeamCityFingerprinter
- type UPnPFingerprinter
- type VaultFingerprinter
- type WinRMFingerprinter
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GetProbeEndpoints ¶
GetProbeEndpoints returns a map of fingerprinter name to probe endpoint for all registered ActiveHTTPFingerprinters.
Types ¶
type ActiveHTTPFingerprinter ¶
type ActiveHTTPFingerprinter interface {
HTTPFingerprinter
// ProbeEndpoint returns the endpoint path to probe for this fingerprinter.
// Return "" to use the default "/" endpoint.
// Examples: "/version", "/api/v1/version", "/_cluster/health"
ProbeEndpoint() string
}
ActiveHTTPFingerprinter extends HTTPFingerprinter with the ability to make additional HTTP requests for enrichment. Use this when detection requires querying specific endpoints (e.g., Kubernetes /version).
type AnyConnectFingerprinter ¶
type AnyConnectFingerprinter struct{}
AnyConnectFingerprinter detects Cisco AnyConnect SSL VPN
func (*AnyConnectFingerprinter) Fingerprint ¶
func (f *AnyConnectFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*AnyConnectFingerprinter) Match ¶
func (f *AnyConnectFingerprinter) Match(resp *http.Response) bool
func (*AnyConnectFingerprinter) Name ¶
func (f *AnyConnectFingerprinter) Name() string
func (*AnyConnectFingerprinter) ProbeEndpoint ¶
func (f *AnyConnectFingerprinter) ProbeEndpoint() string
type ArangoDBFingerprinter ¶
type ArangoDBFingerprinter struct{}
ArangoDBFingerprinter detects ArangoDB via /_api/version endpoint
func (*ArangoDBFingerprinter) Fingerprint ¶
func (f *ArangoDBFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*ArangoDBFingerprinter) Match ¶
func (f *ArangoDBFingerprinter) Match(resp *http.Response) bool
func (*ArangoDBFingerprinter) Name ¶
func (f *ArangoDBFingerprinter) Name() string
func (*ArangoDBFingerprinter) ProbeEndpoint ¶
func (f *ArangoDBFingerprinter) ProbeEndpoint() string
type ArtifactoryFingerprinter ¶
type ArtifactoryFingerprinter struct{}
ArtifactoryFingerprinter detects JFrog Artifactory instances via /artifactory/api/system/ping endpoint
func (*ArtifactoryFingerprinter) Fingerprint ¶
func (f *ArtifactoryFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*ArtifactoryFingerprinter) Match ¶
func (f *ArtifactoryFingerprinter) Match(resp *http.Response) bool
func (*ArtifactoryFingerprinter) Name ¶
func (f *ArtifactoryFingerprinter) Name() string
func (*ArtifactoryFingerprinter) ProbeEndpoint ¶
func (f *ArtifactoryFingerprinter) ProbeEndpoint() string
type BigIPFingerprinter ¶
type BigIPFingerprinter struct{}
BigIPFingerprinter detects F5 BIG-IP management interfaces and load balancers
func (*BigIPFingerprinter) Fingerprint ¶
func (f *BigIPFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*BigIPFingerprinter) Name ¶
func (f *BigIPFingerprinter) Name() string
func (*BigIPFingerprinter) ProbeEndpoint ¶
func (f *BigIPFingerprinter) ProbeEndpoint() string
type ChromaDBFingerprinter ¶
type ChromaDBFingerprinter struct{}
ChromaDBFingerprinter detects ChromaDB vector database via /api/v1/heartbeat endpoint
func (*ChromaDBFingerprinter) Fingerprint ¶
func (f *ChromaDBFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*ChromaDBFingerprinter) Match ¶
func (f *ChromaDBFingerprinter) Match(resp *http.Response) bool
func (*ChromaDBFingerprinter) Name ¶
func (f *ChromaDBFingerprinter) Name() string
func (*ChromaDBFingerprinter) ProbeEndpoint ¶
func (f *ChromaDBFingerprinter) ProbeEndpoint() string
type ConsulFingerprinter ¶
type ConsulFingerprinter struct{}
ConsulFingerprinter detects HashiCorp Consul via /v1/agent/self
func (*ConsulFingerprinter) Fingerprint ¶
func (f *ConsulFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*ConsulFingerprinter) Name ¶
func (f *ConsulFingerprinter) Name() string
func (*ConsulFingerprinter) ProbeEndpoint ¶
func (f *ConsulFingerprinter) ProbeEndpoint() string
type CouchDBFingerprinter ¶
type CouchDBFingerprinter struct{}
CouchDBFingerprinter detects Apache CouchDB via root endpoint
func (*CouchDBFingerprinter) Fingerprint ¶
func (f *CouchDBFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*CouchDBFingerprinter) Name ¶
func (f *CouchDBFingerprinter) Name() string
func (*CouchDBFingerprinter) ProbeEndpoint ¶
func (f *CouchDBFingerprinter) ProbeEndpoint() string
type ElasticsearchFingerprinter ¶
type ElasticsearchFingerprinter struct{}
ElasticsearchFingerprinter detects Elasticsearch via root endpoint (/)
func (*ElasticsearchFingerprinter) Fingerprint ¶
func (f *ElasticsearchFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*ElasticsearchFingerprinter) Match ¶
func (f *ElasticsearchFingerprinter) Match(resp *http.Response) bool
func (*ElasticsearchFingerprinter) Name ¶
func (f *ElasticsearchFingerprinter) Name() string
type EtcdFingerprinter ¶
type EtcdFingerprinter struct{}
EtcdFingerprinter detects etcd distributed key-value store via /version endpoint. Detection is based on the presence of "etcdserver" field in the JSON response.
func (*EtcdFingerprinter) Fingerprint ¶
func (f *EtcdFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
Fingerprint performs etcd detection by parsing the /version JSON response.
func (*EtcdFingerprinter) Match ¶
func (f *EtcdFingerprinter) Match(resp *http.Response) bool
Match returns true if the response might be from etcd (JSON content type).
func (*EtcdFingerprinter) Name ¶
func (f *EtcdFingerprinter) Name() string
func (*EtcdFingerprinter) ProbeEndpoint ¶
func (f *EtcdFingerprinter) ProbeEndpoint() string
ProbeEndpoint returns the endpoint needed for etcd detection. etcd exposes version info at /version endpoint.
type FingerprintResult ¶
type FingerprintResult struct {
Technology string // e.g., "kubernetes"
Version string // e.g., "1.29.0"
CPEs []string // e.g., ["cpe:2.3:a:kubernetes:kubernetes:1.29.0:*:*:*:*:*:*:*"]
Metadata map[string]any // service-specific additional data
}
FingerprintResult contains the detected technology information
func RunFingerprinters ¶
func RunFingerprinters(resp *http.Response, body []byte) []*FingerprintResult
RunFingerprinters executes all matching fingerprinters and returns results
type FortiGateFingerprinter ¶
type FortiGateFingerprinter struct{}
FortiGateFingerprinter detects Fortinet FortiGate appliances.
Detection Strategy: FortiGate appliances run FortiOS with a distinctive obfuscated Server header (xxxxxxxx-xxxxx) and characteristic HTTP responses. Detection uses:
1. Server Header: xxxxxxxx-xxxxx (primary indicator, highest confidence) 2. ETag Format: "XX-XXXXXXXX" where second hex is Unix timestamp (firmware build date) 3. Body Patterns: /remote/login redirect, ftnt-fortinet-grid icon class (only with Server/ETag)
This fingerprinter addresses a detection gap where 3 FortiGate appliances on non-standard ports were invisible to the Chariot pipeline. FortiGate is a common enterprise security appliance, and detection is critical for attack surface visibility.
func (*FortiGateFingerprinter) Fingerprint ¶
func (f *FortiGateFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*FortiGateFingerprinter) Match ¶
func (f *FortiGateFingerprinter) Match(resp *http.Response) bool
func (*FortiGateFingerprinter) Name ¶
func (f *FortiGateFingerprinter) Name() string
type GlobalProtectFingerprinter ¶
type GlobalProtectFingerprinter struct{}
GlobalProtectFingerprinter detects Palo Alto GlobalProtect SSL VPN
func (*GlobalProtectFingerprinter) Fingerprint ¶
func (f *GlobalProtectFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*GlobalProtectFingerprinter) Match ¶
func (f *GlobalProtectFingerprinter) Match(resp *http.Response) bool
func (*GlobalProtectFingerprinter) Name ¶
func (f *GlobalProtectFingerprinter) Name() string
func (*GlobalProtectFingerprinter) ProbeEndpoint ¶
func (f *GlobalProtectFingerprinter) ProbeEndpoint() string
type GrafanaFingerprinter ¶
type GrafanaFingerprinter struct{}
GrafanaFingerprinter detects Grafana instances via /api/health endpoint
func (*GrafanaFingerprinter) Fingerprint ¶
func (f *GrafanaFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*GrafanaFingerprinter) Name ¶
func (f *GrafanaFingerprinter) Name() string
func (*GrafanaFingerprinter) ProbeEndpoint ¶
func (f *GrafanaFingerprinter) ProbeEndpoint() string
type HTTPFingerprinter ¶
type HTTPFingerprinter interface {
// Name returns the fingerprinter identifier
Name() string
// Match returns true if this fingerprinter should attempt detection
// This is a fast pre-filter based on headers/status before reading body
Match(resp *http.Response) bool
// Fingerprint performs full detection and extracts technology info
// body is the response body (already read)
Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
}
HTTPFingerprinter detects applications running over HTTP
func GetFingerprinterByName ¶
func GetFingerprinterByName(name string) HTTPFingerprinter
GetFingerprinterByName returns the fingerprinter with the given name
func GetFingerprinters ¶
func GetFingerprinters() []HTTPFingerprinter
GetFingerprinters returns all registered fingerprinters
type JaegerFingerprinter ¶
type JaegerFingerprinter struct{}
JaegerFingerprinter detects Jaeger instances via /api/services endpoint
func (*JaegerFingerprinter) Fingerprint ¶
func (f *JaegerFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*JaegerFingerprinter) Name ¶
func (f *JaegerFingerprinter) Name() string
func (*JaegerFingerprinter) ProbeEndpoint ¶
func (f *JaegerFingerprinter) ProbeEndpoint() string
type JenkinsFingerprinter ¶
type JenkinsFingerprinter struct{}
JenkinsFingerprinter detects Jenkins instances via X-Jenkins and X-Hudson headers
func (*JenkinsFingerprinter) Fingerprint ¶
func (f *JenkinsFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*JenkinsFingerprinter) Name ¶
func (f *JenkinsFingerprinter) Name() string
type KubernetesFingerprinter ¶
type KubernetesFingerprinter struct{}
KubernetesFingerprinter detects Kubernetes API servers via /version endpoint
func (*KubernetesFingerprinter) Fingerprint ¶
func (f *KubernetesFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*KubernetesFingerprinter) Match ¶
func (f *KubernetesFingerprinter) Match(resp *http.Response) bool
func (*KubernetesFingerprinter) Name ¶
func (f *KubernetesFingerprinter) Name() string
func (*KubernetesFingerprinter) ProbeEndpoint ¶
func (f *KubernetesFingerprinter) ProbeEndpoint() string
type NATSFingerprinter ¶
type NATSFingerprinter struct{}
NATSFingerprinter detects NATS monitoring via /varz endpoint. Detection is based on the presence of "server_id" field in the JSON response.
func (*NATSFingerprinter) Fingerprint ¶
func (f *NATSFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
Fingerprint performs NATS detection by parsing the response (JSON or HTML).
func (*NATSFingerprinter) Match ¶
func (f *NATSFingerprinter) Match(resp *http.Response) bool
Match returns true if the response might be from NATS (JSON or HTML content type).
func (*NATSFingerprinter) Name ¶
func (f *NATSFingerprinter) Name() string
func (*NATSFingerprinter) ProbeEndpoint ¶
func (f *NATSFingerprinter) ProbeEndpoint() string
ProbeEndpoint returns the endpoint needed for NATS detection. NATS exposes monitoring info at /varz endpoint.
type PineconeFingerprinter ¶
type PineconeFingerprinter struct{}
PineconeFingerprinter detects Pinecone Vector Database instances via header-based detection.
Detection Strategy: Pinecone is a managed vector database (SaaS) that runs on HTTPS. When an unauthenticated request is sent to a Pinecone endpoint, the service returns a 401 Unauthorized response with Pinecone-specific headers:
- X-Pinecone-Api-Version (PRIMARY marker - unique to Pinecone)
- X-Pinecone-Auth-Rejected-Reason (SECONDARY marker)
Version Detection: The X-Pinecone-Api-Version header contains the API version (e.g., "2025-01"), not the internal Pinecone service version. Since Pinecone is closed-source SaaS, the internal version cannot be determined. Therefore, the CPE uses a wildcard version.
func (*PineconeFingerprinter) Fingerprint ¶
func (f *PineconeFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
Fingerprint performs detection by checking for Pinecone-specific headers.
Detection Phases:
- PRIMARY: Check for X-Pinecone-Api-Version header (unique to Pinecone)
- SECONDARY: Check for X-Pinecone-Auth-Rejected-Reason header (fallback)
Returns:
- *FingerprintResult with Pinecone detection if headers present
- nil if not detected
- error is always nil (no parsing errors possible for header-based detection)
func (*PineconeFingerprinter) Match ¶
func (f *PineconeFingerprinter) Match(resp *http.Response) bool
Match returns true for ALL responses. We need to check headers regardless of content type since detection is header-based.
func (*PineconeFingerprinter) Name ¶
func (f *PineconeFingerprinter) Name() string
type PrometheusFingerprinter ¶
type PrometheusFingerprinter struct{}
PrometheusFingerprinter detects Prometheus instances via /api/v1/status/buildinfo endpoint
func (*PrometheusFingerprinter) Fingerprint ¶
func (f *PrometheusFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*PrometheusFingerprinter) Match ¶
func (f *PrometheusFingerprinter) Match(resp *http.Response) bool
func (*PrometheusFingerprinter) Name ¶
func (f *PrometheusFingerprinter) Name() string
func (*PrometheusFingerprinter) ProbeEndpoint ¶
func (f *PrometheusFingerprinter) ProbeEndpoint() string
type QNAPFingerprinter ¶
type QNAPFingerprinter struct{}
QNAPFingerprinter detects QNAP NAS devices via authLogin.cgi endpoint
func (*QNAPFingerprinter) Fingerprint ¶
func (f *QNAPFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*QNAPFingerprinter) Name ¶
func (f *QNAPFingerprinter) Name() string
func (*QNAPFingerprinter) ProbeEndpoint ¶
func (f *QNAPFingerprinter) ProbeEndpoint() string
type SOAPFingerprinter ¶
type SOAPFingerprinter struct{}
SOAPFingerprinter detects SOAP API services via envelope namespaces and WSDL
func (*SOAPFingerprinter) Fingerprint ¶
func (f *SOAPFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*SOAPFingerprinter) Name ¶
func (f *SOAPFingerprinter) Name() string
func (*SOAPFingerprinter) ProbeEndpoint ¶
func (f *SOAPFingerprinter) ProbeEndpoint() string
type TeamCityFingerprinter ¶
type TeamCityFingerprinter struct{}
TeamCityFingerprinter detects JetBrains TeamCity instances via /app/rest/server endpoint
func (*TeamCityFingerprinter) Fingerprint ¶
func (f *TeamCityFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*TeamCityFingerprinter) Match ¶
func (f *TeamCityFingerprinter) Match(resp *http.Response) bool
func (*TeamCityFingerprinter) Name ¶
func (f *TeamCityFingerprinter) Name() string
func (*TeamCityFingerprinter) ProbeEndpoint ¶
func (f *TeamCityFingerprinter) ProbeEndpoint() string
type UPnPFingerprinter ¶
type UPnPFingerprinter struct{}
UPnPFingerprinter detects UPnP services via HTTP response headers and body content
func (*UPnPFingerprinter) Fingerprint ¶
func (f *UPnPFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*UPnPFingerprinter) Name ¶
func (f *UPnPFingerprinter) Name() string
type VaultFingerprinter ¶
type VaultFingerprinter struct{}
VaultFingerprinter detects HashiCorp Vault instances via /v1/sys/health endpoint
func (*VaultFingerprinter) Fingerprint ¶
func (f *VaultFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*VaultFingerprinter) Name ¶
func (f *VaultFingerprinter) Name() string
func (*VaultFingerprinter) ProbeEndpoint ¶
func (f *VaultFingerprinter) ProbeEndpoint() string
type WinRMFingerprinter ¶
type WinRMFingerprinter struct{}
WinRMFingerprinter detects WinRM instances via Microsoft-HTTPAPI header on /wsman endpoint
func (*WinRMFingerprinter) Fingerprint ¶
func (f *WinRMFingerprinter) Fingerprint(resp *http.Response, body []byte) (*FingerprintResult, error)
func (*WinRMFingerprinter) Name ¶
func (f *WinRMFingerprinter) Name() string
func (*WinRMFingerprinter) ProbeEndpoint ¶
func (f *WinRMFingerprinter) ProbeEndpoint() string