Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(contrib): add snmp2cpe #1625

Merged
merged 1 commit into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ vuls
!cmd/vuls
future-vuls
trivy-to-vuls
snmp2cpe
!snmp2cpe/
34 changes: 34 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ builds:
tags:
- scanner
main: ./contrib/trivy/cmd/main.go
ldflags:
- -s -w -X github.com/future-architect/vuls/config.Version={{.Version}} -X github.com/future-architect/vuls/config.Revision={{.Commit}}-{{ .CommitDate }}
binary: trivy-to-vuls

- id: future-vuls
Expand All @@ -84,9 +86,30 @@ builds:
- -a
tags:
- scanner
ldflags:
- -s -w -X github.com/future-architect/vuls/config.Version={{.Version}} -X github.com/future-architect/vuls/config.Revision={{.Commit}}-{{ .CommitDate }}
main: ./contrib/future-vuls/cmd/main.go
binary: future-vuls

- id: snmp2cpe
env:
- CGO_ENABLED=0
goos:
- linux
goarch:
- 386
- amd64
- arm
- arm64
flags:
- -a
tags:
- scanner
ldflags:
- -s -w -X github.com/future-architect/vuls/config.Version={{.Version}} -X github.com/future-architect/vuls/config.Revision={{.Commit}}-{{ .CommitDate }}
main: ./contrib/snmp2cpe/cmd/main.go
binary: snmp2cpe

archives:

- id: vuls
Expand Down Expand Up @@ -129,5 +152,16 @@ archives:
- LICENSE
- README*
- CHANGELOG.md

- id: snmp2cpe
name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
builds:
- snmp2cpe
format: tar.gz
files:
- LICENSE
- README*
- CHANGELOG.md

snapshot:
name_template: SNAPSHOT-{{ .Commit }}
4 changes: 4 additions & 0 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ build-trivy-to-vuls: ./contrib/trivy/cmd/main.go
build-future-vuls: ./contrib/future-vuls/cmd/main.go
$(GO) build -a -ldflags "$(LDFLAGS)" -o future-vuls ./contrib/future-vuls/cmd

# snmp2cpe
build-snmp2cpe: ./contrib/snmp2cpe/cmd/main.go
$(GO) build -a -ldflags "$(LDFLAGS)" -o snmp2cpe ./contrib/snmp2cpe/cmd

# integration-test
BASE_DIR := '${PWD}/integration/results'
# $(shell mkdir -p ${BASE_DIR})
Expand Down
5 changes: 3 additions & 2 deletions contrib/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ COPY . $GOPATH/src/$REPOSITORY
RUN cd $GOPATH/src/$REPOSITORY && \
make build-scanner && mv vuls $GOPATH/bin && \
make build-trivy-to-vuls && mv trivy-to-vuls $GOPATH/bin && \
make build-future-vuls && mv future-vuls $GOPATH/bin
make build-future-vuls && mv future-vuls $GOPATH/bin && \
make build-snmp2cpe && mv snmp2cpe $GOPATH/bin

FROM alpine:3.15

Expand All @@ -25,7 +26,7 @@ RUN apk add --no-cache \
nmap \
&& mkdir -p $WORKDIR $LOGDIR

COPY --from=builder /go/bin/vuls /go/bin/trivy-to-vuls /go/bin/future-vuls /usr/local/bin/
COPY --from=builder /go/bin/vuls /go/bin/trivy-to-vuls /go/bin/future-vuls /go/bin/snmp2cpe /usr/local/bin/
COPY --from=aquasec/trivy:latest /usr/local/bin/trivy /usr/local/bin/trivy

VOLUME ["$WORKDIR", "$LOGDIR"]
Expand Down
50 changes: 50 additions & 0 deletions contrib/snmp2cpe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# snmp2cpe

## Main Features

- Estimate hardware and OS CPE from SNMP reply of network devices

## Installation

```console
$ git clone https://github.com/future-architect/vuls.git
$ make build-snmp2cpe
```

## Command Reference

```console
$ snmp2cpe help
snmp2cpe: SNMP reply To CPE

Usage:
snmp2cpe [command]

Available Commands:
completion Generate the autocompletion script for the specified shell
convert snmpget reply to CPE
help Help about any command
v1 snmpget with SNMPv1
v2c snmpget with SNMPv2c
v3 snmpget with SNMPv3
version Print the version

Flags:
-h, --help help for snmp2cpe

Use "snmp2cpe [command] --help" for more information about a command.
```

