Skip to content

Commit

Permalink
add rating functionality.
Browse files Browse the repository at this point in the history
  • Loading branch information
jonhadfield committed Jun 27, 2024
1 parent fd5d93d commit 2d7a2cd
Show file tree
Hide file tree
Showing 29 changed files with 1,081 additions and 90 deletions.
69 changes: 69 additions & 0 deletions cmd/rate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package cmd

import (
"fmt"
"net/netip"
"os"

"github.com/jonhadfield/ipscout/rate"
"github.com/jonhadfield/ipscout/session"

"github.com/spf13/cobra"
)

func newRateCommand() *cobra.Command {
var useTestData bool

cacheCmd := &cobra.Command{
Use: "rate",
Short: "rate ip address",
RunE: func(cmd *cobra.Command, args []string) error {
// using test data doesn't require a host be provided
// but command does so use placeholder
if useTestData {
args = []string{"8.8.8.8"}
}

if len(args) == 0 {
_ = cmd.Help()

os.Exit(0)
}

var err error

if sess.Host, err = netip.ParseAddr(args[0]); err != nil {
return fmt.Errorf("invalid host: %w", err)
}

rater, err := rate.New(sess)
if err != nil {
os.Exit(1)
}

rater.Run()

return nil
},
}

cacheCmd.AddCommand(newDefaultRateCommand())

return cacheCmd
}

func newDefaultRateCommand() *cobra.Command {
return &cobra.Command{
Use: "default",
Short: "output default configuration",
Long: `output default configuration.`,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error { //nolint:revive
return initConfig(cmd)
},
RunE: func(cmd *cobra.Command, args []string) error { //nolint:revive
fmt.Println(session.DefaultConfig)

return nil
},
}
}
76 changes: 60 additions & 16 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"os"
"strings"

"github.com/mitchellh/go-homedir"

"github.com/jonhadfield/ipscout/process"
"github.com/jonhadfield/ipscout/session"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -72,9 +74,11 @@ func newRootCommand() *cobra.Command {

cacheCommand := newCacheCommand()
configCommand := newConfigCommand()
rateCommand := newRateCommand()

rootCmd.AddCommand(cacheCommand)
rootCmd.AddCommand(configCommand)
rootCmd.AddCommand(rateCommand)
rootCmd.AddCommand(versionCmd)
rootCmd.RunE = func(cmd *cobra.Command, args []string) error {
// using test data doesn't require a host be provided
Expand Down Expand Up @@ -166,23 +170,12 @@ const (
defaultVirusTotalOutputPriority = 40
)

func initSessionConfig(sess *session.Session, v *viper.Viper) {
func initProviderConfig(sess *session.Session, v *viper.Viper) {
// IP API
sess.Providers.IPAPI.APIKey = v.GetString("providers.ipapi.api_key")
sess.Providers.IPAPI.ResultCacheTTL = v.GetInt64("providers.ipapi.result_cache_ttl")
sess.Config.Global.Ports = v.GetStringSlice("global.ports")
sess.Config.Global.MaxValueChars = v.GetInt32("global.max_value_chars")

sess.Config.Global.MaxAge = v.GetString("global.max_age")
sess.Config.Global.MaxReports = v.GetInt("global.max_reports")
// TODO: Nasty Hack Alert
// if not specified, ports is returned as a string: "[]"
// set to nil if that's the case
if len(sess.Config.Global.Ports) == 0 || sess.Config.Global.Ports[0] == "[]" {
sess.Config.Global.Ports = nil
}

sess.Config.Global.MaxAge = v.GetString("global.max_age")

// Abuse IPDB
if v.IsSet("providers.abuseipdb.enabled") {
sess.Providers.AbuseIPDB.Enabled = ToPtr(v.GetBool("providers.abuseipdb.enabled"))
} else {
Expand Down Expand Up @@ -504,11 +497,60 @@ func initSessionConfig(sess *session.Session, v *viper.Viper) {
}
}

func initHomeDirConfig(sess *session.Session, v *viper.Viper) error {
var err error

homeDir := v.GetString("home_dir")
if homeDir == "" {
homeDir, err = homedir.Dir()
if err != nil {
return fmt.Errorf("failed to get home directory: %w", err)
}
}

// check home directory exists
_, err = os.Stat(homeDir)
if err != nil && os.IsNotExist(err) {
return fmt.Errorf("home directory %s does not exist: %w", homeDir, err)
}

sess.Config.Global.HomeDir = homeDir

return nil
}

func initSessionConfig(sess *session.Session, v *viper.Viper) error {
initProviderConfig(sess, v)

sess.Config.Global.Ports = v.GetStringSlice("global.ports")
sess.Config.Global.MaxValueChars = v.GetInt32("global.max_value_chars")

sess.Config.Global.MaxAge = v.GetString("global.max_age")
sess.Config.Global.MaxReports = v.GetInt("global.max_reports")
// TODO: Nasty Hack Alert
// if not specified, ports is returned as a string: "[]"
// set to nil if that's the case
if len(sess.Config.Global.Ports) == 0 || sess.Config.Global.Ports[0] == "[]" {
sess.Config.Global.Ports = nil
}

sess.Config.Global.MaxAge = v.GetString("global.max_age")

return nil
}

func initConfig(cmd *cobra.Command) error {
v := viper.New()

// create session
sess = session.New()
configRoot := session.GetConfigRoot("", AppName)

// get home dir to be used for config and cache
if err := initHomeDirConfig(sess, v); err != nil {
return err
}

configRoot := session.GetConfigRoot("", sess.Config.Global.HomeDir, AppName)
sess.App.Version = version
sess.App.SemVer = semver

Expand Down Expand Up @@ -541,7 +583,9 @@ func initConfig(cmd *cobra.Command) error {

sess.Target = os.Stderr

initSessionConfig(sess, v)
if err := initSessionConfig(sess, v); err != nil {
return err
}

// initialise logging
initLogging(cmd)
Expand Down
19 changes: 2 additions & 17 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"github.com/jonhadfield/ipscout/cache"
"github.com/jonhadfield/ipscout/present"
"github.com/jonhadfield/ipscout/session"
"github.com/mitchellh/go-homedir"
)

const MaxColumnWidth = 60
Expand Down Expand Up @@ -250,14 +249,7 @@ func (c *Client) Show() error {
}

func (c *Client) Delete(keys []string) error {
homeDir, err := homedir.Dir()
if err != nil {
c.Sess.Logger.Error("failed to get home directory", "error", err)

os.Exit(1)
}

db, err := cache.Create(c.Sess.Logger, filepath.Join(homeDir, ".config", "ipscout"))
db, err := cache.Create(c.Sess.Logger, filepath.Join(c.Sess.Config.Global.HomeDir, ".config", "ipscout"))
if err != nil {
c.Sess.Logger.Error("failed to create cache", "error", err)

Expand All @@ -276,14 +268,7 @@ func (c *Client) Delete(keys []string) error {
}

func (c *Client) Get(key string, raw bool) error {
homeDir, err := homedir.Dir()
if err != nil {
c.Sess.Logger.Error("failed to get home directory", "error", err)

os.Exit(1)
}

db, err := cache.Create(c.Sess.Logger, filepath.Join(homeDir, ".config", "ipscout"))
db, err := cache.Create(c.Sess.Logger, filepath.Join(c.Sess.Config.Global.HomeDir, ".config", "ipscout"))
if err != nil {
c.Sess.Logger.Error("failed to create cache", "error", err)

Expand Down
28 changes: 3 additions & 25 deletions manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/jonhadfield/ipscout/cache"
"github.com/jonhadfield/ipscout/present"
"github.com/jonhadfield/ipscout/session"
"github.com/mitchellh/go-homedir"
)

const MaxColumnWidth = 60
Expand Down Expand Up @@ -60,14 +59,7 @@ func NewClient(config *session.Session) (Client, error) {
}

func (c *Client) List() error {
homeDir, err := homedir.Dir()
if err != nil {
c.Config.Logger.Error("failed to get home directory", "error", err)

os.Exit(1)
}

db, err := cache.Create(c.Config.Logger, filepath.Join(homeDir, ".config", "ipscout"))
db, err := cache.Create(c.Config.Logger, filepath.Join(c.Config.Config.Global.HomeDir, ".config", "ipscout"))
if err != nil {
c.Config.Logger.Error("failed to create cache", "error", err)

Expand Down Expand Up @@ -99,14 +91,7 @@ func (c *Client) List() error {
}

func (c *Client) Delete(keys []string) error {
homeDir, err := homedir.Dir()
if err != nil {
c.Config.Logger.Error("failed to get home directory", "error", err)

os.Exit(1)
}

db, err := cache.Create(c.Config.Logger, filepath.Join(homeDir, ".config", "ipscout"))
db, err := cache.Create(c.Config.Logger, filepath.Join(c.Config.Config.Global.HomeDir, ".config", "ipscout"))
if err != nil {
c.Config.Logger.Error("failed to create cache", "error", err)

Expand All @@ -125,14 +110,7 @@ func (c *Client) Delete(keys []string) error {
}

func (c *Client) Get(key string, raw bool) error {
homeDir, err := homedir.Dir()
if err != nil {
c.Config.Logger.Error("failed to get home directory", "error", err)

os.Exit(1)
}

db, err := cache.Create(c.Config.Logger, filepath.Join(homeDir, ".config", "ipscout"))
db, err := cache.Create(c.Config.Logger, filepath.Join(c.Config.Config.Global.HomeDir, ".config", "ipscout"))
if err != nil {
c.Config.Logger.Error("failed to create cache", "error", err)

Expand Down
10 changes: 1 addition & 9 deletions process/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import (
"github.com/jonhadfield/ipscout/providers/ipurl"
"github.com/jonhadfield/ipscout/providers/shodan"
"github.com/jonhadfield/ipscout/session"
"github.com/mitchellh/go-homedir"
"golang.org/x/sync/errgroup"
)

Expand Down Expand Up @@ -121,14 +120,7 @@ type Processor struct {
}

func (p *Processor) Run() {
homeDir, err := homedir.Dir()
if err != nil {
p.Session.Logger.Error("failed to get home directory", "error", err)

os.Exit(1)
}

db, err := cache.Create(p.Session.Logger, filepath.Join(homeDir, ".config", "ipscout"))
db, err := cache.Create(p.Session.Logger, filepath.Join(p.Session.Config.Global.HomeDir, ".config", "ipscout"))
if err != nil {
p.Session.Logger.Error("failed to create cache", "error", err)

Expand Down
41 changes: 40 additions & 1 deletion providers/abuseipdb/abuseipdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,45 @@ func (c *Client) GetConfig() *session.Session {
return &c.Session
}

func (c *Client) Rate(findRes []byte) (providers.RateResult, error) {
var doc HostSearchResult

var rateResult providers.RateResult

if err := json.Unmarshal(findRes, &doc); err != nil {
return providers.RateResult{}, fmt.Errorf("error unmarshalling find result: %w", err)
}

if doc.Data.IsTor {
rateResult.Score += 7
rateResult.Reasons = []string{"TOR node"}
}

rateResult.Score = doc.Data.AbuseConfidenceScore / 10
rateResult.Reasons = append(rateResult.Reasons, fmt.Sprintf("confidence: %.2f", doc.Data.AbuseConfidenceScore))

switch {
case rateResult.Score >= 10:
rateResult.Threat = "very high"
rateResult.Score = 10
case rateResult.Score >= 7:
rateResult.Threat = "high"
case rateResult.Score >= 5:
rateResult.Threat = "medium"
case rateResult.Score >= 3:
rateResult.Threat = "low"
default:
rateResult.Threat = "low"
rateResult.Score = 3
}

if doc.Data.IPAddress != "" {
rateResult.Detected = true
}

return rateResult, nil
}

type Client struct {
session.Session
}
Expand Down Expand Up @@ -370,7 +409,7 @@ type HostSearchResult struct {
IsPublic bool `json:"isPublic,omitempty"`
IPVersion int `json:"ipVersion,omitempty"`
IsWhitelisted bool `json:"isWhitelisted,omitempty"`
AbuseConfidenceScore int `json:"abuseConfidenceScore,omitempty"`
AbuseConfidenceScore float64 `json:"abuseConfidenceScore,omitempty"`
CountryCode string `json:"countryCode,omitempty"`
CountryName string `json:"countryName,omitempty"`
UsageType string `json:"usageType,omitempty"`
Expand Down
Loading

0 comments on commit 2d7a2cd

Please sign in to comment.