github.com/lineaje-labs/syft@v0.98.1-0.20231227153149-9e393f60ff1b/syft/pkg/cataloger/binary/default_classifiers.go (about)

     1  package binary
     2  
     3  import (
     4  	"github.com/anchore/syft/syft/cpe"
     5  	"github.com/anchore/syft/syft/pkg"
     6  )
     7  
     8  var defaultClassifiers = []classifier{
     9  	{
    10  		Class:    "python-binary",
    11  		FileGlob: "**/python*",
    12  		EvidenceMatcher: evidenceMatchers(
    13  			// try to find version information from libpython shared libraries
    14  			sharedLibraryLookup(
    15  				`^libpython[0-9]+(?:\.[0-9]+)+[a-z]?\.so.*$`,
    16  				libpythonMatcher),
    17  			// check for version information in the binary
    18  			fileNameTemplateVersionMatcher(
    19  				`(?:.*/|^)python(?P<version>[0-9]+(?:\.[0-9]+)+)$`,
    20  				pythonVersionTemplate),
    21  		),
    22  		Package: "python",
    23  		PURL:    mustPURL("pkg:generic/python@version"),
    24  		CPEs: []cpe.CPE{
    25  			cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*"),
    26  			cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*"),
    27  		},
    28  	},
    29  	{
    30  		Class:           "python-binary-lib",
    31  		FileGlob:        "**/libpython*.so*",
    32  		EvidenceMatcher: libpythonMatcher,
    33  		Package:         "python",
    34  		PURL:            mustPURL("pkg:generic/python@version"),
    35  		CPEs: []cpe.CPE{
    36  			cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*"),
    37  			cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*"),
    38  		},
    39  	},
    40  	{
    41  		Class:    "go-binary",
    42  		FileGlob: "**/go",
    43  		EvidenceMatcher: fileContentsVersionMatcher(
    44  			`(?m)go(?P<version>[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+)?)\x00`),
    45  		Package: "go",
    46  		PURL:    mustPURL("pkg:generic/go@version"),
    47  		CPEs:    singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*"),
    48  	},
    49  	{
    50  		Class:    "helm",
    51  		FileGlob: "**/helm",
    52  		EvidenceMatcher: fileContentsVersionMatcher(
    53  			`(?m)\x00v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00`),
    54  		Package: "helm",
    55  		PURL:    mustPURL("pkg:golang/helm.sh/helm@version"),
    56  		CPEs:    singleCPE("cpe:2.3:a:helm:helm:*:*:*:*:*:*:*"),
    57  	},
    58  	{
    59  		Class:    "redis-binary",
    60  		FileGlob: "**/redis-server",
    61  		EvidenceMatcher: evidenceMatchers(
    62  			fileContentsVersionMatcher(`(?s)payload %5.*?(?P<version>\d.\d\.\d\d*)[a-z0-9]{12,15}-[0-9]{19}`),
    63  			fileContentsVersionMatcher(`(?s)\x00(?P<version>\d.\d\.\d\d*)[a-z0-9]{12}-[0-9]{19}\x00.*?payload %5`),
    64  		),
    65  		Package: "redis",
    66  		PURL:    mustPURL("pkg:generic/redis@version"),
    67  		CPEs:    singleCPE("cpe:2.3:a:redislabs:redis:*:*:*:*:*:*:*:*"),
    68  	},
    69  	{
    70  		Class:    "java-binary-openjdk",
    71  		FileGlob: "**/java",
    72  		EvidenceMatcher: fileContentsVersionMatcher(
    73  			// [NUL]openjdk[NUL]java[NUL]0.0[NUL]11.0.17+8-LTS[NUL]
    74  			// [NUL]openjdk[NUL]java[NUL]1.8[NUL]1.8.0_352-b08[NUL]
    75  			`(?m)\x00openjdk\x00java\x00(?P<release>[0-9]+[.0-9]*)\x00(?P<version>[0-9]+[^\x00]+)\x00`),
    76  		Package: "java",
    77  		PURL:    mustPURL("pkg:generic/java@version"),
    78  		// TODO the updates might need to be part of the CPE, like: 1.8.0:update152
    79  		CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*"),
    80  	},
    81  	{
    82  		Class:    "java-binary-ibm",
    83  		FileGlob: "**/java",
    84  		EvidenceMatcher: fileContentsVersionMatcher(
    85  			// [NUL]java[NUL]1.8[NUL][NUL][NUL][NUL]1.8.0-foreman_2022_09_22_15_30-b00[NUL]
    86  			`(?m)\x00java\x00(?P<release>[0-9]+[.0-9]+)\x00{4}(?P<version>[0-9]+[-._a-zA-Z0-9]+)\x00`),
    87  		Package: "java",
    88  		PURL:    mustPURL("pkg:generic/java@version"),
    89  		CPEs:    singleCPE("cpe:2.3:a:ibm:java:*:*:*:*:*:*:*:*"),
    90  	},
    91  	{
    92  		Class:    "java-binary-oracle",
    93  		FileGlob: "**/java",
    94  		EvidenceMatcher: fileContentsVersionMatcher(
    95  			// [NUL]19.0.1+10-21[NUL]
    96  			`(?m)\x00(?P<version>[0-9]+[.0-9]+[+][-0-9]+)\x00`),
    97  		Package: "java",
    98  		PURL:    mustPURL("pkg:generic/java@version"),
    99  		CPEs:    singleCPE("cpe:2.3:a:oracle:jre:*:*:*:*:*:*:*:*"),
   100  	},
   101  	{
   102  		Class:    "nodejs-binary",
   103  		FileGlob: "**/node",
   104  		EvidenceMatcher: fileContentsVersionMatcher(
   105  			`(?m)node\.js\/v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
   106  		Package:  "node",
   107  		Language: pkg.JavaScript,
   108  		PURL:     mustPURL("pkg:generic/node@version"),
   109  		CPEs:     singleCPE("cpe:2.3:a:nodejs:node.js:*:*:*:*:*:*:*:*"),
   110  	},
   111  	{
   112  		Class:    "go-binary-hint",
   113  		FileGlob: "**/VERSION",
   114  		EvidenceMatcher: fileContentsVersionMatcher(
   115  			`(?m)go(?P<version>[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+)?)`),
   116  		Package: "go",
   117  		PURL:    mustPURL("pkg:generic/go@version"),
   118  	},
   119  	{
   120  		Class:    "busybox-binary",
   121  		FileGlob: "**/busybox",
   122  		EvidenceMatcher: fileContentsVersionMatcher(
   123  			`(?m)BusyBox\s+v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
   124  		Package: "busybox",
   125  		CPEs:    singleCPE("cpe:2.3:a:busybox:busybox:*:*:*:*:*:*:*:*"),
   126  	},
   127  	{
   128  		Class:    "haproxy-binary",
   129  		FileGlob: "**/haproxy",
   130  		EvidenceMatcher: evidenceMatchers(
   131  			fileContentsVersionMatcher(`(?m)HA-Proxy version (?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
   132  			fileContentsVersionMatcher(`(?m)(?P<version>[0-9]+\.[0-9]+\.[0-9]+)-[0-9a-zA-Z]{7}.+HAProxy version`),
   133  		),
   134  		Package: "haproxy",
   135  		PURL:    mustPURL("pkg:generic/haproxy@version"),
   136  		CPEs:    singleCPE("cpe:2.3:a:haproxy:haproxy:*:*:*:*:*:*:*:*"),
   137  	},
   138  	{
   139  		Class:    "perl-binary",
   140  		FileGlob: "**/perl",
   141  		EvidenceMatcher: fileContentsVersionMatcher(
   142  			`(?m)\/usr\/local\/lib\/perl\d\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
   143  		Package: "perl",
   144  		PURL:    mustPURL("pkg:generic/perl@version"),
   145  		CPEs:    singleCPE("cpe:2.3:a:perl:perl:*:*:*:*:*:*:*:*"),
   146  	},
   147  	{
   148  		Class:    "php-cli-binary",
   149  		FileGlob: "**/php*",
   150  		EvidenceMatcher: fileNameTemplateVersionMatcher(
   151  			`(.*/|^)php[0-9]*$`,
   152  			`(?m)X-Powered-By: PHP\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+(beta[0-9]+|alpha[0-9]+|RC[0-9]+)?)`),
   153  		Package: "php-cli",
   154  		PURL:    mustPURL("pkg:generic/php-cli@version"),
   155  		CPEs:    singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*"),
   156  	},
   157  	{
   158  		Class:    "php-fpm-binary",
   159  		FileGlob: "**/php-fpm*",
   160  		EvidenceMatcher: fileContentsVersionMatcher(
   161  			`(?m)X-Powered-By: PHP\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+(beta[0-9]+|alpha[0-9]+|RC[0-9]+)?)`),
   162  		Package: "php-fpm",
   163  		PURL:    mustPURL("pkg:generic/php-fpm@version"),
   164  		CPEs:    singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*"),
   165  	},
   166  	{
   167  		Class:    "php-apache-binary",
   168  		FileGlob: "**/libphp*.so",
   169  		EvidenceMatcher: fileContentsVersionMatcher(
   170  			`(?m)X-Powered-By: PHP\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+(beta[0-9]+|alpha[0-9]+|RC[0-9]+)?)`),
   171  		Package: "libphp",
   172  		PURL:    mustPURL("pkg:generic/php@version"),
   173  		CPEs:    singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*"),
   174  	},
   175  	{
   176  		Class:    "httpd-binary",
   177  		FileGlob: "**/httpd",
   178  		EvidenceMatcher: fileContentsVersionMatcher(
   179  			`(?m)Apache\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
   180  		Package: "httpd",
   181  		PURL:    mustPURL("pkg:generic/httpd@version"),
   182  		CPEs:    singleCPE("cpe:2.3:a:apache:http_server:*:*:*:*:*:*:*:*"),
   183  	},
   184  	{
   185  		Class:    "memcached-binary",
   186  		FileGlob: "**/memcached",
   187  		EvidenceMatcher: fileContentsVersionMatcher(
   188  			`(?m)memcached\s(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
   189  		Package: "memcached",
   190  		PURL:    mustPURL("pkg:generic/memcached@version"),
   191  	},
   192  	{
   193  		Class:    "traefik-binary",
   194  		FileGlob: "**/traefik",
   195  		EvidenceMatcher: fileContentsVersionMatcher(
   196  			// [NUL]v1.7.34[NUL]
   197  			// [NUL]2.9.6[NUL]
   198  			`(?m)\x00v?(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00`),
   199  		Package: "traefik",
   200  		PURL:    mustPURL("pkg:generic/traefik@version"),
   201  	},
   202  	{
   203  		Class:    "postgresql-binary",
   204  		FileGlob: "**/postgres",
   205  		EvidenceMatcher: fileContentsVersionMatcher(
   206  			// [NUL]PostgreSQL 15beta4
   207  			// [NUL]PostgreSQL 15.1
   208  			// [NUL]PostgreSQL 9.6.24
   209  			// ?PostgreSQL 9.5alpha1
   210  			`(?m)(\x00|\?)PostgreSQL (?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`),
   211  		Package: "postgresql",
   212  		PURL:    mustPURL("pkg:generic/postgresql@version"),
   213  	},
   214  	{
   215  		Class:    "mysql-binary",
   216  		FileGlob: "**/mysql",
   217  		EvidenceMatcher: fileContentsVersionMatcher(
   218  			// ../../mysql-8.0.34
   219  			// /mysql-5.6.51/bld/client
   220  			`(?m).*/mysql-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`),
   221  		Package: "mysql",
   222  		PURL:    mustPURL("pkg:generic/mysql@version"),
   223  		CPEs:    singleCPE("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*"),
   224  	},
   225  	{
   226  		Class:    "mariadb-binary",
   227  		FileGlob: "**/mariadb",
   228  		EvidenceMatcher: fileContentsVersionMatcher(
   229  			// 10.6.15-MariaDB
   230  			`(?m)(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)-MariaDB`),
   231  		Package: "mariadb",
   232  		PURL:    mustPURL("pkg:generic/mariadb@version"),
   233  	},
   234  	{
   235  		Class:    "rust-standard-library-linux",
   236  		FileGlob: "**/libstd-????????????????.so",
   237  		EvidenceMatcher: fileContentsVersionMatcher(
   238  			// clang LLVM (rustc version 1.48.0 (7eac88abb 2020-11-16))
   239  			`(?m)(\x00)clang LLVM \(rustc version (?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)) \(\w+ \d{4}\-\d{2}\-\d{2}\)`),
   240  		Package: "rust",
   241  		PURL:    mustPURL("pkg:generic/rust@version"),
   242  		CPEs:    singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*"),
   243  	},
   244  	{
   245  		Class:    "rust-standard-library-macos",
   246  		FileGlob: "**/libstd-????????????????.dylib",
   247  		EvidenceMatcher: fileContentsVersionMatcher(
   248  			// c 1.48.0 (7eac88abb 2020-11-16)
   249  			`(?m)c (?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)) \(\w+ \d{4}\-\d{2}\-\d{2}\)`),
   250  		Package: "rust",
   251  		PURL:    mustPURL("pkg:generic/rust@version"),
   252  		CPEs:    singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*"),
   253  	},
   254  	{
   255  		Class:    "ruby-binary",
   256  		FileGlob: "**/ruby",
   257  		EvidenceMatcher: evidenceMatchers(
   258  			rubyMatcher,
   259  			sharedLibraryLookup(
   260  				// try to find version information from libruby shared libraries
   261  				`^libruby\.so.*$`,
   262  				rubyMatcher),
   263  		),
   264  		Package: "ruby",
   265  		PURL:    mustPURL("pkg:generic/ruby@version"),
   266  		CPEs:    singleCPE("cpe:2.3:a:ruby-lang:ruby:*:*:*:*:*:*:*:*"),
   267  	},
   268  	{
   269  		Class:    "consul-binary",
   270  		FileGlob: "**/consul",
   271  		EvidenceMatcher: fileContentsVersionMatcher(
   272  			// NOTE: This is brittle and may not work for past or future versions
   273  			`CONSUL_VERSION: (?P<version>\d+\.\d+\.\d+)`,
   274  		),
   275  		Package: "consul",
   276  		PURL:    mustPURL("pkg:golang/github.com/hashicorp/consul@version"),
   277  		CPEs:    singleCPE("cpe:2.3:a:hashicorp:consul:*:*:*:*:*:*:*:*"),
   278  	},
   279  	{
   280  		Class:    "nginx-binary",
   281  		FileGlob: "**/nginx",
   282  		EvidenceMatcher: fileContentsVersionMatcher(
   283  			// [NUL]nginx version: nginx/1.25.1 - fetches '1.25.1'
   284  			// [NUL]nginx version: openresty/1.21.4.1 - fetches '1.21.4' as this is the nginx version part
   285  			`(?m)(\x00|\?)nginx version: [^\/]+\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+(?:\+\d+)?(?:-\d+)?)`,
   286  		),
   287  		Package: "nginx",
   288  		PURL:    mustPURL("pkg:generic/nginx@version"),
   289  		CPEs: []cpe.CPE{
   290  			cpe.Must("cpe:2.3:a:f5:nginx:*:*:*:*:*:*:*:*"),
   291  			cpe.Must("cpe:2.3:a:nginx:nginx:*:*:*:*:*:*:*:*"),
   292  		},
   293  	},
   294  	{
   295  		Class:    "bash-binary",
   296  		FileGlob: "**/bash",
   297  		EvidenceMatcher: fileContentsVersionMatcher(
   298  			// @(#)Bash version 5.2.15(1) release GNU
   299  			// @(#)Bash version 5.2.0(1) alpha GNU
   300  			// @(#)Bash version 5.2.0(1) beta GNU
   301  			// @(#)Bash version 5.2.0(1) rc4 GNU
   302  			`(?m)@\(#\)Bash version (?P<version>[0-9]+\.[0-9]+\.[0-9]+)\([0-9]\) [a-z0-9]+ GNU`,
   303  		),
   304  		Package: "bash",
   305  		PURL:    mustPURL("pkg:generic/bash@version"),
   306  		CPEs:    singleCPE("cpe:2.3:a:gnu:bash:*:*:*:*:*:*:*:*"),
   307  	},
   308  }
   309  
   310  // in both binaries and shared libraries, the version pattern is [NUL]3.11.2[NUL]
   311  var pythonVersionTemplate = `(?m)\x00(?P<version>{{ .version }}[-._a-zA-Z0-9]*)\x00`
   312  
   313  var libpythonMatcher = fileNameTemplateVersionMatcher(
   314  	`(?:.*/|^)libpython(?P<version>[0-9]+(?:\.[0-9]+)+)[a-z]?\.so.*$`,
   315  	pythonVersionTemplate,
   316  )
   317  
   318  var rubyMatcher = fileContentsVersionMatcher(
   319  	// ruby 3.2.1 (2023-02-08 revision 31819e82c8) [x86_64-linux]
   320  	// ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5) [x86_64-linux]
   321  	`(?m)ruby (?P<version>[0-9]+\.[0-9]+\.[0-9]+(p[0-9]+)?) `)