diff --git a/go.mod b/go.mod
@@ -5,6 +5,7 @@ go 1.23
require (
github.com/bogdzn/gork v0.0.5
github.com/spf13/cobra v1.8.1
+ github.com/spiral-sec/assetfinder v0.2.0
)
require (
diff --git a/go.sum b/go.sum
@@ -38,6 +38,8 @@ github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spiral-sec/assetfinder v0.2.0 h1:Z49ze7/sVZ6ZjuCRDqFpQt3T78VGW3P+SPzC57/HnAI=
+github.com/spiral-sec/assetfinder v0.2.0/go.mod h1:Btbw+b0afgtwSL+YcFXdyrq9cHm46v3bimm4sJyHi/M=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
diff --git a/osint/assetfinder.go b/osint/assetfinder.go
@@ -0,0 +1,98 @@
+package osint
+
+import (
+ "fmt"
+ "os"
+ "sync"
+ "time"
+
+ // old fork that dissociates main from runner
+ // (i deleted the repo but the code still exists, and the tool has not
+ // been update in 4 years so...)
+ assetfinder "github.com/spiral-sec/assetfinder/scanner"
+)
+
+type fetchFn func(string) ([]string, error)
+
+type AssetfinderConfig struct {
+ scanPath string
+ outfile string
+}
+
+type Assetfinder struct {
+ outfile string
+ functions []fetchFn
+ scanPath string
+}
+
+func (a *Assetfinder) Info(url string) {
+ fmt.Println("[+] Running Assetfinder on %s", url)
+}
+
+func (a *Assetfinder) Configure(c interface{}) {
+ a.scanPath = c.(map[string]interface{})["scanPath"].(string)
+ a.outfile = c.(map[string]interface{})["outfile"].(string)
+
+ a.functions = []fetchFn{
+ assetfinder.CertSpotter,
+ assetfinder.HackerTarget,
+ assetfinder.ThreatCrowd,
+ assetfinder.CrtSh,
+ assetfinder.Facebook,
+ assetfinder.VirusTotal,
+ assetfinder.FindSubDomains,
+ assetfinder.Urlscan,
+ assetfinder.BufferOverrun,
+ }
+}
+
+func (a *Assetfinder) Run(url string) {
+ var wg sync.WaitGroup
+
+ rl := assetfinder.NewRateLimiter(time.Second)
+ out := make(chan string)
+
+ for _, f := range a.functions {
+ wg.Add(1)
+ fn := f
+
+ go func() {
+ defer wg.Done()
+
+ rl.Block(fmt.Sprintf("%#v", fn))
+ names, err := fn(url)
+
+ if err != nil {
+ return
+ }
+
+ for _, n := range names {
+ n = assetfinder.CleanDomain(n)
+ out <- n
+ }
+ }()
+ }
+
+ go func() {
+ wg.Wait()
+ close(out)
+ }()
+
+ printed := make(map[string]bool)
+ file, err := os.OpenFile(a.outfile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+ if err != nil {
+ return
+ }
+ defer file.Close()
+
+ for n := range out {
+ if _, ok := printed[n]; ok {
+ continue
+ }
+ printed[n] = true
+ fmt.Println(n)
+ file.WriteString(n + string('\n'))
+ }
+
+ fmt.Printf("[OSINT %s] Assetfinder done.", url, a.outfile)
+}
diff --git a/osint/run.go b/osint/run.go
@@ -43,8 +43,25 @@ func (opts OsintOpts) runGoogleDorks() {
}
}
+func (opts OsintOpts) runSubfinder() {
+
+}
+
func (opts OsintOpts) runAssetfinder() {
+ asf := Assetfinder{}
+ asfCfg := make(map[string]interface{})
+
+ asfOutfile := fmt.Sprintf("%s/assetfinder_%s.txt", opts.scanPath, opts.domain)
+ asfCfg["scanPath"] = opts.scanPath
+ asfCfg["outfile"] = asfOutfile
+
+ asf.Configure(asfCfg)
+ asf.Info(opts.domain)
+
+ if !opts.dryRun {
+ asf.Run(opts.domain)
+ }
}
func (opts OsintOpts) runDnsx() {
@@ -63,6 +80,7 @@ func (opts OsintOpts) Run() {
fmt.Printf("\n[OSINT] domain: %s\n\n", opts.domain)
opts.runGoogleDorks()
+ opts.runSubfinder()
opts.runAssetfinder()
opts.runDnsx()
opts.runHttpx()
| | | |