Skip to content

Commit db35acc

Browse files
committed
feat: pass metadata & general improvements
1 parent 25bdf47 commit db35acc

File tree

8 files changed

+71
-15
lines changed

8 files changed

+71
-15
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,7 @@ testers
1111
/goctopus
1212

1313
dist/
14-
.env
14+
.env
15+
16+
# root go files (often used for testing / prototyping)
17+
/*.go

pkg/address/address.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package address
22

3+
import "strings"
4+
35
type Addr struct {
4-
Address string
5-
Source string
6+
Address string
7+
Source string
8+
Metadata map[string]string
69
}
710

811
func New(address string) *Addr {
912
return &Addr{
10-
Address: address,
11-
Source: address,
13+
Address: address,
14+
Source: address,
15+
Metadata: map[string]string{},
1216
}
1317
}
1418

@@ -19,3 +23,19 @@ func NewSourced(address, source string) *Addr {
1923
Source: source,
2024
}
2125
}
26+
27+
func (a *Addr) AddMetadata(key, value string) {
28+
a.Metadata[key] = value
29+
}
30+
31+
func (a *Addr) Copy() *Addr {
32+
metadataCopy := make(map[string]string)
33+
for k, v := range a.Metadata {
34+
metadataCopy[k] = v
35+
}
36+
return &Addr{
37+
Address: strings.Clone(a.Address),
38+
Source: strings.Clone(a.Source),
39+
Metadata: metadataCopy,
40+
}
41+
}

pkg/config/config.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func LoadFromArgs() {
7676
log.SetLevel(log.ErrorLevel)
7777
}
7878

79-
if err := ValidateConfig(&config); err != nil {
79+
if err := validateConfig(&config, true); err != nil {
8080
log.Error(err)
8181
flag.PrintDefaults()
8282
os.Exit(1)
@@ -85,7 +85,10 @@ func LoadFromArgs() {
8585
c = &config
8686
}
8787

88-
func ValidateConfig(conf *Config) error {
88+
// Validates the config.
89+
// `cli` is used to determine if the config is loaded from the CLI or from a file.
90+
// If cli is false, then the addresses check is skipped.
91+
func validateConfig(conf *Config, isCli bool) error {
8992
if conf.MaxWorkers < 1 {
9093
return errors.New("[Invalid config] Max workers must be greater than 0")
9194
}
@@ -98,15 +101,15 @@ func ValidateConfig(conf *Config) error {
98101
return errors.New("[Invalid config] Introspection has to be enabled to use field suggestion fingerprinting")
99102
}
100103

101-
if conf.InputFile == "" && len(conf.Addresses) == 0 {
104+
if isCli && c.InputFile == "" && len(c.Addresses) == 0 {
102105
return errors.New("[Invalid config] Please specify an input file or a list of addresses")
103106
}
104107

105108
return nil
106109
}
107110

108111
func Load(config *Config) {
109-
if err := ValidateConfig(config); err != nil {
112+
if err := validateConfig(config, false); err != nil {
110113
log.Error(err)
111114
flag.PrintDefaults()
112115
os.Exit(1)

pkg/domain/enumeration.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import (
1111

1212
func makeCallback(domain *address.Addr, subDomains chan *address.Addr) func(s *resolve.HostEntry) {
1313
return func(s *resolve.HostEntry) {
14-
subDomains <- address.NewSourced(s.Host, domain.Source)
14+
addr := domain.Copy()
15+
addr.Address = s.Host
16+
subDomains <- addr
1517
}
1618
}
1719

pkg/domain/fingerprint.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func FingerprintSubDomain(domain *address.Addr) (*output.FingerprintOutput, erro
4848
}
4949
output.Domain = domain.Address
5050
output.Source = domain.Source
51+
output.Metadata = domain.Metadata
5152
return output, nil
5253
}
5354
return nil, errors.New("no graphql endpoint found")

pkg/goctopus/fingerprint.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func worker(addresses chan *address.Addr, output chan *output.FingerprintOutput,
1717
log.Debugf("Worker %d instantiated", workerId)
1818
for address := range addresses {
1919
log.Debugf("Worker %d started on: %v", workerId, address)
20-
res, err := FingerprintAddress(address)
20+
res, err := fingerprintAddress(address)
2121
if err == nil {
2222
log.Debugf("Worker %d found endpoint: %v", workerId, res)
2323
output <- res
@@ -26,7 +26,10 @@ func worker(addresses chan *address.Addr, output chan *output.FingerprintOutput,
2626
log.Debugf("Worker %d finished", workerId)
2727
}
2828

29-
func FingerprintAddress(address *address.Addr) (*output.FingerprintOutput, error) {
29+
/**
30+
* Fingerprint an address, without subdomain enumeration
31+
*/
32+
func fingerprintAddress(address *address.Addr) (*output.FingerprintOutput, error) {
3033
// If the domain is a url, we don't need to crawl it
3134
if utils.IsUrl(address.Address) {
3235
return endpoint.FingerprintEndpoint(address)
@@ -65,6 +68,6 @@ func FingerprintAddresses(addresses chan *address.Addr, output chan *output.Fing
6568
close(enumeratedAddresses)
6669
log.Debugf("Waiting for workers to finish...")
6770
workersWg.Wait()
68-
close(output)
6971
log.Debugf("All workers finished")
72+
close(output)
7073
}

pkg/goctopus/single_address.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package goctopus
2+
3+
import (
4+
"github.com/Escape-Technologies/goctopus/pkg/address"
5+
out "github.com/Escape-Technologies/goctopus/pkg/output"
6+
)
7+
8+
// Fingerprints a single address and outputs a slice of FingerprintOutput.
9+
func FingerprintAddress(addr *address.Addr) []*out.FingerprintOutput {
10+
outputSlice := make([]*out.FingerprintOutput, 0)
11+
output := make(chan *out.FingerprintOutput, 1)
12+
addresses := make(chan *address.Addr, 1)
13+
addresses <- addr
14+
close(addresses)
15+
go FingerprintAddresses(addresses, output)
16+
for fingerprintOutput := range output {
17+
outputSlice = append(outputSlice, fingerprintOutput)
18+
}
19+
return outputSlice
20+
}

pkg/output/output.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ type FingerprintResult string
1212
const (
1313
ResultOpenGraphql FingerprintResult = "OPEN_GRAPHQL"
1414
ResultAuthentifiedGraphql FingerprintResult = "AUTHENTIFIED_GRAPHQL"
15-
// ResultMaybeGraphql FingerprintResult = "MAYBE_GRAPHQL"
1615
)
1716

1817
type FingerprintOutput struct {
@@ -21,7 +20,8 @@ type FingerprintOutput struct {
2120
Url string `json:"url"`
2221
Introspection bool `json:"introspection"`
2322
FieldSuggestion bool `json:"field_suggestion"`
24-
Source string `json:"source"` // the original address used to fingerprint the endpoint
23+
Source string `json:"source"` // the original address used to fingerprint the endpoint
24+
Metadata map[string]string `json:"metadata"` // optional metadata
2525
}
2626

2727
func (o *FingerprintOutput) MarshalJSON() ([]byte, error) {
@@ -56,5 +56,9 @@ func marshalOutput(o *FingerprintOutput, c *config.Config) ([]byte, error) {
5656
outputMap["domain"] = utils.DomainFromUrl(o.Url)
5757
}
5858

59+
if o.Metadata == nil || len(o.Metadata) == 0 {
60+
delete(outputMap, "metadata")
61+
}
62+
5963
return json.Marshal(outputMap)
6064
}

0 commit comments

Comments
 (0)