cortex

package module
v3.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 25, 2019 License: AGPL-3.0 Imports: 17 Imported by: 1

README

GoDoc Build Status Codacy Badge Coverage Status

Cortex client library

Usage example

Get the latest library version:

go get -u github.com/ilyaglow/go-cortex

Simply run analyzer for an observable

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/ilyaglow/go-cortex"
)

func main() {
	crtx, err := cortex.NewClient("http://127.0.0.1:9001/", &cortex.ClientOpts{
		Auth: &cortex.APIAuth{
			APIKey: "YOUR-API-KEY",
		},
	})
	if err != nil {
		log.Fatal(err)
	}

	rep, err := crtx.Analyzers.Run(context.Background(), "MaxMind_GeoIP_3_0", &cortex.Task{
		Data:     "1.1.1.1",
		DataType: "ip",
		TLP:      &cortex.TLPGreen,
		PAP:      &cortex.PAPGreen,
	}, time.Minute*5)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%v\n", rep)
}

Aggregated analysis of an observable

Could be used to analyze an observable by all analyzers that can process it's data type at once.

You should use callback functions to set an action for each analyzer, when one returns a report or an error. Take a look at the following example:

package main

import (
	"context"
	"log"
	"os"
	"time"

	"github.com/ilyaglow/go-cortex"
)

func main() {
	crtx, err := cortex.NewClient("http://127.0.0.1:9001/", &cortex.ClientOpts{
		Auth: &cortex.APIAuth{
			APIKey: "YOUR-API-KEY",
		},
	})
	if err != nil {
		log.Fatal(err)
	}

	task := &cortex.Task{
		Data: "1.1.1.1",
		DataType: "ip",
		TLP: &cortex.TLPWhite,
		PAP: &cortex.PAPWhite,
	}

	// Create a new MultiRun struct with at most 5 minute timeout for the run
	mul := crtx.Analyzers.NewMultiRun(context.Background(), 5*time.Minute)

	// Handle each analyzer's report
	mul.OnReport = func(r *cortex.Report) {
		log.Println(r)
	}
	// Log each analyzer's error
	mul.OnError = func(e error, o cortex.Observable, a *cortex.Analyzer) {
		log.Printf("Cortex analyzer %s failed on data %s with an error: %s", a.Name, o.Description(), e.Error())
	}

	// Actually run the analysis
	err = mul.Do(task)
	if err != nil {
		log.Fatal(err)
	}
}

Documentation

Overview

Package cortex is the client library for Cortex v2 API. Link: https://github.com/TheHive-Project/Cortex.

Check out Cortex v2 documentation: https://github.com/TheHive-Project/CortexDocs

Index

Constants

View Source
const (
	// TxSafe is a safe taxonomy level
	TxSafe = "safe"

	// TxInfo is an info taxonomy level
	TxInfo = "info"

	// TxSuspicious is a suspicious taxonomy level
	TxSuspicious = "suspicious"

	// TxMalicious is a malicious taxonomy level
	TxMalicious = "malicious"
)
View Source
const (

	// APIRoute represents a prefix path
	APIRoute = "api"
)

Variables

View Source
var (

	// DefaultInput represents an analyzer or responder input that is used by
	// default
	DefaultInput = os.Stdin
)
View Source
var Rxs = map[string]*regexp.Regexp{
	"cc":              rxCC,
	"ipv4":            rxIPv4,
	"ipv6":            rxIPv6,
	"domain":          rxDomain,
	"email":           rxEmail,
	"hash":            rxHash,
	"registry":        rxRegistryKey,
	"url":             rxURL,
	"user-agent":      rxUserAgent,
	"bitcoin-address": rxBitcoinAddress,
}

Rxs represents map of regexes

Functions

This section is empty.

Types

type APIAuth

type APIAuth struct {
	APIKey string
}

APIAuth represents authentication by API token

func (*APIAuth) Token

func (a *APIAuth) Token() string

Token returns API key and satisfies auth interface

type Analyzer

type Analyzer struct {
	Author        string                 `json:"author"`
	BaseConfig    string                 `json:"baseConfig"`
	Configuration map[string]interface{} `json:"configuration"`
	CreatedAt     int64                  `json:"createdAt"`
	CreatedBy     string                 `json:"createdBy"`
	DataTypeList  []string               `json:"dataTypeList"`
	DefinitionID  string                 `json:"analyzerDefinitionId"`
	Description   string                 `json:"description"`
	ID            string                 `json:"id"`
	JobCache      interface{}            `json:"jobCache,omitempty"` // unknown
	License       string                 `json:"license"`
	Name          string                 `json:"name"`
	Rate          int                    `json:"rate,omitempty"`
	RateUnit      string                 `json:"rateUnit,omitempty"`
	URL           string                 `json:"url"`
	UpdatedAt     int64                  `json:"updatedAt,omitempty"`
	UpdatedBy     string                 `json:"updatedBy,omitempty"`
	Version       string                 `json:"version"`
}

