Go to file
Christopher Talib b1ca4b3c5f Shodan in Dgraph, first part
Implementing first version for shodan node, missing yet some models, but
the overal approach works and can be queried in Ratel.
2020-05-18 16:09:04 +02:00
balboa Implementing config variables in the application 2020-02-10 16:11:25 +01:00
broker Shodan in Dgraph, first part 2020-05-18 16:09:04 +02:00
elasticsearch Adding code and setting up elastic search 2020-02-17 12:08:49 +01:00
filters Shodan in Dgraph, first part 2020-05-18 16:09:04 +02:00
graph Shodan in Dgraph, first part 2020-05-18 16:09:04 +02:00
models Shodan in Dgraph, first part 2020-05-18 16:09:04 +02:00
plugins Shodan in Dgraph, first part 2020-05-18 16:09:04 +02:00
utils Enh/modular arch 2020-02-25 10:05:31 +01:00
.gitignore Adding configuration documentation and the config file in the gitignore 2020-02-10 14:40:33 +01:00
connectors_test.go First work on test for connection to CertStream 2020-01-26 17:27:40 +01:00
docker-compose.yml Adding docker-compose for dgraph 2020-05-13 11:51:54 +02:00
go.mod saving 2020-03-19 09:27:15 +01:00
go.sum saving 2020-03-19 09:27:15 +01:00
main.go Shodan in Dgraph, first part 2020-05-18 16:09:04 +02:00
main_test.go First work on test for connection to CertStream 2020-01-26 17:27:40 +01:00
README.md Shodan in Dgraph, first part 2020-05-18 16:09:04 +02:00

Styx

IMPORTANT

For development purposes, each time you restart Styx, the database and the schema is dropped. Currently, this is hardcoded and used to make development easier. Just so you know.

Prerequisites

Styx uses a couple of other services to run:

  • Kafka for messaging (not implemented yet in the docker, but currently not necessary)
  • Dgraph for graph representation of results
  • Docker-compose to launch everything

For that purposes, there is a docker-compose.yml file that you can spin up with the following command when in the directory:

docker-compose up -d

Note: for some reasons, OpenVPN blocks the establishment of the docker compose, you can alternatively run Dgraph manually as such:

docker run --rm -it -p 8080:8080 -p 9080:9080 -p 8000:8000 -v ~/dgraph:/dgraph dgraph/standalone:v20.03.0

Install

go get -u gitlab.dcso.lolcat/LABS/styx
cd $GOPATH/src/gitlab.dcso.lolcat/LABS/styx
go build
docker-compose up -d # or the other command
./styx

Note: if you have issues with the docker compose, make sure it runs on the same subnet. Check this for inspiration.

Example configuration:

certstream:
activated: true

pastebin:
activated: true

shodan:
activated: true
key: "SHODAN_KEY"
ports:
- 80
- 443

kafka:
activated: true
protocol: "tcp"
host: "localhost"
port: 9092
topic: "styx"
partition: 0

balboa:
# the url you tunneled to Balboa
url: http://127.0.0.1:8030
activated: true

elasticsearch:
activated: true
url: http://localhost:9200
index: "pastebin"

Dgraph Interface

You can connect to the Dgraph interface at this default address: localhost:8000. There you would be able to run GraphQL+ queries, here to query a node.

query {
    Node(func: eq(id, "node--cde8decb-0a8b-4d19-bd77-c2decb6dab9c")) {
        uid
            ndata
            modified
            type
            id
    }
}

Or filter node by type, this example works for certstream nodes:

query {
    Node(func: eq(type, "certstream")) {
        uid
            created
            modified
            type
            ndata
            certNode {
      uid
      fingerprint
      cn
      raw {
        uid
        id
      }
      chain {
        uid
        id
      }
      sourceName
      serialNumber
      basicConstrains
      notBefore
      notAfter
    }
    shodanNode {
        uid
            hostData {
                product
                ip
                version
                hostnames
                port
                html
            }
    }
  }
}

Datastructure

Meta

Node --[Edge]-- Node

type Node struct {
	ID       string `json:"id"`
	Type     string `json:"type"`
	Data     string `json:"data"` // For plain Node, the data is the ID of another typed node or a unique value like a domain or a host name.
	Created  string `json:"created"`
	Modified string `json:"modified"`
}

// Edge defines a relation between two nodes.
type Edge struct {
	ID        string `json:"id"`
	NodeOneID string `json:"nodeOneID"`
	NodeTwoID string `json:"nodeTwoID"`
	Timestamp string `json:"timestamp"`
	Source    string `json:"source"`
}

Certstream

Node --[Edge]-- CertNode --[Edge]-- CertStreamRaw Node(domain) --[Edge]-- CertNode


// CertStreamRaw is a wrapper around the stream function to unmarshall the
// data receive in a Go structure.
type CertStreamRaw struct {
	ID       string           `json:"id"`
	Type     string           `json:"type"`
	Data     CertStreamStruct `json:"data"`
	Created  string           `json:"created"`
	Modified string           `json:"modified"`
}

// CertNode represents our custom struct of data extraction from CertStream.
type CertNode struct {
	ID               string     `json:"id"`
	Fingerprint      string     `json:"fingerprint"`
	NotBefore        string     `json:"notBefore"`
	NotAfter         string     `json:"notAfter"`
	CN               string     `json:"cn"`
	SourceName       string     `json:"sourceName"`
	SerialNumber     string     `json:"serialNumber"`
	BasicConstraints string     `json:"basicConstraints"`
	RawUUID          string     `json:"rawUUID"`
	Chain            []CertNode `json:"chainedTo"`
}

Pastebin

Node --[Edge]-- PasteNode --[Edge]-- FullPaste

// PasteNode is a node from PasteBin.
type PasteNode struct {
	ID       string    `json:"id"`
	Type     string    `json:"type"`
	Data     FullPaste `json:"data"`
	Created  string    `json:"create"`
	Modified string    `json:"modified"`
}

// FullPaste wrapes meta and information from Pastebin.
type FullPaste struct {
	Meta PasteMeta `json:"meta"`
	Full string    `json:"full"`
}

Shodan

Node --[Edge]-- ShodanNode --[Edge]-- Node(s) (hostnames and domains)

type ShodanNode struct {
	ID       string           `json:"id"`
	Type     string           `json:"type"`
	Data     *shodan.HostData `json:"data"`
	Created  string           `json:"created"`
	Modified string           `json:"modified"`
}

Balboa

Balboa enrichment happens on domains and hostnames extracted from Certstream and Shodan streams and the node is created only if Balboa returns data.

Node --[Edge]-- ShodanNode --[Edge]-- Node (domain) --[Edge]-- BalboaNode

type BalboaNode struct {
	ID       string           `json:"id"`
	Type     string           `json:"type"`
	Data     []balboa.Entries `json:"data"`
	Created  string           `json:"created"`
	Modified string           `json:"modified"`
}