This commit is contained in:
Hadi
2026-04-06 15:12:34 +02:00
commit 4989225671
117 changed files with 11454 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
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
}