Analyzer defines a specific Cortex Analyzer

type AnalyzerError

type AnalyzerError struct {
	Success      bool      `json:"success"`
	ErrorMessage string    `json:"errorMessage"`
	Input        *JobInput `json:"input"`
}

AnalyzerError is the report that analyzer app should return in case something went wrong

type AnalyzerReport

type AnalyzerReport struct {
	Artifacts  []ExtractedArtifact `json:"artifacts"`
	FullReport interface{}         `json:"full"`
	Success    bool                `json:"success"`
	Summary    *Summary            `json:"summary"`
}

AnalyzerReport is the report that analyzer app should return in case everything is okay

type AnalyzerService

AnalyzerService is an interface for managing analyzers

type AnalyzerServiceOp

type AnalyzerServiceOp struct {
	// contains filtered or unexported fields
}

AnalyzerServiceOp handles analyzer methods from Cortex API

func (*AnalyzerServiceOp) DataTypes

func (a *AnalyzerServiceOp) DataTypes(ctx context.Context) ([]string, error)

DataTypes returns all available data types that Cortex can analyse. The entries are not sorted.

func (*AnalyzerServiceOp) Get

Get a specified Cortex analyzer by its name

func (*AnalyzerServiceOp) List

List all Cortex analyzers with pagination

func (*AnalyzerServiceOp) ListByType

func (a *AnalyzerServiceOp) ListByType(ctx context.Context, t string) ([]Analyzer, *http.Response, error)

ListByType lists Cortex analyzers by datatype

func (*AnalyzerServiceOp) NewMultiRun

func (a *AnalyzerServiceOp) NewMultiRun(ctx context.Context, d time.Duration) *MultiRun

NewMultiRun is a function that bootstraps MultiRun struct

func (*AnalyzerServiceOp) Run

Run will start the observable analysis using specified analyzer, wait for a certain duration and return a report

func (*AnalyzerServiceOp) StartJob

func (a *AnalyzerServiceOp) StartJob(ctx context.Context, anid string, o Observable) (*Job, *http.Response, error)

StartJob starts observable analysis

type Artifact

type Artifact struct {
	DataType  string `json:"dataType"`
	CreatedBy string `json:"createdBy"`
	CreatedAt int64  `json:"createdAt"`
	Data      string `json:"data"`
	TLP       TLP    `json:"tlp"`
	PAP       PAP    `json:"pap"`
	ID        string `json:"id"`
}

Artifact represents an artifact

type Client

type Client struct {
	Client    *http.Client
	BaseURL   *url.URL
	UserAgent string
	Opts      *ClientOpts
	PageSize  int

	Analyzers AnalyzerService
	Users     UserService
}

Client is used to communicate with Cortex API

func NewClient

func NewClient(baseurl string, opts *ClientOpts) (*Client, error)

NewClient bootstraps a client to interact with Cortex API

func (*Client) Do

func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*http.Response, error)

Do sends an API request and returns the API response. The API response is JSON decoded and stored in the value pointed to by v, or returned as an error if an API error has occurred. If v implements the io.Writer interface, the raw response body will be written to v, without attempting to first decode it.

The provided ctx must be non-nil. If it is canceled or times out, ctx.Err() will be returned.

func (*Client) NewFileRequest

func (c *Client) NewFileRequest(method, urlStr string, body interface{}, fileName string, r io.Reader) (*http.Request, error)

NewFileRequest creates an API request with a file http form.

func (*Client) NewRequest

func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Request, error)

NewRequest creates an API request. A relative URL can be provided in urlStr, in which case it is resolved relative to the BaseURL of the Client. Relative URLs should always be specified without a preceding slash. If specified, the value pointed to by body is JSON encoded and included as the request body.

type ClientOpts

type ClientOpts struct {
	Auth       auth
	HTTPClient *http.Client
}

ClientOpts represent options that are passed to client.

type ExtractedArtifact

type ExtractedArtifact struct {
	Type  string `json:"type"`
	Value string `json:"value"`
}

ExtractedArtifact is used for artifacts with slightly different structure

func ExtractArtifacts

func ExtractArtifacts(body string) []ExtractedArtifact

ExtractArtifacts extracts all artifacts from the report string

type FileTask

type FileTask struct {
	FileTaskMeta
	Reader   io.Reader
	FileName string
}

FileTask is a file to be analyzed

func (*FileTask) Description