## Usage

```console
$ snmp2cpe v2c --debug 192.168.1.99 public
2023/03/28 14:16:54 DEBUG: .1.3.6.1.2.1.1.1.0 ->
2023/03/28 14:16:54 DEBUG: .1.3.6.1.2.1.47.1.1.1.1.12.1 -> Fortinet
2023/03/28 14:16:54 DEBUG: .1.3.6.1.2.1.47.1.1.1.1.7.1 -> FGT_50E
2023/03/28 14:16:54 DEBUG: .1.3.6.1.2.1.47.1.1.1.1.10.1 -> FortiGate-50E v5.4.6,build1165b1165,171018 (GA)
{"192.168.1.99":{"entPhysicalTables":{"1":{"entPhysicalMfgName":"Fortinet","entPhysicalName":"FGT_50E","entPhysicalSoftwareRev":"FortiGate-50E v5.4.6,build1165b1165,171018 (GA)"}}}}

$ snmp2cpe v2c 192.168.1.99 public | snmp2cpe convert
{"192.168.1.99":["cpe:2.3:h:fortinet:fortigate-50e:-:*:*:*:*:*:*:*","cpe:2.3:o:fortinet:fortios:5.4.6:*:*:*:*:*:*:*"]}
```
15 changes: 15 additions & 0 deletions contrib/snmp2cpe/cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import (
"fmt"
"os"

rootCmd "github.com/future-architect/vuls/contrib/snmp2cpe/pkg/cmd/root"
)

func main() {
if err := rootCmd.NewCmdRoot().Execute(); err != nil {
fmt.Fprintf(os.Stderr, "failed to exec snmp2cpe: %s\n", fmt.Sprintf("%+v", err))
os.Exit(1)
}
}
52 changes: 52 additions & 0 deletions contrib/snmp2cpe/pkg/cmd/convert/convert.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package convert

import (
"encoding/json"
"os"

"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/future-architect/vuls/contrib/snmp2cpe/pkg/cpe"
"github.com/future-architect/vuls/contrib/snmp2cpe/pkg/snmp"
)

// NewCmdConvert ...
func NewCmdConvert() *cobra.Command {
cmd := &cobra.Command{
Use: "convert",
Short: "snmpget reply to CPE",
Args: cobra.MaximumNArgs(1),
Example: `$ snmp2cpe v2c 192.168.11.11 public | snmp2cpe convert
$ snmp2cpe v2c 192.168.11.11 public | snmp2cpe convert -
$ snmp2cpe v2c 192.168.11.11 public > v2c.json && snmp2cpe convert v2c.json`,
RunE: func(_ *cobra.Command, args []string) error {
r := os.Stdin
if len(args) == 1 && args[0] != "-" {
f, err := os.Open(args[0])
if err != nil {
return errors.Wrapf(err, "failed to open %s", args[0])
}
defer f.Close()
r = f
}

var reply map[string]snmp.Result
if err := json.NewDecoder(r).Decode(&reply); err != nil {
return errors.Wrap(err, "failed to decode")
}

converted := map[string][]string{}
for ipaddr, res := range reply {
converted[ipaddr] = cpe.Convert(res)
}

if err := json.NewEncoder(os.Stdout).Encode(converted); err != nil {
return errors.Wrap(err, "failed to encode")
}

return nil
},
}
return cmd
}
30 changes: 30 additions & 0 deletions contrib/snmp2cpe/pkg/cmd/root/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package root

import (
"github.com/spf13/cobra"

convertCmd "github.com/future-architect/vuls/contrib/snmp2cpe/pkg/cmd/convert"
v1Cmd "github.com/future-architect/vuls/contrib/snmp2cpe/pkg/cmd/v1"
v2cCmd "github.com/future-architect/vuls/contrib/snmp2cpe/pkg/cmd/v2c"
v3Cmd "github.com/future-architect/vuls/contrib/snmp2cpe/pkg/cmd/v3"
versionCmd "github.com/future-architect/vuls/contrib/snmp2cpe/pkg/cmd/version"
)

// NewCmdRoot ...
func NewCmdRoot() *cobra.Command {
cmd := &cobra.Command{
Use: "snmp2cpe <command>",
Short: "snmp2cpe",
Long: "snmp2cpe: SNMP reply To CPE",
SilenceErrors: true,
SilenceUsage: true,
}

cmd.AddCommand(v1Cmd.NewCmdV1())
cmd.AddCommand(v2cCmd.NewCmdV2c())
cmd.AddCommand(v3Cmd.NewCmdV3())
cmd.AddCommand(convertCmd.NewCmdConvert())
cmd.AddCommand(versionCmd.NewCmdVersion())

return cmd
}
47 changes: 47 additions & 0 deletions contrib/snmp2cpe/pkg/cmd/v1/v1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package v1

import (
"encoding/json"
"os"

"github.com/gosnmp/gosnmp"
"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/future-architect/vuls/contrib/snmp2cpe/pkg/snmp"
)

// SNMPv1Options ...
type SNMPv1Options struct {
Debug bool
}

// NewCmdV1 ...
func NewCmdV1() *cobra.Command {
opts := &SNMPv1Options{
Debug: false,
}

cmd := &cobra.Command{
Use: "v1 <IP Address> <Community>",
Short: "snmpget with SNMPv1",
Example: "$ snmp2cpe v1 192.168.100.1 public",
Args: cobra.ExactArgs(2),
RunE: func(_ *cobra.Command, args []string) error {
r, err := snmp.Get(gosnmp.Version1, args[0], snmp.WithCommunity(args[1]), snmp.WithDebug(opts.Debug))
if err != nil {
return errors.Wrap(err, "failed to snmpget")
}

if err := json.NewEncoder(os.Stdout).Encode(map[string]snmp.Result{args[0]: r}); err != nil {
return errors.Wrap(err, "failed to encode")
}

return nil
},
}

cmd.Flags().BoolVarP(&opts.Debug, "debug", "", false, "debug mode")

return cmd
}
47 changes: 47 additions & 0 deletions contrib/snmp2cpe/pkg/cmd/v2c/v2c.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package v2c

import (
"encoding/json"
"os"

"github.com/gosnmp/gosnmp"
"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/future-architect/vuls/contrib/snmp2cpe/pkg/snmp"
)

// SNMPv2cOptions ...
type SNMPv2cOptions struct {
Debug bool
}

// NewCmdV2c ...
func NewCmdV2c() *cobra.Command {
opts := &SNMPv2cOptions{
Debug: false,
}

cmd := &cobra.Command{
Use: "v2c <IP Address> <Community>",
Short: "snmpget with SNMPv2c",
Example: "$ snmp2cpe v2c 192.168.100.1 public",
Args: cobra.ExactArgs(2),
RunE: func(_ *cobra.Command, args []string) error {
r, err := snmp.Get(gosnmp.Version2c, args[0], snmp.WithCommunity(args[1]), snmp.WithDebug(opts.Debug))
if err != nil {
return errors.Wrap(err, "failed to snmpget")
}

if err := json.NewEncoder(os.Stdout).Encode(map[string]snmp.Result{args[0]: r}); err != nil {
return errors.Wrap(err, "failed to encode")
}

return nil
},
}

cmd.Flags().BoolVarP(&opts.Debug, "debug", "", false, "debug mode")

return cmd
}
39 changes: 39 additions & 0 deletions contrib/snmp2cpe/pkg/cmd/v3/v3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package v3

import (
"github.com/gosnmp/gosnmp"
"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/future-architect/vuls/contrib/snmp2cpe/pkg/snmp"
)

// SNMPv3Options ...
type SNMPv3Options struct {
Debug bool
}

// NewCmdV3 ...
func NewCmdV3() *cobra.Command {
opts := &SNMPv3Options{
Debug: false,
}

cmd := &cobra.Command{
Use: "v3 <args>",
Short: "snmpget with SNMPv3",
Example: "$ snmp2cpe v3",
RunE: func(_ *cobra.Command, _ []string) error {
_, err := snmp.Get(gosnmp.Version3, "", snmp.WithDebug(opts.Debug))
if err != nil {
return errors.Wrap(err, "failed to snmpget")
}

return nil
},
}

cmd.Flags().BoolVarP(&opts.Debug, "debug", "", false, "debug mode")

return cmd
}
Loading