cortex

package module
v2.3.2+incompatible Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2018 License: AGPL-3.0 Imports: 17 Imported by: 0

README

GoDoc Build Status Codacy Badge Coverage Status

[WIP] Cortex v2 client library

This version is not compatible with Cortex v1 version.

I tried to avoid limitations, pitfalls and antipatterns from the previous version, so I even changed a whole approach in a couple places. Hope you'll enjoy it.

Usage example

Get latest library

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,
	}, 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 work with it's data type at once. Previous implementation used a channel approach that seemed to me very limiting.

Now you can use callback functions when analyzer returns a report or an error.

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,
	}

	// Create new MultiRun struct
	mul := crtx.Analyzers.NewMultiRun(context.Background(), 5*time.Minute)
	mul.OnReport = func(r *cortex.Report) {
		log.Println(r)
	}
	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 (
	// TLPWhite represents non-limited disclosure.
	TLPWhite = 0

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

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

	// TLPRed is not for disclosure, restricted to participants only.
	TLPRed = 3
)
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 added in v1.1.0

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 added in v1.1.0

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) 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       int    `json:"tlp"`
	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
}

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 and API request with file 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
}

ClientOpts represent options that are passed to client

type ExtractedArtifact added in v1.1.0

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

ExtractedArtifact is used for artifacts with slightly different structure

func ExtractArtifacts added in v1.1.0

func ExtractArtifacts(body string) []ExtractedArtifact

ExtractArtifacts extracts all artifacts from 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 "file" for a file task

type FileTaskMeta

type FileTaskMeta struct {
	DataType string `json:"dataType"`
	TLP      *int   `json:"tlp,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         int               `json:"tlp,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 added in v1.1.0

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

NewInput grabs stdin 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)
}

JobService is an interface for managing jobs

type JobServiceOp

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

JobServiceOp handles cases methods from TheHive API

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 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 added in v1.1.0

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

Summary is a customized report object which may have taxonomies

type Task

type Task struct {
	Data       string      `json:"data,omitempty"`
	DataType   string      `json:"dataType,omitempty"`
	TLP        *int        `json:"tlp,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

Jump to

Keyboard shortcuts

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