func (f *FileTask) Description() string

Description returns a file name

func (*FileTask) Type

func (f *FileTask) Type() string

Type usually returns just a string "file" for a file task

type FileTaskMeta

type FileTaskMeta struct {
	DataType string `json:"dataType"`
	TLP      *TLP   `json:"tlp,omitempty"`
	PAP      *PAP   `json:"pap,omitempty"`
}

FileTaskMeta represents meta data of the file observable

type Job

type Job struct {
	Task
	ID                   string `json:"id"`
	AnalyzerDefinitionID string `json:"analyzerDefinitionId"`
	AnalyzerID           string `json:"analyzerID"`
	AnalyzerName         string `json:"analyzerName"`
	Status               string `json:"status"`
	Organization         string `json:"organization"`
	StartDate            int64  `json:"startDate"`
	EndDate              int64  `json:"endDate"`
	Date                 int64  `json:"date"`
	CreatedAt            int64  `json:"createdAt"`
	CreatedBy            string `json:"createdBy"`
	UpdatedAt            int64  `json:"updatedAt,omitempty"`
	UpdatedBy            string `json:"updatedBy,omitempty"`
}

Job is a sample Cortex job

type JobInput

type JobInput struct {
	DataType    string            `json:"dataType"`
	TLP         TLP               `json:"tlp,omitempty"`
	PAP         PAP               `json:"pap,omitempty"`
	Data        string            `json:"data,omitempty"`
	File        string            `json:"file,omitempty"`
	FileName    string            `json:"filename,omitempty"`
	ContentType string            `json:"contentType,omitempty"`
	Config      cfg               `json:"config,omitempty"`
	Message     string            `json:"message,omitempty"`
	Parameters  map[string]string `json:"parameters,omitempty"`
}

JobInput is used to track failed jobs and work with analyzer's input

func NewInput

func NewInput() (*JobInput, *http.Client, error)

NewInput grabs DefaultInput (stdin by default) and bootstraps *JobInput and *http.Client

func (*JobInput) PrintError

func (j *JobInput) PrintError(err error)

PrintError returns unsuccessful Report with an error message

func (*JobInput) PrintReport

func (j *JobInput) PrintReport(body interface{}, taxes []Taxonomy)

PrintReport constructs Report by raw body and taxonomies

type JobService

type JobService interface {
	Get(context.Context, string) (*Job, *http.Response, error)
	GetReport(context.Context, string) (*Report, *http.Response, error)
	WaitReport(context.Context, string, time.Duration) (*Report, *http.Response, error)
	Delete(context.Context, string) (*http.Response, error)
}

JobService is an interface for managing jobs

type JobServiceOp

type JobServiceOp struct {
	// contains filtered or unexported fields
}

JobServiceOp handles cases methods from the Cortex API

func (*JobServiceOp) Delete added in v3.1.0

func (j *JobServiceOp) Delete(ctx context.Context, jobid string) (*http.Response, error)

Delete the job from Cortex. This marks the job as Deleted. However the job's data is not removed from the database.

func (*JobServiceOp) Get

func (j *JobServiceOp) Get(ctx context.Context, jobid string) (*Job, *http.Response, error)

Get retrieves a Job by it's ID

func (*JobServiceOp) GetReport

func (j *JobServiceOp) GetReport(ctx context.Context, jobid string) (*Report, *http.Response, error)

GetReport retrieves the analysis Report by a job ID

func (*JobServiceOp) WaitReport

func (j *JobServiceOp) WaitReport(ctx context.Context, jid string, d time.Duration) (*Report, *http.Response, error)

WaitReport synchronously waits a certain job id for a specified duration of time and returns a report

type MultiRun

type MultiRun struct {
	Timeout time.Duration

	OnReport func(*Report)
	OnError  func(error, Observable, *Analyzer)
	// contains filtered or unexported fields
}

MultiRun represents configuration for running multiple analyzers

func (*MultiRun) AnalyzeFile

func (m *MultiRun) AnalyzeFile(wg *sync.WaitGroup, ft *FileTask, ans ...Analyzer) error

AnalyzeFile analyses a file observable by multiple analyzers

func (*MultiRun) AnalyzeString

func (m *MultiRun) AnalyzeString(wg *sync.WaitGroup, t *Task, ans ...Analyzer) error

AnalyzeString analyses a basic string-alike observable by multiple analyzers

func (*MultiRun) Do

func (m *MultiRun) Do(o Observable) error

Do analyzes an observable with all appropriate analyzers

type Observable

type Observable interface {
	Type() string
	Description() string
}

Observable is an interface for string type artifact and file type artifact

type PAP

type PAP uint8

PAP means Permissible Actions Protocol.

