Skip to content

Commit

Permalink
Feature/47 update http url field in agent target to address url (#49)
Browse files Browse the repository at this point in the history
Co-authored-by: Maarten de Kruijf <MaartendeKruijf@users.noreply.github.com>
Co-authored-by: Maarten de Kruijf <maarten.dekruijf@tno.nl>
  • Loading branch information
3 people authored Mar 14, 2024
1 parent dd68696 commit 6e2b957
Show file tree
Hide file tree
Showing 17 changed files with 142 additions and 70 deletions.
2 changes: 1 addition & 1 deletion internal/capability/ssh/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (sshCapability *SshCapability) Execute(metadata execution.Metadata,
return results, err
}

func CombinePortAndAddress(addresses map[string][]string, port string) string {
func CombinePortAndAddress(addresses map[cacao.NetAddressType][]string, port string) string {
if port == "" {
port = "22"
}
Expand Down
40 changes: 26 additions & 14 deletions models/cacao/cacao.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ const (
CACAO_VERSION_2 = "cacao-2.0"
)

// Custom type intended for AgentTarget.Address dict keys
// not used at the moment as it would break a few things
type NetAddressType string

const (
DName NetAddressType = "dname"
IPv4 NetAddressType = "ipv4"
IPv6 NetAddressType = "ipv6"
L2Mac NetAddressType = "l2mac"
VLan NetAddressType = "vlan"
Url NetAddressType = "url"
)

type (
Extensions map[string]interface{}
Workflow map[string]Step
Expand Down Expand Up @@ -94,20 +107,19 @@ type Contact struct {
}

type AgentTarget struct {
ID string `bson:"id,omitempty" json:"id,omitempty"`
Type string `bson:"type" json:"type" validate:"required"`
Name string `bson:"name" json:"name" validate:"required"`
Description string `bson:"description,omitempty" json:"description,omitempty"`
Location CivicLocation `bson:"location,omitempty" json:"location,omitempty"`
AgentTargetExtensions Extensions `bson:"agent_target_extensions,omitempty" json:"agent_target_extensions,omitempty"`
Contact Contact `bson:"contact,omitempty" json:"contact,omitempty"`
Logical []string `bson:"logical,omitempty" json:"logical,omitempty"`
Sector string `bson:"sector,omitempty" json:"sector,omitempty"`
HttpUrl string `bson:"http_url,omitempty" json:"http_url,omitempty"`
AuthInfoIdentifier string `bson:"authentication_info,omitempty" json:"authentication_info,omitempty"`
Category []string `bson:"category,omitempty" json:"category,omitempty"`
Address map[string][]string `bson:"address,omitempty" json:"address,omitempty"`
Port string `bson:"port,omitempty" json:"port,omitempty"`
ID string `bson:"id,omitempty" json:"id,omitempty"`
Type string `bson:"type" json:"type" validate:"required"`
Name string `bson:"name" json:"name" validate:"required"`
Description string `bson:"description,omitempty" json:"description,omitempty"`
Location CivicLocation `bson:"location,omitempty" json:"location,omitempty"`
AgentTargetExtensions Extensions `bson:"agent_target_extensions,omitempty" json:"agent_target_extensions,omitempty"`
Contact Contact `bson:"contact,omitempty" json:"contact,omitempty"`
Logical []string `bson:"logical,omitempty" json:"logical,omitempty"`
Sector string `bson:"sector,omitempty" json:"sector,omitempty"`
AuthInfoIdentifier string `bson:"authentication_info,omitempty" json:"authentication_info,omitempty"`
Category []string `bson:"category,omitempty" json:"category,omitempty"`
Address map[NetAddressType][]string `bson:"address,omitempty" json:"address,omitempty"`
Port string `bson:"port,omitempty" json:"port,omitempty"`
}

type AuthenticationInformation struct {
Expand Down
20 changes: 5 additions & 15 deletions models/validator/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ type Empty struct{}
var component = reflect.TypeOf(Empty{}).PkgPath()
var log *logger.Log

var cacao_v1_csd01_http string = "https://raw.githubusercontent.com/cyentific-rni/cacao-json-schemas/cacao-v1.0-csd02/schemas/playbook.json"
var cacao_v2_csd01_http string = "https://raw.githubusercontent.com/cyentific-rni/cacao-json-schemas/cacao-v2.0-csd01/schemas/playbook.json"
var oca_cacao_schemas string = "https://raw.githubusercontent.com/opencybersecurityalliance/cacao-roaster/main/lib/cacao-json-schemas/schemas/playbook.json"

//var cacao_v2_csd03_http string = "https://raw.githubusercontent.com/cyentific-rni/cacao-json-schemas/cacao-v2.0-csd03/schemas/playbook.json"
//var oasis_cacao_schemas string = "https://raw.githubusercontent.com/oasis-open/cacao-json-schemas/main/schemas/playbook.json"
//var cyentific_cacao_schemas string = "https://raw.githubusercontent.com/cyentific-rni/cacao-json-schemas/cacao-v2.0-csd03/schemas/playbook.json"

func init() {
log = logger.Logger(component, logger.Info, "", logger.Json)
Expand All @@ -45,11 +45,7 @@ func UnmarshalJson[BodyType any](b *[]byte) (any, error) {
return body, nil
}

// TODO: change return to just error as boolean does not provide additional info

func IsValidCacaoJson(data []byte) error {
// NOTE: Using cacao-v2.0-csd01 instead of cacao-v2.0-csd03
// Because latest version seem to have a bug. Opened issue in repo

var rawJson map[string]interface{}
if err := json.Unmarshal([]byte(data), &rawJson); err != nil {
Expand All @@ -65,15 +61,9 @@ func IsValidCacaoJson(data []byte) error {
var err error
switch version {
case cacao.CACAO_VERSION_1:
sch, err = compiler.Compile(cacao_v1_csd01_http)
if err != nil {
return err
}
return errors.New("you submitted a cacao v1 playbook. at the moment, soarca only supports cacao v2 playbooks")
case cacao.CACAO_VERSION_2:
// NOTE: CURRENTLY THERE IS AN INCONSISTENCY BETWEEN CDS01 AND CDS03
// The cds03 schema is bugged at the time being (13/11/2023)
// So we cannot validate checking authentication information
sch, err = compiler.Compile(cacao_v2_csd01_http)
sch, err = compiler.Compile(oca_cacao_schemas)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/capability/ssh/ssh_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestSshConnection(t *testing.T) {

expectedTarget := cacao.AgentTarget{
Type: "ssh",
Address: map[string][]string{"ipv4": {"localhost"}},
Address: map[cacao.NetAddressType][]string{"ipv4": {"localhost"}},
// Port: "22",
AuthInfoIdentifier: "some-authid-1",
}
Expand Down
2 changes: 1 addition & 1 deletion test/unittest/cacao/cacao_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func TestCacaoDecode(t *testing.T) {
assert.Equal(t, workflow.AgentDefinitions["http-api--7e9174ec-a293-43df-a72d-471c79e276bf"].Name, "Firewall 1")
assert.Equal(t, workflow.AgentDefinitions["http-api--7e9174ec-a293-43df-a72d-471c79e276bf"].ID, "http-api--7e9174ec-a293-43df-a72d-471c79e276bf")
assert.Equal(t, workflow.AgentDefinitions["http-api--7e9174ec-a293-43df-a72d-471c79e276bf"].Type, "http-api")
assert.Equal(t, workflow.AgentDefinitions["http-api--7e9174ec-a293-43df-a72d-471c79e276bf"].HttpUrl, "hxxp://example.com/v1/")
assert.Equal(t, workflow.AgentDefinitions["http-api--7e9174ec-a293-43df-a72d-471c79e276bf"].Address["dname"][0], "hxxp://example.com/v1/")
assert.Equal(t, workflow.AgentDefinitions["http-api--7e9174ec-a293-43df-a72d-471c79e276bf"].Location.Name, "Eindhoven")

assert.Equal(t, workflow.AuthenticationInfoDefinitions["http-basic--76c26f7f-9a15-40ff-a90a-7b19e23372ae"].ID, "http-basic--76c26f7f-9a15-40ff-a90a-7b19e23372ae")
Expand Down
1 change: 1 addition & 0 deletions test/unittest/cacao/playbooks/infinite_playbook.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"agent_definitions": {
"individual--6b23a237-ade8-4d00-9aa1-75999732d557": {
"name": "banana rama",
"type": "individual",
"banana": "rama"
}
}
Expand Down
5 changes: 4 additions & 1 deletion test/unittest/cacao/playbooks/invalid_email_playbook.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
"http-api--7e9174ec-a293-43df-a72d-471c79e276bf": {
"type": "http-api",
"name": "Firewall 1",
"http_url": "hxxp://example.com/v1/",
"address": {
"dname": ["hxxp://example.com/v1/"]
},
"authentication_info": "http-basic--76c26f7f-9a15-40ff-a90a-7b19e23372ae",
"category": [
"firewall"
Expand All @@ -40,6 +42,7 @@
},
"individual--6b23a237-ade8-4d00-9aa1-75999732d557": {
"name": "banana rama",
"type": "individual",
"banana": "rama",
"contact" : {
"email" : {
Expand Down
16 changes: 10 additions & 6 deletions test/unittest/cacao/playbooks/invalid_playbook.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@
"password": "super-secure-password"
}
},
"agents": {
"agent_definitions": {
"http-api--7e9174ec-a293-43df-a72d-471c79e276bf": {

"type": "invalid",
"name": "Firewall 1",
"http_url": "hxxp://example.com/v1/",
"address": {
"dname": ["hxxp://example.com/v1/"]
},

"authentication_info": "http-basic--76c26f7f-9a15-40ff-a90a-7b19e23372ae",
"category": [
"firewall"
Expand Down Expand Up @@ -61,7 +65,7 @@
"command": "GET http://__imc_address__/by/__cve__"
}
],
"agent": "individual--6b23a237-ade8-4d00-9aa1-75999732d557"
"agent": "http-api--7e9174ec-a293-43df-a72d-471c79e276bf"
},
"action--9fcc5c3b-0b70-4d73-b922-cf5491dcd1a4": {
"type": "action",
Expand All @@ -74,7 +78,7 @@
"command": "GET http://__bia_address__/analysisreport/__cve__"
}
],
"agent": "individual--6b23a237-ade8-4d00-9aa1-75999732d557"
"agent": "http-api--7e9174ec-a293-43df-a72d-471c79e276bf"
},
"action--09b97fab-56a1-45dc-a88f-be3cde3eac33": {
"type": "action",
Expand All @@ -87,7 +91,7 @@
"command": "GET http://__coagenerator_address__/coa/__assetuuid__"
}
],
"agent": "individual--6b23a237-ade8-4d00-9aa1-75999732d557"
"agent": "http-api--7e9174ec-a293-43df-a72d-471c79e276bf"
},
"action--2190f685-1857-44ac-ad0e-0ded6c6ef3ce": {
"type": "action",
Expand All @@ -100,7 +104,7 @@
"command": "GET http://__bia_address__/analysisreport/__coa_list__"
}
],
"agent": "individual--6b23a237-ade8-4d00-9aa1-75999732d557"
"agent": "http-api--7e9174ec-a293-43df-a72d-471c79e276bf"
},
"end--6b23c237-ade8-4d00-9aa1-75999738d557": {
"type": "end",
Expand Down
1 change: 1 addition & 0 deletions test/unittest/cacao/playbooks/missing_step_playbook.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
"agent_definitions": {
"individual--6b23a237-ade8-4d00-9aa1-75999732d557": {
"name": "banana rama",
"type": "individual",
"banana": "rama"
}
}
Expand Down
1 change: 1 addition & 0 deletions test/unittest/cacao/playbooks/parallels_playbook.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"agent_definitions": {
"individual--6b23a237-ade8-4d00-9aa1-75999732d557": {
"name": "banana rama",
"type": "individual",
"banana": "rama"
}
}
Expand Down
5 changes: 4 additions & 1 deletion test/unittest/cacao/playbooks/playbook.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
"http-api--7e9174ec-a293-43df-a72d-471c79e276bf": {
"type": "http-api",
"name": "Firewall 1",
"http_url": "hxxp://example.com/v1/",
"address": {
"dname": ["hxxp://example.com/v1/"]
},
"authentication_info": "http-basic--76c26f7f-9a15-40ff-a90a-7b19e23372ae",
"category": [
"firewall"
Expand All @@ -40,6 +42,7 @@
},
"individual--6b23a237-ade8-4d00-9aa1-75999732d557": {
"name": "banana rama",
"type": "individual",
"banana": "rama",
"contact": {
"email": {
Expand Down
8 changes: 6 additions & 2 deletions test/unittest/cacao/validators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/go-playground/assert/v2"
)

func TestNotValidCacaoJson(t *testing.T) {
func TestNotValidCacaoJsonInvalidAgentTargetType(t *testing.T) {
jsonFile, err := os.Open(PB_PATH + "invalid_playbook.json")
if err != nil {
fmt.Println(err)
Expand All @@ -24,9 +24,13 @@ func TestNotValidCacaoJson(t *testing.T) {
byteValue, _ := io.ReadAll(jsonFile)
errValid := validator.IsValidCacaoJson(byteValue)
if errValid == nil {
fmt.Println(errValid)
t.Fail()
}

t.Log(errValid)
expected := "value must be \"http-api\""
assert.Equal(t, strings.Contains(fmt.Sprint(errValid), expected), true)

}

func TestValidCacaoJson(t *testing.T) {
Expand Down
4 changes: 3 additions & 1 deletion test/unittest/capability/openc2/openc2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ func TestOpenC2Request(t *testing.T) {
stepId, _ := uuid.Parse("81eff59f-d084-4324-9e0a-59e353dbd28f")

target := cacao.AgentTarget{
HttpUrl: "https://soarca.tno.nl",
Address: map[cacao.NetAddressType][]string{
"url": {"https://soarca.tno.nl"},
},
AuthInfoIdentifier: authId.String(),
}

Expand Down
8 changes: 4 additions & 4 deletions test/unittest/capability/ssh/ssh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,29 +76,29 @@ func TestAuthenticationValidationPrivateKeyAuthSpacesAsUser(t *testing.T) {
}

func TestAddressAndPortCombination(t *testing.T) {
ipv4 := map[string][]string{"ipv4": {"134.221.49.62"}}
ipv4 := map[cacao.NetAddressType][]string{"ipv4": {"134.221.49.62"}}
port := "22"
expectedFqdn := "134.221.49.62:22"
result := ssh.CombinePortAndAddress(ipv4, port)
assert.Equal(t, result, expectedFqdn)
}
func TestAddressAndPortCombinationNoPort(t *testing.T) {
ipv4 := map[string][]string{"ipv4": {"134.221.49.62"}}
ipv4 := map[cacao.NetAddressType][]string{"ipv4": {"134.221.49.62"}}
port := ""
expectedFqdn := "134.221.49.62:22"
result := ssh.CombinePortAndAddress(ipv4, port)
assert.Equal(t, result, expectedFqdn)
}

func TestAddressAndPortCombinationNoAddress(t *testing.T) {
ipv4 := map[string][]string{}
ipv4 := map[cacao.NetAddressType][]string{}
port := "22"
expectedFqdn := ""
result := ssh.CombinePortAndAddress(ipv4, port)
assert.Equal(t, result, expectedFqdn)
}
func TestAddressAndPortCombinationNoIpv4Address(t *testing.T) {
ipv4 := map[string][]string{"invallid": {"feed::0001"}}
ipv4 := map[cacao.NetAddressType][]string{"invallid": {"feed::0001"}}
port := "22"
expectedFqdn := ""
result := ssh.CombinePortAndAddress(ipv4, port)
Expand Down
5 changes: 4 additions & 1 deletion test/unittest/routes/playbook.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
"http-api--7e9174ec-a293-43df-a72d-471c79e276bf": {
"type": "http-api",
"name": "Firewall 1",
"http_url": "hxxp://example.com/v1/",
"address": {
"dname": ["hxxp://example.com/v1/"]
},
"authentication_info": "http-basic--76c26f7f-9a15-40ff-a90a-7b19e23372ae",
"category": [
"firewall"
Expand All @@ -40,6 +42,7 @@
},
"individual--6b23a237-ade8-4d00-9aa1-75999732d557": {
"name": "banana rama",
"type": "individual",
"banana": "rama"
}
},
Expand Down
Loading

0 comments on commit 6e2b957

Please sign in to comment.