mirror of
https://github.com/anotherhadi/iknowyou.git
synced 2026-04-11 16:37:25 +02:00
92 lines
2.7 KiB
Go
92 lines
2.7 KiB
Go
package githubrecon
|
|
|
|
import (
|
|
"context"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"github.com/anotherhadi/iknowyou/internal/tools"
|
|
)
|
|
|
|
const (
|
|
name = "github-recon"
|
|
description = "GitHub OSINT reconnaissance tool. Gathers profile info, social links, organisations, SSH/GPG keys, commits, and more from a GitHub username or email."
|
|
link = "https://github.com/anotherhadi/nur-osint"
|
|
icon = "github"
|
|
)
|
|
|
|
type Config struct {
|
|
Token string `yaml:"token" iky:"desc=GitHub personal access token (enables higher rate limits and more data);required=false"`
|
|
Deepscan bool `yaml:"deepscan" iky:"desc=Enable deep scan (slower - scans all repositories for authors/emails);default=false"`
|
|
SpoofEmail bool `yaml:"spoof_email" iky:"desc=Include email spoofing check (email mode only, requires token);default=false"`
|
|
}
|
|
|
|
type Runner struct {
|
|
cfg Config
|
|
}
|
|
|
|
func New() tools.ToolRunner {
|
|
cfg := Config{}
|
|
tools.ApplyDefaults(&cfg)
|
|
return &Runner{cfg: cfg}
|
|
}
|
|
|
|
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.InputTypeUsername,
|
|
tools.InputTypeEmail,
|
|
}
|
|
}
|
|
|
|
func (r *Runner) ConfigPtr() interface{} { return &r.cfg }
|
|
|
|
func (r *Runner) ConfigFields() []tools.ConfigField {
|
|
return tools.ReflectConfigFields(r.cfg)
|
|
}
|
|
|
|
func (r *Runner) Available() (bool, string) {
|
|
if _, err := exec.LookPath("github-recon"); err != nil {
|
|
return false, "github-recon binary not found in PATH"
|
|
}
|
|
return true, ""
|
|
}
|
|
|
|
func (r *Runner) Dependencies() []string { return []string{"github-recon"} }
|
|
|
|
func (r *Runner) Run(ctx context.Context, target string, inputType tools.InputType, out chan<- tools.Event) error {
|
|
defer close(out)
|
|
|
|
args := []string{target}
|
|
if r.cfg.Token != "" {
|
|
args = append(args, "--token", r.cfg.Token)
|
|
}
|
|
if r.cfg.Deepscan {
|
|
args = append(args, "--deepscan")
|
|
}
|
|
if r.cfg.SpoofEmail && inputType == tools.InputTypeEmail {
|
|
args = append(args, "--spoof-email")
|
|
}
|
|
|
|
cmd := exec.CommandContext(ctx, "github-recon", args...)
|
|
output, err := tools.RunWithPTY(ctx, cmd)
|
|
|
|
// Remove banner
|
|
output = tools.RemoveFirstLines(output, 10)
|
|
|
|
count := 0
|
|
if err != nil && ctx.Err() != nil {
|
|
out <- tools.Event{Tool: name, Type: tools.EventTypeError, Payload: "scan cancelled"}
|
|
} else if output != "" {
|
|
out <- tools.Event{Tool: name, Type: tools.EventTypeOutput, Payload: output}
|
|
count = strings.Count(output, "Username:")
|
|
}
|
|
out <- tools.Event{Tool: name, Type: tools.EventTypeCount, Payload: count}
|
|
out <- tools.Event{Tool: name, Type: tools.EventTypeDone}
|
|
return nil
|
|
}
|