var (
	// PAPWhite represents no restrictions in using information.
	// Source: https://github.com/MISP/misp-taxonomies/blob/master/PAP/machinetag.json#L24
	PAPWhite PAP

	// PAPGreen - active actions allowed.
	// Recipients may use PAP:GREEN information to ping the target,
	// block incoming/outgoing traffic from/to the target
	// or specifically configure honeypots to interact with the target
	// Source: https://github.com/MISP/misp-taxonomies/blob/master/PAP/machinetag.json#L19
	PAPGreen PAP = 1

	// PAPAmber - passive cross check.
	// Recipients may use PAP:AMBER information for conducting online checks,
	// like using services provided by third parties (e.g. VirusTotal),
	// or set up a monitoring honeypot.
	// Source: https://github.com/MISP/misp-taxonomies/blob/master/PAP/machinetag.json#L14
	PAPAmber PAP = 2

	// PAPRed - non-detectable actions only.
	// Recipients may not use PAP:RED information on the network.
	// Only passive actions on logs, that are not detectable from the outside.
	// Source: https://github.com/MISP/misp-taxonomies/blob/master/PAP/machinetag.json#L9
	PAPRed PAP = 3
)

type Report

type Report struct {
	Job
	ReportBody ReportBody `json:"report,omitempty"`
}

Report represents a struct returned by the Cortex

func (*Report) Taxonomies

func (r *Report) Taxonomies() []Taxonomy

Taxonomies is a shortcut to get taxonomies from the report

type ReportBody

type ReportBody struct {
	Artifacts    []Artifact  `json:"artifacts,omitempty"`
	FullReport   interface{} `json:"full,omitempty"`
	Success      bool        `json:"success,omitempty"`
	Summary      Summary     `json:"summary,omitempty"`
	ErrorMessage string      `json:"errorMessage,omitempty"`
	Input        string      `json:"input,omitempty"`
}

ReportBody represents a report with analyzer results

type Summary

type Summary struct {
	Taxonomies []Taxonomy `json:"taxonomies,omitempty"`
}

Summary is a customized report object which may have taxonomies

type TLP

type TLP uint8

TLP means Traffic Light Protocol.

var (
	// TLPWhite represents non-limited disclosure.
	TLPWhite TLP

	// TLPGreen limits disclosure, restricted to the community.
	TLPGreen TLP = 1

	// TLPAmber represents limited disclosure, restricted to participants’ organizations.
	TLPAmber TLP = 2

	// TLPRed is not for disclosure, restricted to participants only.
	TLPRed TLP = 3
)

Type var is used instead of const because a pointer is needed when cortex.Task and cortex.FileTaskMeta structs are being marshalled. This will enable omitting the value and force Cortex itself to use default TLP and PAP for tasks: cortex.TLPAmber and cortex.PAPAmber.

type Task

type Task struct {
	Data       string      `json:"data,omitempty"`
	DataType   string      `json:"dataType,omitempty"`
	TLP        *TLP        `json:"tlp,omitempty"`
	PAP        *PAP        `json:"pap,omitempty"`
	Message    string      `json:"message,omitempty"`
	Parameters interface{} `json:"parameters,omitempty"`
}

Task represents a Cortex task to run

func (*Task) Description

func (t *Task) Description() string

Description returns Data of the task, satisfying an Observable interface

func (*Task) Type

func (t *Task) Type() string

Type returns DataType of the task, satisfying an Observable interface

type Taxonomy

type Taxonomy struct {
	Predicate string      `json:"predicate"`
	Namespace string      `json:"namespace"`
	Value     interface{} `json:"value"`
	Level     string      `json:"level"`
}

Taxonomy represents a taxonomy object in a report

type User

type User struct {
	Name         string   `json:"name"`
	CreatedAt    int64    `json:"createdAt"`
	Roles        []string `json:"roles"`
	CreatedBy    string   `json:"createdBy"`
	Organization string   `json:"organization"`
	Status       string   `json:"status"`
	UpdatedBy    string   `json:"updatedBy"`
	UpdatedAt    int64    `json:"updatedAt"`
	ID           string   `json:"id"`
	HasKey       bool     `json:"hasKey"`
	HasPassword  bool     `json:"hasPassword"`
}

User represents a Cortex User

type UserService

type UserService interface {
	Current(context.Context) (*User, *http.Response, error)
}

UserService is an interface for managing users

type UserServiceOp

type UserServiceOp struct {
	// contains filtered or unexported fields
}

UserServiceOp handles user specific methods from Cortex API

func (*UserServiceOp) Current

func (u *UserServiceOp) Current(ctx context.Context) (*User, *http.Response, error)

Current retrieves a current user

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL