diff --git a/README.md b/README.md index eb41372..76a1cf4 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ _(__ )_ / _ __/ - 🔎 Automated Google dorking - 💘 Shodan integration - 📦 CMS detection +- 🔍 HTTP Header Analysis ## Contributing and support diff --git a/pkg/config/config.go b/pkg/config/config.go index b3c4aaf..972155e 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -26,6 +26,7 @@ type Settings struct { ApiMode bool Template string CMS bool + Headers bool } const ( @@ -65,6 +66,7 @@ func Parse() *Settings { flagSet.BoolVar(&settings.Whois, "whois", false, "Enable WHOIS lookup"), flagSet.BoolVar(&settings.JavaScript, "js", false, "Enable JavaScript scans"), flagSet.BoolVar(&settings.CMS, "cms", false, "Enable CMS detection"), + flagSet.BoolVar(&settings.Headers, "headers", false, "Enable HTTP Header Analysis"), ) flagSet.CreateGroup("runtime", "Runtime", diff --git a/pkg/scan/headers.go b/pkg/scan/headers.go new file mode 100644 index 0000000..6b11395 --- /dev/null +++ b/pkg/scan/headers.go @@ -0,0 +1,60 @@ +package scan + +import ( + "fmt" + "net/http" + "strings" + "time" + "os" + + "github.com/charmbracelet/log" + "github.com/dropalldatabases/sif/internal/styles" + "github.com/dropalldatabases/sif/pkg/logger" +) + +type HeaderResult struct { + Name string `json:"name"` + Value string `json:"value"` +} + +func Headers(url string, timeout time.Duration, logdir string) ([]HeaderResult, error) { + fmt.Println(styles.Separator.Render("🔍 Starting " + styles.Status.Render("HTTP Header Analysis") + "...")) + + sanitizedURL := strings.Split(url, "://")[1] + + if logdir != "" { + if err := logger.WriteHeader(sanitizedURL, logdir, "HTTP Header Analysis"); err != nil { + log.Errorf("Error creating log file: %v", err) + return nil, err + } + } + + headerlog := log.NewWithOptions(os.Stderr, log.Options{ + Prefix: "Headers 🔍", + }).With("url", url) + + client := &http.Client{ + Timeout: timeout, + } + + resp, err := client.Get(url) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var results []HeaderResult + + for name, values := range resp.Header { + for _, value := range values { + results = append(results, HeaderResult{Name: name, Value: value}) + headerlog.Infof("%s: %s", styles.Highlight.Render(name), value) + if logdir != "" { + logger.Write(sanitizedURL, logdir, fmt.Sprintf("%s: %s\n", name, value)) + } + } + } + + return results, nil +} + diff --git a/sif.go b/sif.go index 0ef5da0..d9a4885 100644 --- a/sif.go +++ b/sif.go @@ -175,6 +175,15 @@ func (app *App) Run() error { } } + if app.settings.Headers { + result, err := scan.Headers(url, app.settings.Timeout, app.settings.LogDir) + if err != nil { + log.Errorf("Error while running HTTP Header Analysis: %s", err) + } else { + moduleResults = append(moduleResults, ModuleResult{"headers", result}) + } + } + if app.settings.ApiMode { result := UrlResult{ Url: url,