mirror of
https://github.com/anotherhadi/iknowyou.git
synced 2026-04-12 00:47:26 +02:00
init
This commit is contained in:
126
back/internal/tools/wappalyzer/tool.go
Normal file
126
back/internal/tools/wappalyzer/tool.go
Normal file
@@ -0,0 +1,126 @@
|
||||
package wappalyzer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
wappalyzergo "github.com/projectdiscovery/wappalyzergo"
|
||||
|
||||
"github.com/anotherhadi/iknowyou/internal/tools"
|
||||
)
|
||||
|
||||
const (
|
||||
name = "wappalyzer"
|
||||
description = "Web technology fingerprinting via wappalyzergo — detects CMS, frameworks, web servers, analytics, CDN, and 1500+ other technologies running on a domain."
|
||||
link = "https://github.com/projectdiscovery/wappalyzergo"
|
||||
icon = "wappalyzer"
|
||||
)
|
||||
|
||||
type Runner struct {
|
||||
wappalyze *wappalyzergo.Wappalyze
|
||||
}
|
||||
|
||||
func New() tools.ToolRunner {
|
||||
w, _ := wappalyzergo.New()
|
||||
return &Runner{wappalyze: w}
|
||||
}
|
||||
|
||||
func (r *Runner) Name() string { return name }
|
||||
func (r *Runner) Description() string { return description }
|
||||
func (r *Runner) Link() string { return link }
|
||||
func (r *Runner) Icon() string { return icon }
|
||||
|
||||
func (r *Runner) InputTypes() []tools.InputType {
|
||||
return []tools.InputType{tools.InputTypeDomain}
|
||||
}
|
||||
|
||||
func (r *Runner) Run(ctx context.Context, target string, _ tools.InputType, out chan<- tools.Event) error {
|
||||
defer close(out)
|
||||
|
||||
// Try HTTPS first, fall back to HTTP
|
||||
var (
|
||||
resp *http.Response
|
||||
body []byte
|
||||
err error
|
||||
)
|
||||
for _, scheme := range []string{"https", "http"} {
|
||||
targetURL := fmt.Sprintf("%s://%s", scheme, target)
|
||||
req, reqErr := http.NewRequestWithContext(ctx, http.MethodGet, targetURL, nil)
|
||||
if reqErr != nil {
|
||||
continue
|
||||
}
|
||||
req.Header.Set("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)")
|
||||
|
||||
resp, err = http.DefaultClient.Do(req)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
body, err = io.ReadAll(resp.Body)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if ctx.Err() != nil {
|
||||
out <- tools.Event{Tool: name, Type: tools.EventTypeError, Payload: "scan cancelled"}
|
||||
out <- tools.Event{Tool: name, Type: tools.EventTypeCount, Payload: 0}
|
||||
out <- tools.Event{Tool: name, Type: tools.EventTypeDone}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil || resp == nil {
|
||||
msg := "failed to connect to target"
|
||||
if err != nil {
|
||||
msg = err.Error()
|
||||
}
|
||||
out <- tools.Event{Tool: name, Type: tools.EventTypeError, Payload: msg}
|
||||
out <- tools.Event{Tool: name, Type: tools.EventTypeCount, Payload: 0}
|
||||
out <- tools.Event{Tool: name, Type: tools.EventTypeDone}
|
||||
return nil
|
||||
}
|
||||
|
||||
fingerprints := r.wappalyze.FingerprintWithInfo(resp.Header, body)
|
||||
if len(fingerprints) == 0 {
|
||||
out <- tools.Event{Tool: name, Type: tools.EventTypeCount, Payload: 0}
|
||||
out <- tools.Event{Tool: name, Type: tools.EventTypeDone}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Group by category
|
||||
byCategory := make(map[string][]string)
|
||||
for tech, info := range fingerprints {
|
||||
cats := info.Categories
|
||||
if len(cats) == 0 {
|
||||
cats = []string{"Other"}
|
||||
}
|
||||
for _, cat := range cats {
|
||||
byCategory[cat] = append(byCategory[cat], tech)
|
||||
}
|
||||
}
|
||||
|
||||
cats := make([]string, 0, len(byCategory))
|
||||
for c := range byCategory {
|
||||
cats = append(cats, c)
|
||||
}
|
||||
sort.Strings(cats)
|
||||
|
||||
var sb strings.Builder
|
||||
sb.WriteString(fmt.Sprintf("Detected %d technologies\n\n", len(fingerprints)))
|
||||
for _, cat := range cats {
|
||||
techs := byCategory[cat]
|
||||
sort.Strings(techs)
|
||||
sb.WriteString(fmt.Sprintf("%s:\n", cat))
|
||||
for _, t := range techs {
|
||||
sb.WriteString(fmt.Sprintf(" - %s\n", t))
|
||||
}
|
||||
sb.WriteString("\n")
|
||||
}
|
||||
|
||||
out <- tools.Event{Tool: name, Type: tools.EventTypeOutput, Payload: strings.TrimSpace(sb.String())}
|
||||
out <- tools.Event{Tool: name, Type: tools.EventTypeCount, Payload: len(fingerprints)}
|
||||
out <- tools.Event{Tool: name, Type: tools.EventTypeDone}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user