diff --git a/syft/pkg/cataloger/binary/capabilities.yaml b/syft/pkg/cataloger/binary/capabilities.yaml index bf7e11d04..c98e5c57e 100644 --- a/syft/pkg/cataloger/binary/capabilities.yaml +++ b/syft/pkg/cataloger/binary/capabilities.yaml @@ -786,6 +786,56 @@ catalogers: cpes: - cpe:2.3:a:kubernetes:ingress-nginx:*:*:*:*:*:*:*:* type: BinaryPkg + - method: glob + criteria: + - '**/filebeat' + packages: + - class: filebeat-binary + name: filebeat + purl: pkg:generic/filebeat + cpes: + - cpe:2.3:a:elastic:filebeat:*:*:*:*:*:*:*:* + type: BinaryPkg + - method: glob + criteria: + - '**/metricbeat' + packages: + - class: metricbeat-binary + name: metricbeat + purl: pkg:generic/metricbeat + cpes: + - cpe:2.3:a:elastic:metricbeat:*:*:*:*:*:*:*:* + type: BinaryPkg + - method: glob + criteria: + - '**/heartbeat' + packages: + - class: heartbeat-binary + name: heartbeat + purl: pkg:generic/heartbeat + cpes: + - cpe:2.3:a:elastic:heartbeat:*:*:*:*:*:*:*:* + type: BinaryPkg + - method: glob + criteria: + - '**/packetbeat' + packages: + - class: packetbeat-binary + name: packetbeat + purl: pkg:generic/packetbeat + cpes: + - cpe:2.3:a:elastic:packetbeat:*:*:*:*:*:*:*:* + type: BinaryPkg + - method: glob + criteria: + - '**/auditbeat' + packages: + - class: auditbeat-binary + name: auditbeat + purl: pkg:generic/auditbeat + cpes: + - cpe:2.3:a:elastic:auditbeat:*:*:*:*:*:*:*:* + type: BinaryPkg - method: glob criteria: - '**/elastic-agent' diff --git a/syft/pkg/cataloger/binary/classifier_cataloger_test.go b/syft/pkg/cataloger/binary/classifier_cataloger_test.go index f58963db8..a64ea072b 100644 --- a/syft/pkg/cataloger/binary/classifier_cataloger_test.go +++ b/syft/pkg/cataloger/binary/classifier_cataloger_test.go @@ -2557,6 +2557,83 @@ func Test_Cataloger_PositiveCases(t *testing.T) { Metadata: metadata("ingress-nginx-binary"), }, }, + { + logicalFixture: "filebeat/9.4.2/linux-amd64", + expected: pkg.Package{ + Name: "filebeat", + Version: "9.4.2", + Type: "binary", + PURL: "pkg:generic/filebeat@9.4.2", + Locations: locations("filebeat"), + Metadata: metadata("filebeat-binary"), + }, + }, + { + logicalFixture: "filebeat/8.18.4/linux-amd64", + expected: pkg.Package{ + Name: "filebeat", + Version: "8.18.4", + Type: "binary", + PURL: "pkg:generic/filebeat@8.18.4", + Locations: locations("filebeat"), + Metadata: metadata("filebeat-binary"), + }, + }, + { + logicalFixture: "filebeat/8.11.2/linux-amd64", + expected: pkg.Package{ + Name: "filebeat", + Version: "8.11.2", + Type: "binary", + PURL: "pkg:generic/filebeat@8.11.2", + Locations: locations("filebeat"), + Metadata: metadata("filebeat-binary"), + }, + }, + { + logicalFixture: "metricbeat/9.4.2/linux-amd64", + expected: pkg.Package{ + Name: "metricbeat", + Version: "9.4.2", + Type: "binary", + PURL: "pkg:generic/metricbeat@9.4.2", + Locations: locations("metricbeat"), + Metadata: metadata("metricbeat-binary"), + }, + }, + { + logicalFixture: "heartbeat/9.4.2/linux-amd64", + expected: pkg.Package{ + Name: "heartbeat", + Version: "9.4.2", + Type: "binary", + PURL: "pkg:generic/heartbeat@9.4.2", + Locations: locations("heartbeat"), + Metadata: metadata("heartbeat-binary"), + }, + }, + { + logicalFixture: "packetbeat/9.4.2/linux-amd64", + expected: pkg.Package{ + Name: "packetbeat", + Version: "9.4.2", + Type: "binary", + PURL: "pkg:generic/packetbeat@9.4.2", + Locations: locations("packetbeat"), + Metadata: metadata("packetbeat-binary"), + }, + }, + { + logicalFixture: "auditbeat/9.4.2/linux-amd64", + expected: pkg.Package{ + Name: "auditbeat", + Version: "9.4.2", + Type: "binary", + PURL: "pkg:generic/auditbeat@9.4.2", + Locations: locations("auditbeat"), + Metadata: metadata("auditbeat-binary"), + }, + }, { logicalFixture: "elastic-agent/9.4.2/linux-amd64", expected: pkg.Package{ diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index 9b7680a4d..56f7865de 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -28,6 +28,18 @@ func DefaultClassifiers() []binutils.Classifier { // 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", @@ -1110,6 +1122,46 @@ func DefaultClassifiers() []binutils.Classifier { 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", diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/auditbeat/9.4.2/linux-amd64/auditbeat b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/auditbeat/9.4.2/linux-amd64/auditbeat new file mode 100644 index 000000000..c92847e0f --- /dev/null +++ b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/auditbeat/9.4.2/linux-amd64/auditbeat @@ -0,0 +1,8 @@ +name: auditbeat +offset: 106492476 +length: 100 +snippetSha256: 7cfca991c6d073690c48c9489a6929009b866e78d266ecb6f6f2b6f04d9f592f +fileSha256: 81ac1f3ab45bb7b3211cf26f94660ae73fdd257bb4890bdf8e71ecddb5afce10 + +### byte snippet to follow ### +rulesforcestdinsetupTest 9.4.2%s %windexeventint16int32int64uint8arraysliceInts:Ptrs:sse41sse42ssse3 \ No newline at end of file diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/filebeat/8.11.2/linux-amd64/filebeat b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/filebeat/8.11.2/linux-amd64/filebeat new file mode 100644 index 000000000..48e03e85a --- /dev/null +++ b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/filebeat/8.11.2/linux-amd64/filebeat @@ -0,0 +1,8 @@ +name: filebeat +offset: 99362887 +length: 100 +snippetSha256: e81df9ab08f801188a6912a2c3651233049a50474063deba3181be22d50e4c14 +fileSha256: e29c151f3eae6d2aa6c57ce6810a1ca657fd29cd335d85c83d3b76fddaf0d7ed + +### byte snippet to follow ### +.5.4.82.5.4.92006-015m.rate8.11.2-9765625: type ::ffff::method:scheme:status<>