package binary import ( "fmt" "github.com/anchore/packageurl-go" "github.com/anchore/syft/syft/cpe" "github.com/anchore/syft/syft/pkg/cataloger/internal/binutils" ) // in both binaries and shared libraries, the version pattern is [NUL]3.11.2[NUL] var pythonVersionTemplate = `(?m)\x00(?P{{ .version }}[-._a-zA-Z0-9]*)\x00` //nolint:funlen func DefaultClassifiers() []binutils.Classifier { m := binutils.ContextualEvidenceMatchers{CatalogerName: catalogerName} var libpythonMatcher = m.FileNameTemplateVersionMatcher( `(?:.*/|^)libpython(?P[0-9]+(?:\.[0-9]+)+)[a-z]?\.so.*$`, pythonVersionTemplate, ) var rubyMatcher = m.FileContentsVersionMatcher( // ruby 3.4.0dev (2024-09-15T01:06:11Z master 532af89e3b) [x86_64-linux] // ruby 3.4.0preview1 (2024-05-16 master 9d69619623) [x86_64-linux] // ruby 3.3.0rc1 (2023-12-11 master a49643340e) [x86_64-linux] // ruby 3.2.1 (2023-02-08 revision 31819e82c8) [x86_64-linux] // ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5) [x86_64-linux] `(?m)ruby (?P[0-9]+\.[0-9]+\.[0-9]+((p|preview|rc|dev)[0-9]*)?) `) // all Elastic Beats (filebeat, metricbeat, heartbeat, packetbeat, auditbeat) var elasticBeatsMatcher = binutils.MatchAny( // 9.x: forcestdinsetupTest 9.4.2%s %w (filebeat/metricbeat/auditbeat) // forcestdinsetupTest 9.4.2input (heartbeat/packetbeat) m.FileContentsVersionMatcher(`Test (?P[0-9]+\.[0-9]+\.[0-9]+)[a-z%]`), // 9.x: exportconfigcreateplugin9.4.2-globalclient // 8.18.x: exportconfigcreateplugin8.18.4globalclient m.FileContentsVersionMatcher(`plugin(?:output)?(?P[0-9]+\.[0-9]+\.[0-9]+)[-a-z]`), // 8.11.x: 5m.rate8.11.2-9765625 m.FileContentsVersionMatcher(`5m\.rate(?P[0-9]+\.[0-9]+\.[0-9]+)-`), ) classifiers := []binutils.Classifier{ { Class: "python-binary", FileGlob: "**/python*", EvidenceMatcher: binutils.MatchAny( // try to find version information from libpython shared libraries binutils.SharedLibraryLookup( `^libpython[0-9]+(?:\.[0-9]+)+[a-z]?\.so.*$`, libpythonMatcher), // check for version information in the binary m.FileNameTemplateVersionMatcher( `(?:.*/|^)python(?P[0-9]+(?:\.[0-9]+)+)$`, pythonVersionTemplate), ), Package: "python", PURL: mustPURL("pkg:generic/python@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { Class: "python-binary-lib", FileGlob: "**/libpython*.so*", EvidenceMatcher: libpythonMatcher, Package: "python", PURL: mustPURL("pkg:generic/python@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { Class: "pypy-binary-lib", FileGlob: "**/libpypy*.so*", EvidenceMatcher: m.FileContentsVersionMatcher( `(?m)\[PyPy (?P[0-9]+\.[0-9]+\.[0-9]+)`), Package: "pypy", PURL: mustPURL("pkg:generic/pypy@version"), }, { Class: "go-binary", FileGlob: "**/{go,go.exe}", EvidenceMatcher: binutils.MatchAny( m.FileContentsVersionMatcher( `(?m)go(?P[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+)?)\x00`), binutils.SupportingEvidenceMatcher("VERSION*", m.FileContentsVersionMatcher( `(?m)go(?P[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+|-[_0-9a-z]+)?)`)), binutils.SupportingEvidenceMatcher("../VERSION*", m.FileContentsVersionMatcher( `(?m)go(?P[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+|-[_0-9a-z]+)?)`)), ), Package: "go", PURL: mustPURL("pkg:generic/go@version"), CPEs: singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "julia-binary", FileGlob: "**/libjulia-internal.so", EvidenceMatcher: binutils.MatchAny( // �1.13.0-beta3[NUL]branch // [NUL]GIT_VERSION_INFO[NUL]jl_image_unpack[NUL]1.13.0-alpha2[NUL]branch // [NUL]GIT_VERSION_INFO[NUL]__init__[NUL]1.12.6[NUL]branch[NUL]commit // [NUL]GIT_VERSION_INFO[NUL]__init__[NUL]verify_methods[NUL]1.11.9[NUL]branch[NUL]commit // [NUL][NUL]__init__[NUL]1.10.11[NUL]verify_methods[NUL] m.FileContentsVersionMatcher(`\x00__init__\x00(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00(branch|verify_methods)`), m.FileContentsVersionMatcher(`(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00branch\x00`), // [NUL]verify_methods[NUL]Task cannot be serialized[NUL]1.9.0-alpha1[NUL]BigInt[NUL] m.FileContentsVersionMatcher(`\x00verify_methods\x00.{0,30}(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00BigInt`), // unknown option `%s`[NUL]1.8.5[NUL]julia version %s m.FileContentsVersionMatcher(`\x00(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00julia version`), ), Package: "julia", PURL: mustPURL("pkg:generic/julia@version"), CPEs: singleCPE("cpe:2.3:a:julialang:julia:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "julia-binary", FileGlob: "**/julia", EvidenceMatcher: binutils.SharedLibraryLookup( // libjulia.so.1 // libjulia.so.0.6 // libjulia.so `^libjulia\.so(\.[0-9])?(\.[0-9])?$`, binutils.MatchAny( // unknown option `%s`[NUL]1.5.4[NUL]julia version %s m.FileContentsVersionMatcher(`\x00(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00julia version`), // [NUL]#kw#[NUL]1.3.1[NUL]BigInt // [NUL]#kw#[NUL]0.7.0-beta2[NUL]_require_dependencies m.FileContentsVersionMatcher(`\x00#kw#\x00(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00(BigInt|_require_dependencies)`), // [NUL]ObjectIdDict[NUL]0.6.4[NUL]jl_sysimg_cpu_target m.FileContentsVersionMatcher(`\x00ObjectIdDict\x00(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00jl_sysimg_cpu_target`), // [NUL]require[NUL]0.4.6[NUL]core2 m.FileContentsVersionMatcher(`\x00require\x00(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00core2`), ), ), Package: "julia", PURL: mustPURL("pkg:generic/julia@version"), CPEs: singleCPE("cpe:2.3:a:julialang:julia:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "helm", FileGlob: "**/helm", EvidenceMatcher: binutils.MatchAny( // [NUL]v1.21.2[NUL].......[NUL][NUL]v4.1.4[NUL][NUL][NUL] // [NUL]v2.0.0-beta.2[NUL][NUL][NUL] m.FileContentsVersionMatcher(`\x00v(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]|-beta\.[0-9]|-rc\.[0-9])?)\x00{2,}`), // [NUK]'[DLE]v3.12.0[NUL][NUL]...go1.20.3[NUL][NUL] m.FileContentsVersionMatcher(`v(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]|-beta\.[0-9]|-rc\.[0-9])?)\x00+.{1,500}go[0-9]+\.[0-9]+\.[0-9]+\x00+`), // [NUL]v3.11.1[NUL]�[NUL] m.FileContentsVersionMatcher(`\x00v(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]|-beta\.[0-9]|-rc\.[0-9])?)\x00`), // [NUL]@�@v3.15.2[NUL][NUL] m.FileContentsVersionMatcher(`@v(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]|-beta\.[0-9]|-rc\.[0-9])?)\x00`), ), Package: "helm", PURL: mustPURL("pkg:golang/helm.sh/helm@version"), CPEs: singleCPE("cpe:2.3:a:helm:helm:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "redis-binary", FileGlob: "**/redis-server", EvidenceMatcher: binutils.MatchAll( // Negative Matchers to exclude valkey-server binutils.MatchNone( binutils.MatchPath("**/valkey-server"), ), binutils.MatchAny( // matches most recent versions of redis (~v7), e.g. "7.0.14buildkitsandbox-1702957741000000000" m.FileContentsVersionMatcher(`[^\d](?P\d+.\d+\.\d+)buildkitsandbox-\d+`), // matches against older versions of redis (~v3 - v6), e.g. "4.0.11841ce7054bd9-1542359302000000000" m.FileContentsVersionMatcher(`[^\d](?P[0-9]+\.[0-9]+\.[0-9]+)\w{12}-\d+`), // matches against older versions of redis (~v2), e.g. "Server started, Redis version 2.8.23" m.FileContentsVersionMatcher(`Redis version (?P[0-9]+\.[0-9]+\.[0-9]+)`), ), ), Package: "redis", PURL: mustPURL("pkg:generic/redis@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:redislabs:redis:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:redis:redis:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { Class: "valkey-binary", FileGlob: "**/valkey-server", EvidenceMatcher: m.FileContentsVersionMatcher( // valkey9.0.0buildkitsandbox-1764887574000000000 `[^\d](?P\d+.\d+\.\d+)buildkitsandbox-\d+`), Package: "valkey", PURL: mustPURL("pkg:generic/valkey@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:lfprojects:valkey:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:linuxfoundation:valkey:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:valkey-io:valkey:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { Class: "nodejs-binary", FileGlob: "**/node", EvidenceMatcher: binutils.MatchAny( // [NUL]node v0.10.48[NUL] // [NUL]v0.12.18[NUL] // [NUL]v4.9.1[NUL] // node.js/v22.9.0 m.FileContentsVersionMatcher(`(?m)\x00(node )?v(?P(0|4|5|6)\.[0-9]+\.[0-9]+)\x00`), m.FileContentsVersionMatcher(`(?m)node\.js\/v(?P[0-9]+\.[0-9]+\.[0-9]+)`), ), Package: "node", PURL: mustPURL("pkg:generic/node@version"), CPEs: singleCPE("cpe:2.3:a:nodejs:node.js:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "busybox-binary", FileGlob: "**/busybox", EvidenceMatcher: m.FileContentsVersionMatcher( `(?m)BusyBox\s+v(?P[0-9]+\.[0-9]+\.[0-9]+)`), Package: "busybox", PURL: mustPURL("pkg:generic/busybox@version"), CPEs: singleCPE("cpe:2.3:a:busybox:busybox:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "util-linux-binary", FileGlob: "**/getopt", EvidenceMatcher: m.FileContentsVersionMatcher( `\x00util-linux\s(?P[0-9]+\.[0-9]+\.[0-9]+)\x00`), Package: "util-linux", PURL: mustPURL("pkg:generic/util-linux@version"), CPEs: singleCPE("cpe:2.3:a:kernel:util-linux:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "haproxy-binary", FileGlob: "**/haproxy", EvidenceMatcher: binutils.MatchAny( m.FileContentsVersionMatcher(`(?m)version (?P[0-9]+\.[0-9]+(\.|-dev|-rc)[0-9]+)(-[a-z0-9]{7})?, released 20`), m.FileContentsVersionMatcher(`(?m)HA-Proxy version (?P[0-9]+\.[0-9]+(\.|-dev)[0-9]+)`), m.FileContentsVersionMatcher(`(?m)(?P[0-9]+\.[0-9]+(\.|-dev)[0-9]+)-[0-9a-zA-Z]{7}.+HAProxy version`), ), Package: "haproxy", PURL: mustPURL("pkg:generic/haproxy@version"), CPEs: singleCPE("cpe:2.3:a:haproxy:haproxy:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "perl-binary", FileGlob: "**/perl", EvidenceMatcher: m.FileContentsVersionMatcher( `(?m)\/usr\/local\/lib\/perl\d\/(?P[0-9]+\.[0-9]+\.[0-9]+)`), Package: "perl", PURL: mustPURL("pkg:generic/perl@version"), CPEs: singleCPE("cpe:2.3:a:perl:perl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "php-composer-binary", FileGlob: "**/composer*", EvidenceMatcher: m.FileContentsVersionMatcher( `(?m)'pretty_version'\s*=>\s*'(?P[0-9]+\.[0-9]+\.[0-9]+(beta[0-9]+|alpha[0-9]+|RC[0-9]+)?)'`), Package: "composer", PURL: mustPURL("pkg:generic/composer@version"), CPEs: singleCPE("cpe:2.3:a:getcomposer:composer:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "httpd-binary", FileGlob: "**/httpd", EvidenceMatcher: m.FileContentsVersionMatcher( `(?m)Apache\/(?P[0-9]+\.[0-9]+\.[0-9]+)`), Package: "httpd", PURL: mustPURL("pkg:generic/httpd@version"), CPEs: singleCPE("cpe:2.3:a:apache:http_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "memcached-binary", FileGlob: "**/memcached", EvidenceMatcher: m.FileContentsVersionMatcher( `(?m)memcached\s(?P[0-9]+\.[0-9]+\.[0-9]+)`), Package: "memcached", PURL: mustPURL("pkg:generic/memcached@version"), CPEs: singleCPE("cpe:2.3:a:memcached:memcached:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "traefik-binary", FileGlob: "**/traefik", EvidenceMatcher: m.FileContentsVersionMatcher( // [NUL]v1.7.34[NUL] // [NUL]2.9.6[NUL] // 3.0.4[NUL] `(?m)(\x00v?|\x{FFFD}.?)(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00`), Package: "traefik", PURL: mustPURL("pkg:generic/traefik@version"), CPEs: singleCPE("cpe:2.3:a:traefik:traefik:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "arangodb-binary", FileGlob: "**/arangosh", EvidenceMatcher: m.FileContentsVersionMatcher( `(?m)\x00*(?P[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+)?)\s(enterprise\s)?\[linux\]`), Package: "arangodb", PURL: mustPURL("pkg:generic/arangodb@version"), CPEs: singleCPE("cpe:2.3:a:arangodb:arangodb:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "postgresql-binary", FileGlob: "**/postgres", EvidenceMatcher: m.FileContentsVersionMatcher( // [NUL]PostgreSQL 15beta4 // [NUL]PostgreSQL 15.1 // [NUL]PostgreSQL 9.6.24 // ?PostgreSQL 9.5alpha1 `(?m)(\x00|\?)PostgreSQL (?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`), Package: "postgresql", PURL: mustPURL("pkg:generic/postgresql@version"), CPEs: singleCPE("cpe:2.3:a:postgresql:postgresql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "mysql-binary", FileGlob: "**/mysql", EvidenceMatcher: binutils.MatchAny( // shutdown[NUL]8.0.37[NUL][NUL][NUL][NUL][NUL]mysql_real_esc m.FileContentsVersionMatcher(`\x00(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)\x00+mysql`), // /export/home/pb2/build/sb_0-26781090-1516292385.58/release/mysql-8.0.4-rc/mysys_ssl/my_default.cc m.FileContentsVersionMatcher(`(?m).*/mysql-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`), ), Package: "mysql", PURL: mustPURL("pkg:generic/mysql@version"), CPEs: singleCPE("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "mysql-binary", FileGlob: "**/mysql", EvidenceMatcher: m.FileContentsVersionMatcher( `(?m).*/percona-server-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`), Package: "percona-server", PURL: mustPURL("pkg:generic/percona-server@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { Class: "mysql-binary", FileGlob: "**/mysql", EvidenceMatcher: m.FileContentsVersionMatcher( `(?m).*/Percona-XtraDB-Cluster-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`), Package: "percona-xtradb-cluster", PURL: mustPURL("pkg:generic/percona-xtradb-cluster@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:percona:xtradb_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { // Legacy MySQL Cluster contains both MySQL Server and MySQL Cluster versions (Example: 5.7.33-ndb-7.5.21) // This classifier identifies the MySQL Server version of the mysqld binary (5.7.33 in the example above). Class: "mysqld-mysql-cluster-legacy-binary", FileGlob: "**/mysqld", EvidenceMatcher: m.FileContentsVersionMatcher( `cluster-gpl\x00(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?)\-ndb\-[0-9]+(\.[0-9]+)?(\.[0-9]+)?`), Package: "mysql-server", PURL: mustPURL("pkg:generic/mysql-server@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:oracle:mysql_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { Class: "mysqld-binary", FileGlob: "**/mysqld", EvidenceMatcher: binutils.BranchingEvidenceMatcher([]binutils.Classifier{ { // Legacy MySQL Cluster contains both MySQL Server and MySQL Cluster versions (Example: 5.7.33-ndb-7.5.21) // This classifier identifies the MySQL Cluster version of the mysqld binary (7.5.21 in the example above). Class: "mysqld-mysql-cluster-legacy-binary", EvidenceMatcher: m.FileContentsVersionMatcher( `cluster-gpl\x00[0-9]+(\.[0-9]+)?(\.[0-9]+)?\-ndb\-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?)`), Package: "mysql-cluster", PURL: mustPURL("pkg:generic/mysql-cluster@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:oracle:mysql_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { // mysqld from MySQL Cluster after versioning was aligned with MySQL Server Class: "mysqld-mysql-cluster-binary", EvidenceMatcher: m.FileContentsVersionMatcher( `/mysql-cluster-gpl-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)/`), Package: "mysql-cluster", PURL: mustPURL("pkg:generic/mysql-cluster@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:oracle:mysql_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:oracle:mysql_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { // mysqld from MySQL Server Class: "mysqld-mysql-server-binary", EvidenceMatcher: m.FileContentsVersionMatcher( `/mysql-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)/`), Package: "mysql-server", PURL: mustPURL("pkg:generic/mysql-server@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:oracle:mysql_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, }...), }, { Class: "ndbd-binary", FileGlob: "**/ndbd", EvidenceMatcher: m.FileContentsVersionMatcher( `/mysql-cluster-gpl-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)/`), Package: "mysql-cluster", PURL: mustPURL("pkg:generic/mysql-cluster@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:oracle:mysql_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { Class: "ndbmtd-binary", FileGlob: "**/ndbmtd", EvidenceMatcher: m.FileContentsVersionMatcher( `/mysql-cluster-gpl-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)/`), Package: "mysql-cluster", PURL: mustPURL("pkg:generic/mysql-cluster@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:oracle:mysql_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { Class: "ndb_mgmd-binary", FileGlob: "**/ndb_mgmd", EvidenceMatcher: m.FileContentsVersionMatcher( `/mysql-cluster-gpl-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)/`), Package: "mysql-cluster", PURL: mustPURL("pkg:generic/mysql-cluster@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:oracle:mysql_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { Class: "xtrabackup-binary", FileGlob: "**/xtrabackup", EvidenceMatcher: m.FileContentsVersionMatcher( `(?m).*/percona-xtrabackup-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`), Package: "percona-xtrabackup", PURL: mustPURL("pkg:generic/percona-xtrabackup@version"), CPEs: singleCPE("cpe:2.3:a:percona:xtrabackup:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "mariadb-binary", FileGlob: "**/{mariadb,mysql}", EvidenceMatcher: binutils.MatchAny( // 10.6.15-MariaDB m.FileContentsVersionMatcher(`(?m)(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)-MariaDB`), // MariaDB.org / RHEL tarball builds embed the release directory name, which does not contain the // "-MariaDB" marker. The version is in the build path instead, e.g.: // mariadb-11.8.5-2-redhat-x86_64/rhel-8/bin/mariadb // mariadb-11.8.5-linux-systemd-x86_64 // Without this the older matcher misses the version and a later release suffix (e.g. "2") can be // picked up instead, producing false-positive matches against ancient CVEs (see anchore/grype#3452). m.FileContentsVersionMatcher(`(?m)(?:^|/)mariadb-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)-`), ), Package: "mariadb", PURL: mustPURL("pkg:generic/mariadb@version"), CPEs: singleCPE("cpe:2.3:a:mariadb:mariadb:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "rust-standard-library-linux", FileGlob: "**/libstd-????????????????.so", EvidenceMatcher: m.FileContentsVersionMatcher( // clang LLVM (rustc version 1.48.0 (7eac88abb 2020-11-16)) `(?m)(\x00)clang LLVM \(rustc version (?P[0-9]+(\.[0-9]+)?(\.[0-9]+)) \(\w+ \d{4}\-\d{2}\-\d{2}\)`), Package: "rust", PURL: mustPURL("pkg:generic/rust@version"), CPEs: singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "rust-standard-library-macos", FileGlob: "**/libstd-????????????????.dylib", EvidenceMatcher: m.FileContentsVersionMatcher( // c 1.48.0 (7eac88abb 2020-11-16) `(?m)c (?P[0-9]+(\.[0-9]+)?(\.[0-9]+)) \(\w+ \d{4}\-\d{2}\-\d{2}\)`), Package: "rust", PURL: mustPURL("pkg:generic/rust@version"), CPEs: singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "ruby-binary", FileGlob: "**/ruby", EvidenceMatcher: binutils.MatchAny( rubyMatcher, binutils.SharedLibraryLookup( // try to find version information from libruby shared libraries `^libruby\.so.*$`, rubyMatcher), ), Package: "ruby", PURL: mustPURL("pkg:generic/ruby@version"), CPEs: singleCPE("cpe:2.3:a:ruby-lang:ruby:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "erlang-binary", FileGlob: "**/erlexec", EvidenceMatcher: binutils.MatchAny( m.FileContentsVersionMatcher( // [NUL]/usr/src/otp_src_25.3.2.6/erts/ `(?m)/src/otp_src_(?P[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`, ), m.FileContentsVersionMatcher( // [NUL]/usr/local/src/otp-25.3.2.7/erts/ `(?m)/usr/local/src/otp-(?P[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`, ), ), Package: "erlang", PURL: mustPURL("pkg:generic/erlang@version"), CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "erlang-alpine-binary", FileGlob: "**/beam.smp", EvidenceMatcher: binutils.MatchAny( m.FileContentsVersionMatcher( // [NUL]/usr/src/otp_src_25.3.2.6/erts/ `(?m)/src/otp_src_(?P[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`, ), m.FileContentsVersionMatcher( // [NUL]/usr/local/src/otp-25.3.2.7/erts/ `(?m)/usr/local/src/otp-(?P[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`, ), m.FileContentsVersionMatcher( // [NUL][NUL]26.1.2[NUL][NUL][NUL][NUL][NUL][NUL][NUL]NUL[NUL][NUL]Erlang/OTP `\x00+(?P[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)\x00+Erlang/OTP`, ), m.FileContentsVersionMatcher( // Erlang/OTP 17%s [erts-6.4.1.6] [source] [64-bit] [smp:%beu:%beu] [async-threads:%d] [hipe] [kernel-poll:%s][NUL]17.5.6.9[NUL][NUL][NUL] `(?s)Erlang/OTP.{1,150}\x00+(?P[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)\x00+`, ), ), Package: "erlang", PURL: mustPURL("pkg:generic/erlang@version"), CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "erlang-library", FileGlob: "**/liberts_internal.a", EvidenceMatcher: binutils.MatchAny( m.FileContentsVersionMatcher( // [NUL]/usr/src/otp_src_25.3.2.6/erts/ `(?m)/src/otp_src_(?P[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`, ), m.FileContentsVersionMatcher( // [NUL]/usr/local/src/otp-25.3.2.7/erts/ `(?m)/usr/local/src/otp-(?P[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`, ), ), Package: "erlang", PURL: mustPURL("pkg:generic/erlang@version"), CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "swipl-binary", FileGlob: "**/swipl", EvidenceMatcher: m.FileContentsVersionMatcher( `(?m)swipl-(?P[0-9]+\.[0-9]+\.[0-9]+)\/`, ), Package: "swipl", PURL: mustPURL("pkg:generic/swipl@version"), CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "dart-binary", FileGlob: "**/dart", EvidenceMatcher: m.FileContentsVersionMatcher( // MathAtan[NUL]2.12.4 (stable) // "%s"[NUL]3.0.0 (stable) // Dart,GC"[NUL]3.5.2 (stable) // Dart,GC"[NUL]3.6.0-216.1.beta (beta) `(?m)\x00(?P[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+(\.[0-9]+)?\.beta)?) `, ), Package: "dart", PURL: mustPURL("pkg:generic/dart@version"), CPEs: singleCPE("cpe:2.3:a:dart:dart_software_development_kit:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "deno-binary", FileGlob: "**/deno", EvidenceMatcher: binutils.MatchAny( m.FileContentsVersionMatcher( // Deno/2.6.3 // Deno/1.41.0 `Deno/(?P[0-9]+\.[0-9]+\.[0-9]+)`, ), m.FileContentsVersionMatcher( // deno::tools::standalonedeno-65db94feba9d4d51a09b74629f566dbc90484fbarelease/v1.29.4windows // cli/tools/standalone.rsdeno-74064c9d8c222b33b2a552ea0af1054f57002a96release/v1.28.3windows `deno-[0-9a-z]{40}release/v(?P[0-9]+\.[0-9]+\.[0-9]+)`, ), m.FileContentsVersionMatcher( // cli/tools/standalone.rsdeno-ab286750a8c87215a9651efb11fcc620f29140051.16.4release/vdlwindows `deno-[0-9a-z]{40}(?P[0-9]+\.[0-9]+\.[0-9]+)`, ), m.FileContentsVersionMatcher( // 1.10.31567c1013cc8ff12cf039137792da66a1d0015b5DENO_UNSTABLE_COVERAGE_DIRNo current directorycli/main `(?P[0-9]+\.[0-9]+\.[0-9]+)[0-9a-z]{40}DENO`, ), ), Package: "deno", PURL: mustPURL("pkg:generic/deno@version"), CPEs: singleCPE("cpe:2.3:a:deno:deno:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "haskell-ghc-binary", FileGlob: "**/ghc*", EvidenceMatcher: binutils.MatchAny( m.FileContentsVersionMatcher( `(?m)\x00GHC (?P[0-9]+\.[0-9]+\.[0-9]+)\x00`, ), m.FileContentsVersionMatcher( // [NUL]libHSghc-7.10.3-0AG9TOjDEtx4Ji3wSwHOBe-ghc7.10.3.so[NUL] // [NUL]libHSghc-8.10.4-ghc8.10.4.so[NUL] `\x00libHSghc\-(?P[0-9]+\.[0-9]+\.[0-9]+)\-([a-zA-Z0-9]+\-)?ghc[0-9]+\.[0-9]+\.[0-9]+\.so\x00`, ), ), Package: "haskell/ghc", PURL: mustPURL("pkg:generic/haskell/ghc@version"), CPEs: singleCPE("cpe:2.3:a:haskell:ghc:*:*:*:*:*:*:*:*"), }, { Class: "haskell-cabal-binary", FileGlob: "**/cabal", EvidenceMatcher: binutils.MatchAny( m.FileContentsVersionMatcher( `(?m)\x00Cabal-(?P[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)-`, ), m.FileContentsVersionMatcher( // [NUL][NUL][NUL]/opt/cabal/1.22/lib/x86_64-linux-ghc-7.10.2/cabal-install-1.22.6.0-AfxbHivcmw40BMGrAXG3jJ[NUL][NUL][NUL] `\x00.{0,50}cabal\-install\-(?P[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)\-[a-zA-Z0-9]+\x00+`, ), ), Package: "haskell/cabal", PURL: mustPURL("pkg:generic/haskell/cabal@version"), CPEs: singleCPE("cpe:2.3:a:haskell:cabal:*:*:*:*:*:*:*:*"), }, { Class: "haskell-stack-binary", FileGlob: "**/stack", EvidenceMatcher: m.FileContentsVersionMatcher( `(?m)Version\s*(?P[0-9]+\.[0-9]+\.[0-9]+),\s*Git`, ), Package: "haskell/stack", PURL: mustPURL("pkg:generic/haskell/stack@version"), CPEs: singleCPE("cpe:2.3:a:haskell:stack:*:*:*:*:*:*:*:*"), }, { Class: "consul-binary", FileGlob: "**/consul", EvidenceMatcher: binutils.MatchAny( m.FileContentsVersionMatcher( // NOTE: This is brittle and may not work for past or future versions `CONSUL_VERSION: (?P\d+\.\d+\.\d+)`, ), m.FileContentsVersionMatcher( // GitDescribe=1.12.9" `GitDescribe=(?P\d+\.\d+\.\d+)\"`, ), m.FileContentsVersionMatcher( // [NUL][NUL][NUL]v1.7.14[NUL][NUL][NUL] `\x00+v(?P\d+\.\d+\.\d+)\x00+`, ), ), Package: "consul", PURL: mustPURL("pkg:golang/github.com/hashicorp/consul@version"), CPEs: singleCPE("cpe:2.3:a:hashicorp:consul:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "hashicorp-vault-binary", FileGlob: "**/vault", EvidenceMatcher: binutils.MatchAny( m.FileContentsVersionMatcher( // revoke1.18.0 `(?m)revoke(?P[0-9]+\.[0-9]+\.[0-9]+)`, ), m.FileContentsVersionMatcher( // secondsindex_state1.20.0-rc1 `state(?P[0-9]+\.[0-9]+\.[0-9]+\-rc[0-9])`, ), m.FileContentsVersionMatcher( // %s0.0.0.00x%016x1.14.101.49.22123-abc19531252.5.4.32.5.4.52.5.4.62.5.4.72.5.4.82.5.4.92 // %s0.0.0.00x%016x1.14.3 // txn0.0.0.00x%016x1.13.13123-abc19531252.5.4.32.5.4.52.5.4.62.5.4.72.5.4.82.5.4.92006-019765625: type ::1/128::ffff::method: `016x(?P1.1[1,3,4].[0-9]{1,2})`, ), m.FileContentsVersionMatcher( // [NUL][NUL][NUL]1.11.6[NUL][NUL][NUL] `\x00+(?P1\.[0-9][0,1]?\.[0-9]+)\x00+`, ), ), Package: "github.com/hashicorp/vault", PURL: mustPURL("pkg:golang/github.com/hashicorp/vault@version"), CPEs: singleCPE("cpe:2.3:a:hashicorp:vault:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "nginx-binary", FileGlob: "**/nginx", EvidenceMatcher: m.FileContentsVersionMatcher( // [NUL]nginx version: nginx/1.25.1 - fetches '1.25.1' // [NUL]nginx version: openresty/1.21.4.1 - fetches '1.21.4' as this is the nginx version part `(?m)(\x00|\?)nginx version: [^\/]+\/(?P[0-9]+\.[0-9]+\.[0-9]+(?:\+\d+)?(?:-\d+)?)`, ), Package: "nginx", PURL: mustPURL("pkg:generic/nginx@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:f5:nginx:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:nginx:nginx:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { Class: "bash-binary", FileGlob: "**/bash", EvidenceMatcher: m.FileContentsVersionMatcher( // @(#)Bash version 5.2.15(1) release GNU // @(#)Bash version 5.2.0(1) alpha GNU // @(#)Bash version 5.2.0(1) beta GNU // @(#)Bash version 5.2.0(1) rc4 GNU `(?m)@\(#\)Bash version (?P[0-9]+\.[0-9]+\.[0-9]+)\([0-9]\) [a-z0-9]+ GNU`, ), Package: "bash", PURL: mustPURL("pkg:generic/bash@version"), CPEs: singleCPE("cpe:2.3:a:gnu:bash:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "openssl-binary", FileGlob: "**/openssl", EvidenceMatcher: binutils.BranchingEvidenceMatcher([]binutils.Classifier{ { Class: "openssl-binary-aws-lc", EvidenceMatcher: m.FileContentsVersionMatcher( // [NUL]OpenSSL 1.1.1 (compatible; AWS-LC 1.69.0)[NUL] `AWS-LC (?P[0-9]+\.[0-9]+\.[0-9]+)\)\x00`, ), Package: "aws-lc", PURL: mustPURL("pkg:generic/aws-lc@version"), CPEs: singleCPE("cpe:2.3:a:amazon:aws_libcrypto:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "openssl-binary", EvidenceMatcher: m.FileContentsVersionMatcher( // [NUL]OpenSSL 3.1.4' // [NUL]OpenSSL 1.1.1w' `\x00OpenSSL (?P[0-9]+\.[0-9]+\.[0-9]+([a-z]+|-alpha[0-9]|-beta[0-9]|-rc[0-9])?)`, ), Package: "openssl", PURL: mustPURL("pkg:generic/openssl@version"), CPEs: singleCPE("cpe:2.3:a:openssl:openssl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }...), }, { Class: "openldap-search-binary", FileGlob: "**/ldapsearch", EvidenceMatcher: m.FileContentsVersionMatcher( // $OpenLDAP: ldapsearch 2.4.45' `\$OpenLDAP:\sldapsearch\s(?P[0-9]+\.[0-9]+\.[0-9]+)`, ), Package: "openldap", PURL: mustPURL("pkg:generic/openldap@version"), CPEs: singleCPE("cpe:2.3:a:openldap:openldap:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "qt-qtbase-lib", FileGlob: "**/libQt*Core.so*", EvidenceMatcher: binutils.MatchAny( // Qt 5.x and Qt 6.x pattern [NUL][NUL]Qt 6.5.0 (x86_64-little_endian-... m.FileContentsVersionMatcher(`\x00\x00Qt (?P[0-9]+\.[0-9]+\.[0-9]+) \(`), // Qt 4.x pattern QtCore lib ver 4.8.7 m.FileContentsVersionMatcher(`QtCore library version (?P[0-9]+\.[0-9]+\.[0-9]+)`), ), Package: "qtbase", PURL: mustPURL("pkg:generic/qtbase@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:qt:qt:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:a:qt:qtbase:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { Class: "gcc-binary", FileGlob: "**/gcc", EvidenceMatcher: m.FileContentsVersionMatcher( // GCC: \(GNU\) 12.3.0' `GCC: \(GNU\) (?P[0-9]+\.[0-9]+\.[0-9]+)`, ), Package: "gcc", PURL: mustPURL("pkg:generic/gcc@version"), CPEs: singleCPE("cpe:2.3:a:gnu:gcc:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "fluent-bit-binary", FileGlob: "**/fluent-bit", EvidenceMatcher: m.FileContentsVersionMatcher( // [NUL]3.0.2[NUL]%sFluent Bit // [NUL]2.2.3[NUL]Fluent Bit // [NUL]2.2.1[NUL][NUL][NUL]Fluent Bit // [NUL]1.7.0[NUL]\x1b[1m[NUL]%sFluent Bit (versions 1.7.0-dev-3 through 1.7.0-dev-9 and 1.7.0-rc4 through 1.7.0-rc8) // [NUL][NUL]1.3.10[NUL][NUL]Fluent Bit v%s `\x00(\x00)?(?P[0-9]+\.[0-9]+\.[0-9]+)\x00(\x1b\[1m\x00|\x00|\x00\x00)?(%s)?Fluent`, ), Package: "fluent-bit", PURL: mustPURL("pkg:github/fluent/fluent-bit@version"), CPEs: singleCPE("cpe:2.3:a:treasuredata:fluent_bit:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "wordpress-cli-binary", FileGlob: "**/wp", EvidenceMatcher: m.FileContentsVersionMatcher( // wp-cli/wp-cli 2.9.0' `(?m)wp-cli/wp-cli (?P[0-9]+\.[0-9]+\.[0-9]+)`, ), Package: "wp-cli", PURL: mustPURL("pkg:generic/wp-cli@version"), CPEs: singleCPE("cpe:2.3:a:wp-cli:wp-cli:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "curl-binary", FileGlob: "**/curl", EvidenceMatcher: m.FileContentsVersionMatcher( `curl/(?P[0-9]+\.[0-9]+\.[0-9]+)`, ), Package: "curl", PURL: mustPURL("pkg:generic/curl@version"), CPEs: singleCPE("cpe:2.3:a:haxx:curl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "lighttpd-binary", FileGlob: "**/lighttpd", EvidenceMatcher: m.FileContentsVersionMatcher( `\x00lighttpd/(?P[0-9]+\.[0-9]+\.[0-9]+)\x00`, ), Package: "lighttpd", PURL: mustPURL("pkg:generic/lighttpd@version"), CPEs: singleCPE("cpe:2.3:a:lighttpd:lighttpd:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "proftpd-binary", FileGlob: "**/proftpd", EvidenceMatcher: m.FileContentsVersionMatcher( `\x00ProFTPD Version (?P[0-9]+\.[0-9]+\.[0-9]+[a-z]?)\x00`, ), Package: "proftpd", PURL: mustPURL("pkg:generic/proftpd@version"), CPEs: singleCPE("cpe:2.3:a:proftpd:proftpd:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "zstd-binary", FileGlob: "**/zstd", EvidenceMatcher: m.FileContentsVersionMatcher( `\x00v(?P[0-9]+\.[0-9]+\.[0-9]+)\x00`, ), Package: "zstd", PURL: mustPURL("pkg:generic/zstd@version"), CPEs: singleCPE("cpe:2.3:a:facebook:zstandard:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "xz-binary", FileGlob: "**/xz", EvidenceMatcher: m.FileContentsVersionMatcher( `\x00xz \(XZ Utils\) (?P[0-9]+\.[0-9]+\.[0-9]+)\x00`, ), Package: "xz", PURL: mustPURL("pkg:generic/xz@version"), CPEs: singleCPE("cpe:2.3:a:tukaani:xz:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "gzip-binary", FileGlob: "**/gzip", EvidenceMatcher: m.FileContentsVersionMatcher( `\x00(?P[0-9]+\.[0-9]+)\x00`, ), Package: "gzip", PURL: mustPURL("pkg:generic/gzip@version"), CPEs: singleCPE("cpe:2.3:a:gnu:gzip:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "sqlcipher-binary", FileGlob: "**/sqlcipher", EvidenceMatcher: m.FileContentsVersionMatcher( `[^0-9]\x00(?P[0-9]+\.[0-9]+\.[0-9]+)\x00`, ), Package: "sqlcipher", PURL: mustPURL("pkg:generic/sqlcipher@version"), CPEs: singleCPE("cpe:2.3:a:zetetic:sqlcipher:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "jq-binary", FileGlob: "**/jq", EvidenceMatcher: m.FileContentsVersionMatcher( `\x00(?P[0-9]{1,3}\.[0-9]{1,3}(\.[0-9]+)?)\x00`, ), Package: "jq", PURL: mustPURL("pkg:generic/jq@version"), CPEs: singleCPE("cpe:2.3:a:jqlang:jq:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "chrome-binary", FileGlob: "**/chrome", EvidenceMatcher: m.FileContentsVersionMatcher( // [NUL]127.0.6533.119[NUL]Default `\x00(?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\x00Default`, ), Package: "chrome", PURL: mustPURL("pkg:generic/chrome@version"), CPEs: singleCPE("cpe:2.3:a:google:chrome:*:*:*:*:*:*:*:*"), }, { Class: "firefox-binary", FileGlob: "**/{firefox,firefox.exe}", EvidenceMatcher: binutils.SupportingEvidenceMatcher( "application.ini", m.FileContentsVersionMatcher( `(?ms)^Name=Firefox\r?$.*?^Version=(?P[0-9]+(?:\.[0-9]+)+(?:[A-Za-z][0-9A-Za-z.-]*)?)\r?$`, ), ), Package: "firefox", PURL: mustPURL("pkg:generic/firefox@version"), CPEs: singleCPE("cpe:2.3:a:mozilla:firefox:*:*:*:*:*:*:*:*"), }, { Class: "ffmpeg-binary", FileGlob: "**/ffmpeg", EvidenceMatcher: m.FileContentsVersionMatcher( // Pattern found in the binary: "%s version 7.1.1" or "%s version 6.0" // When executed outputs: "ffmpeg version 7.1.1" or "ffmpeg version 6.0" `(?m)%s version (?P[0-9]+\.[0-9]+(\.[0-9]+)?)`, ), Package: "ffmpeg", PURL: mustPURL("pkg:generic/ffmpeg@version"), CPEs: singleCPE("cpe:2.3:a:ffmpeg:ffmpeg:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "ffmpeg-library", FileGlob: "**/libav*", EvidenceMatcher: binutils.MatchAny( // Primary pattern: FFmpeg version found in most libraries m.FileContentsVersionMatcher(`(?m)FFmpeg version (?P[0-9]+\.[0-9]+(\.[0-9]+)?)`), // Fallback: library-specific version patterns for libavcodec and libavformat m.FileContentsVersionMatcher(`(?m)Lavc(?P[0-9]+\.[0-9]+\.[0-9]+)`), m.FileContentsVersionMatcher(`(?m)Lavf(?P[0-9]+\.[0-9]+\.[0-9]+)`), ), Package: "ffmpeg", PURL: mustPURL("pkg:generic/ffmpeg@version"), CPEs: singleCPE("cpe:2.3:a:ffmpeg:ffmpeg:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "ffmpeg-library", FileGlob: "**/libswresample*", EvidenceMatcher: m.FileContentsVersionMatcher( // FFmpeg version pattern for libswresample `(?m)FFmpeg version (?P[0-9]+\.[0-9]+(\.[0-9]+)?)`), Package: "ffmpeg", PURL: mustPURL("pkg:generic/ffmpeg@version"), CPEs: singleCPE("cpe:2.3:a:ffmpeg:ffmpeg:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "elixir-binary", FileGlob: "**/elixir", EvidenceMatcher: m.FileContentsVersionMatcher( // Capture optional pre-release suffix (-rc.1, -alpha.0, -beta.2, // etc.) so release-candidate elixir images (#4819) match. `(?m)ELIXIR_VERSION=(?P[0-9]+\.[0-9]+\.[0-9]+(?:-[a-z0-9]+(?:\.[0-9]+)?)?)`), Package: "elixir", PURL: mustPURL("pkg:generic/elixir@version"), CPEs: []cpe.CPE{ cpe.Must("cpe:2.3:a:elixir-lang:elixir:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { Class: "elixir-library", FileGlob: "**/elixir/ebin/elixir.app", EvidenceMatcher: m.FileContentsVersionMatcher( // Same pre-release extension as elixir-binary above. `(?m)\{vsn,"(?P[0-9]+\.[0-9]+\.[0-9]+(?:-[a-z0-9]+(?:\.[0-9]+)?)?)"\}`), Package: "elixir", PURL: mustPURL("pkg:generic/elixir@version"), CPEs: singleCPE("cpe:2.3:a:elixir-lang:elixir:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "istio-binary", FileGlob: "**/pilot-discovery", EvidenceMatcher: binutils.MatchAny( // [NUL]1.26.8[NUL][NUL]1.26.8[NUL] // [NUL]1.3.7[NUL][NUL][NUL]1.3.8[NUL] m.FileContentsVersionMatcher(`[0-9]+\.[0-9]+\.[0-9]+\x00+(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]+|-beta\.[0-9]+|-rc\.[0-9]+|-dev)?)\x00+`), // Clean[NUL][NUL][NUL]1.8.0[NUL] m.FileContentsVersionMatcher(`Clean\x00+(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]+|-beta\.[0-9]+|-rc\.[0-9]+|-dev)?)\x00+`), // Modified[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]1.10-dev[NUL][NUL][NUL] m.FileContentsVersionMatcher(`Modified\x00+(?P[0-9]+\.[0-9]+-dev)\x00+`), // 1.1.17[NUL]...S=v[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]+|-beta\.[0-9]+|-rc\.[0-9]+|-dev)?)\x00+.{1,100}S?=v[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]+|-beta\.[0-9]+|-rc\.[0-9]+|-dev)?)\x00+`), // Clean[NUL][NUL][NUL]1.8.0[NUL] m.FileContentsVersionMatcher(`Clean\x00+(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]+|-beta\.[0-9]+|-rc\.[0-9]+|-dev)?)\x00+`), // Modified[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]1.10-dev[NUL][NUL][NUL] m.FileContentsVersionMatcher(`Modified\x00+(?P[0-9]+\.[0-9]+-dev)\x00+`), // 1.1.17[NUL]...S=v[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]+|-beta\.[0-9]+|-rc\.[0-9]+|-dev)?)\x00+.{1,100}S?=v[0-9]{2}\.[0-9]+\.[0-9]+\-[0-9]{6,})\x00+`), // [NUL][NUL][NUL][NUL]release-12.3.2+security-01[NUL][NUL][NUL][NUL] // [NUL][NUL][NUL][NUL]release-12.3.1[NUL][NUL][NUL][NUL] m.FileContentsVersionMatcher(`\x00+release-(?P[0-9]{2}\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+`), // [NUL][NUL][NUL][NUL]go1.21.8[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]11.0.0-preview[NUL][NUL]...+DT m.FileContentsVersionMatcher(`(?s)\x00+go1\.[0-9]+\.[0-9]+\x00+(?P[0-9]{2}\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+.{1,500}\+DT`), // HEAD[NUL][NUL][NUL][NUL]12.0.0[NUL][NUL]$a // 11.0.0[NUL][NUL]$a m.FileContentsVersionMatcher(`(?P[0-9]{2}\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+\$a`), // [NUL]0xDC0xBF10.4.19[NUL] m.FileContentsVersionMatcher(`\x00.(?P10\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00`), // 10.3.12[NUL]...[NUL]go1.22.7[NUL][NUL][NUL][NUL]...+DT m.FileContentsVersionMatcher(`(?s)(?P[0-9]{2}\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+.{1,100}\x00go1\.[0-9]+\.[0-9]+\x00.{1,100}\+DT`), // 9.5.21[NUL][NUL]v9.5.x[NUL][NUL][NUL][NUL][NUL][NUL]$a m.FileContentsVersionMatcher(`(?P[0-9]+\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+v[0-9]+\.[0-9]+\.x\x00+`), // HEAD[NUL][NUL][NUL][NUL]9.2.20[NUL][NUL][NUL][NUL] // HEAD[NUL][NUL]:[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]9.2.13[NUL][NUL][NUL][NUL] m.FileContentsVersionMatcher(`HEAD\x00+.*\x00+(?P[0-9]\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+`), // 1b0f5f0a81[NUL][NUL][NUL][NUL][NUL][NUL]9.4.0-beta1[NUL][NUL][NUL][NUL][NUL]/usr/local/go m.FileContentsVersionMatcher(`[a-z0-9]+\x00+(?P[0-9]\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+\/usr\/local\/go`), ), Package: "grafana", PURL: mustPURL("pkg:generic/grafana@version"), CPEs: singleCPE("cpe:2.3:a:grafana:grafana:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "grafana-binary", FileGlob: "**/grafana-server", EvidenceMatcher: binutils.MatchAny( // 78f0340031[NUL][NUL][NUL][NUL][NUL][NUL]9.3.0-beta1[NUL][NUL][NUL][NUL][NUL]/usr/local/go m.FileContentsVersionMatcher(`[a-z0-9]+\x00+(?P[0-9]\.[0-9]+\.[0-9]+(-beta[0-9]|-test)?)\x00+\/usr\/local\/go`), // HEAD[NUL][NUL][NUL][NUL]9.0.0[NUL]:[NUL] // HEAD[NUL][NUL][NUL][NUL]:[NUL][NUL][NUL][NUL][NUL][NUL][NUL]7.5.17[NUL][NUL][NUL][NUL] // HEAD[NUL][NUL][NUL][NUL]m[NUL]...[NUL][NUL]6.7.6[NUL][NUL][NUL].[NUL][NUL][NUL][NUL][NUL][NUL][NUL]: m.FileContentsVersionMatcher(`HEAD\x00+.*\x00+(?P[0-9]\.[0-9]+\.[0-9]+(-beta[0-9]|-test)?)\x00+`), // [NUL][NUL][NUL][NUL][NUL]6.7.0-test[NUL][NUL][NUL]...[NUL][NUL][NUL][NUL]/usr/local/go // [NUL][NUL][NUL][NUL][NUL]6.0.0-beta1[NUL][NUL][NUL]...[NUL][NUL][NUL][NUL]/usr/local/go m.FileContentsVersionMatcher(`(?s)\x00+(?P[0-9]\.[0-9]+\.[0-9]+(-beta[0-9]|-test)?)\x00+.*\x00+.{1,1000}\x00+\/u`), ), Package: "grafana", PURL: mustPURL("pkg:generic/grafana@version"), CPEs: singleCPE("cpe:2.3:a:grafana:grafana:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "envoy-binary", FileGlob: "**/envoy", EvidenceMatcher: binutils.MatchAny( // 1.3x [NUL]1.36.4[NUL]...envoy_reloadable_features // 1.34.5 [NUL]1.34.5[NUL]...envoy.reloadable_features m.FileContentsVersionMatcher(`(?s)\x00(?P1\.3[0-9]\.[0-9]+(-dev)?)\x00.{0,1000}envoy_reloadable_features`), m.FileContentsVersionMatcher(`(?s)\x00(?P1\.34\.5)\x00.{0,200}envoy\.reloadable_features`), // 1.2x envoy_quic_...[NUL]1.28.7[NUL] m.FileContentsVersionMatcher(`(?s)envoy_quic_.{0,1000}\x00(?P1\.2[0-9]\.[0-9]+(-dev)?)\x00`), // 1.2x [NUL]1.20.7[NUL]Unable to // 1.1x [NUL]1.18.6-dev[NUL]Unable to m.FileContentsVersionMatcher(`(?s)\x00(?P1\.[12][0-9]\.[0-9]+(-dev)?)\x00.{0,1000}Unable to`), // 1.2x [NUL]1.22.11[NUL]...ValidationError // 1.1x [NUL]1.14.3[NUL]...ValidationError m.FileContentsVersionMatcher(`(?s)\x00(?P1\.2[0-9]\.[0-9]+(-dev)?)\x00.{0,580}ValidationError`), m.FileContentsVersionMatcher(`(?s)\x00(?P1\.1[0-9]\.[0-9]+(-dev)?)\x00.{0,1000}ValidationError`), // 1.1x [source...[NUL]1.11.0[NUL]/ m.FileContentsVersionMatcher(`(?s)\[source/.{0,200}\x00(?P1\.1[0-9]\.[0-9]+(-dev)?)\x00`), // 1.x [NUL]1.6.0[NUL]RELEASE m.FileContentsVersionMatcher(`(?s)\x00(?P1\.[0-9]\.[0-9]+(-dev)?)\x00.{0,20}RELEASE`), // contrib 1.3x [NUL]1.34.12[NUL]envoy_quiche... or [NUL]1.30.2[NUL]envoy/extensions... or [NUL]1.30.8[NUL]envoy:// m.FileContentsVersionMatcher(`(?s)\x00(?P1\.3[0-9]\.[0-9]+(-dev)?)\x00envoy[/._:]`), // contrib 1.3x [NUL]1.30.7[NUL]...envoy.service or [NUL]1.30.6[NUL]...envoy.data m.FileContentsVersionMatcher(`(?s)\x00(?P1\.3[0-9]\.[0-9]+(-dev)?)\x00.{0,200}envoy[./]`), // contrib1.3x [NUL]1.31.2[NUL]...envoy_quic or [NUL]1.36.x[NUL]...envoy_quic m.FileContentsVersionMatcher(`(?s)\x00(?P1\.3[0-9]\.[0-9]+(-dev)?)\x00.{0,1000}envoy_quic`), // contrib 1.3x [NUL]1.30.1[NUL]TLS client m.FileContentsVersionMatcher(`(?s)\x00(?P1\.3[0-9]\.[0-9]+(-dev)?)\x00TLS `), // contrib 1.2x [NUL]1.24.9[NUL]envoy/extensions... m.FileContentsVersionMatcher(`(?s)\x00(?P1\.2[0-9]\.[0-9]+(-dev)?)\x00envoy[/._]`), // contrib 1.2x [NUL]1.22.10[NUL]...envoy. or [NUL]1.24.5[NUL]...envoy. m.FileContentsVersionMatcher(`(?s)\x00(?P1\.2[0-9]\.[0-9]+(-dev)?)\x00.{0,500}envoy\.`), // contrib 1.2x [NUL]1.23.7[NUL]...envoy_internal m.FileContentsVersionMatcher(`(?s)\x00(?P1\.2[0-9]\.[0-9]+(-dev)?)\x00.{0,300}envoy_`), ), Package: "envoy", PURL: mustPURL("pkg:generic/envoy@version"), CPEs: singleCPE("cpe:2.3:a:envoyproxy:envoy:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "mongodb-binary", FileGlob: "**/mongod", EvidenceMatcher: binutils.MatchAny( // mongodb 4.x, 5.x, 6.x: ber followed by tcmalloc // e.g 6.0.27[NUL]tcmalloc m.FileContentsVersionMatcher(`(?P[0-9]+\.[0-9]+\.[0-9]+)\x00tcmalloc`), // mongodb 7.x: ver followed by "heap_size" // e.g 7.0.28[NUL]heap_size m.FileContentsVersionMatcher(`(?P[0-9]+\.[0-9]+\.[0-9]+)\x00+heap_size`), // mongodb 8.x: ber followed by "cppdefines" // e.g 8.0.17[NUL]cppdefines m.FileContentsVersionMatcher(`(?P[0-9]+\.[0-9]+\.[0-9]+)\x00+cppdefines`), ), Package: "mongodb", PURL: mustPURL("pkg:generic/mongodb@version"), CPEs: singleCPE("cpe:2.3:a:mongodb:mongodb:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "ingress-nginx-binary", FileGlob: "**/nginx-ingress-controller", EvidenceMatcher: binutils.MatchAny( // [NUL][NUL]v1.15.1[NUL][NUL]@e[ETX][NUL][NUL][NUL][NUL]go1.26.1[NUL][NUL][NUL] // �v1.15.1[NUL][NUL]�z[ETX][NUL][NUL][NUL][NUL]go1.24.4[NUL][NUL][NUL] m.FileContentsVersionMatcher(`v(?P[0-9]+\.[0-9]+\.[0-9]+)\x00+.{0,50}go[0-9]+\.[0-9]+(\-(alpha|beta)\.[0-9])?\.[0-9]+\x00+`), // �Lv1.9.6[NUL][NUL]$a�c[SOH][NUL][NUL][NUL] // [NUL][NUL]v0.34.0[NUL]......�$a�...[NUL] m.FileContentsVersionMatcher(`v(?P[0-9]+\.[0-9]+\.[0-9]+(\-(alpha|beta)\.[0-9])?)\x00+.{0,800}\$a.{0,10}\x00+`), // [NUL][NUL]v1.7.1[NUL][NUL][NUL]...S=v[0-9]+\.[0-9]+\.[0-9]+(\-(alpha|beta)\.[0-9])?)\x00+.{0,100}S=v[0-9]+\.[0-9]+\.[0-9]+(\-(alpha|beta)\.[0-9])?)\x00+`), // [NUL][NUL]v1.2.0-beta.1[NUL][NUL] // [NUL][NUL]v1.0.0-alpha.2[NUL][NUL] m.FileContentsVersionMatcher(`\x00+v(?P[0-9]+\.[0-9]+\.[0-9]+\-(alpha|beta)\.[0-9])\x00+`), ), Package: "nginx-ingress-controller", PURL: mustPURL("pkg:generic/nginx-ingress-controller@version"), CPEs: singleCPE("cpe:2.3:a:kubernetes:ingress-nginx:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "filebeat-binary", FileGlob: "**/filebeat", EvidenceMatcher: elasticBeatsMatcher, Package: "filebeat", PURL: mustPURL("pkg:generic/filebeat@version"), CPEs: singleCPE("cpe:2.3:a:elastic:filebeat:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "metricbeat-binary", FileGlob: "**/metricbeat", EvidenceMatcher: elasticBeatsMatcher, Package: "metricbeat", PURL: mustPURL("pkg:generic/metricbeat@version"), CPEs: singleCPE("cpe:2.3:a:elastic:metricbeat:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "heartbeat-binary", FileGlob: "**/heartbeat", EvidenceMatcher: elasticBeatsMatcher, Package: "heartbeat", PURL: mustPURL("pkg:generic/heartbeat@version"), CPEs: singleCPE("cpe:2.3:a:elastic:heartbeat:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "packetbeat-binary", FileGlob: "**/packetbeat", EvidenceMatcher: elasticBeatsMatcher, Package: "packetbeat", PURL: mustPURL("pkg:generic/packetbeat@version"), CPEs: singleCPE("cpe:2.3:a:elastic:packetbeat:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "auditbeat-binary", FileGlob: "**/auditbeat", EvidenceMatcher: elasticBeatsMatcher, Package: "auditbeat", PURL: mustPURL("pkg:generic/auditbeat@version"), CPEs: singleCPE("cpe:2.3:a:elastic:auditbeat:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "elastic-agent-binary", FileGlob: "**/elastic-agent", EvidenceMatcher: binutils.MatchAny( // 9.4.x: config/statsenroll: true9.4.2-headeruint16secret // 9.0.x: configenroll9.0.0-headeruint16secret // 8.19.x: config/statsenroll8.19.4headeruint16secret m.FileContentsVersionMatcher(`enroll(?:: true)?(?P[0-9]+\.[0-9]+\.[0-9]+)-?header`), // 8.11.x: 3:04PM8.11.2:https m.FileContentsVersionMatcher(`PM(?P[0-9]+\.[0-9]+\.[0-9]+):https`), ), Package: "elastic-agent", PURL: mustPURL("pkg:generic/elastic-agent@version"), CPEs: singleCPE("cpe:2.3:a:elastic:elastic_agent:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "krb5-library", FileGlob: "**/libkrb5.so*", // [NUL]KRB5_BRAND: krb5-1.18.4-final 1.18.4 20210722 // [NUL]KRB5_BRAND: krb5-1.17-final 1.17 20190108 (base releases brand as 2-component) EvidenceMatcher: m.FileContentsVersionMatcher( `\x00KRB5_BRAND:\s+krb5-[^\s]+\s+(?P[0-9]+(?:\.[0-9]+){1,2})(?:\s|$)`, ), Package: "krb5", PURL: mustPURL("pkg:generic/krb5@version"), CPEs: singleCPE("cpe:2.3:a:mit:kerberos_5:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "heimdal-krb5-library", FileGlob: "**/libkrb5.so*", // $Version: Heimdal 7.5.0 // $Version: Heimdal 7.8.0 // $Version: Heimdal 7.1 // $Version: Heimdal 7.0.3 EvidenceMatcher: m.FileContentsVersionMatcher( `(?m)\$Version:\s+Heimdal\s+(?P[0-9]+(?:\.[0-9]+){1,2})(?:\s|$)`, ), Package: "heimdal-krb5", PURL: mustPURL("pkg:generic/heimdal-krb5@version"), CPEs: singleCPE("cpe:2.3:a:heimdal_project:heimdal:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, } return append(classifiers, defaultJavaClassifiers()...) } // singleCPE returns a []cpe.CPE with Source: Generated based on the cpe string or panics if the // cpe string cannot be parsed into valid CPE Attributes func singleCPE(cpeString string, source ...cpe.Source) []cpe.CPE { src := cpe.GeneratedSource if len(source) > 0 { src = source[0] } return []cpe.CPE{ cpe.Must(cpeString, src), } } func mustPURL(purl string) packageurl.PackageURL { p, err := packageurl.FromString(purl) if err != nil { panic(fmt.Sprintf("invalid PURL: %s", p)) } return p }