Signed-off-by: Hadi <[email protected]>
This commit is contained in:
Hadi
2025-05-20 15:28:32 +02:00
parent 7f74f5d28f
commit 5a9483411a
14 changed files with 845 additions and 216 deletions
+107 -33
View File
@@ -2,43 +2,50 @@ package main
import (
"context"
"flag"
"fmt"
"os"
ghrecon "github.com/anotherhadi/gh-recon/gh-recon"
"github.com/charmbracelet/log"
"github.com/google/go-github/v72/github"
flag "github.com/spf13/pflag"
)
func main() {
var username string
var token string
flag.StringVar(&username, "username", "", "Target username")
flag.StringVar(&token, "token", "", "Github token")
var onlyCommitsLeak bool
var fromEmail string
var deep bool
var silent bool
var jsonFile string
var excludeRepos string
flag.StringVarP(&username, "username", "u", "", "GitHub username to analyze")
flag.StringVarP(&token, "token", "t", "", "GitHub personal access token (e.g. ghp_...)")
flag.StringVarP(&fromEmail, "email", "e", "", "Search accounts by email address")
flag.BoolVarP(
&onlyCommitsLeak,
"only-commits",
"c",
false,
"Display only commits with author info",
)
flag.BoolVarP(
&deep,
"deep",
"d",
false,
"Enable deep scan (clone repos, regex search, analyse licenses, etc.)",
)
flag.BoolVarP(&silent, "silent", "s", false, "Suppress all non-essential output")
flag.StringVarP(&jsonFile, "json", "j", "", "Write results to specified JSON file")
flag.StringVar(
&excludeRepos,
"exclude-repo",
"",
"Exclude repos from deep scan (comma-separated list)",
)
flag.Parse()
if username == "" {
fmt.Println("Please provide a username with the --username flag")
os.Exit(1)
}
err := ghrecon.ParseUsername(username)
if err != nil {
log.Error("Invalid username", "err", err)
os.Exit(1)
}
client := github.NewClient(nil)
if token == "" {
log.Info(
"It's recommended to set a Github token for better rate limits. You can set it using the --token flag.",
)
} else {
client = client.WithAuthToken(token)
}
ctx := context.Background()
styles := log.DefaultStyles()
styles.Levels[log.InfoLevel] = styles.Levels[log.InfoLevel].Foreground(ghrecon.Grey)
logger := log.NewWithOptions(os.Stderr, log.Options{
@@ -47,18 +54,85 @@ func main() {
})
logger.SetStyles(styles)
if username == "" && fromEmail == "" {
logger.Error(
"Please provide a username with the --username (-u) flag or an email with the --email (-e) flag",
)
os.Exit(1)
} else if username != "" {
if err := ghrecon.ParseUsername(username); err != nil {
logger.Error("Invalid username", "err", err)
os.Exit(1)
}
}
client := github.NewClient(nil)
if token == "" {
if !silent {
logger.Info(
"It's recommended to set a Github token for better rate limits. You can set it using the --token (-t) flag.",
)
}
} else {
client = client.WithAuthToken(token)
}
ctx := context.Background()
r := ghrecon.NewRecon(
client,
logger,
ctx,
silent,
jsonFile,
)
ghrecon.Header()
r.User(username)
r.Orgs(username)
r.SshKeys(username)
r.GpgKeys(username)
r.SshSigningKeys(username)
r.Socials(username)
r.Commits(username)
r.Header()
if fromEmail != "" {
emailsInfo := r.Email(fromEmail)
r.WriteJson(
map[string]any{
"Authors": emailsInfo,
},
)
return
}
if onlyCommitsLeak {
commitsInfo := r.Commits(username)
r.WriteJson(
map[string]any{
"Authors": commitsInfo,
},
)
return
}
userInfo := r.User(username)
orgsInfo := r.Orgs(username)
sshKeysInfo := r.SshKeys(username)
gpgKeysInfo := r.GpgKeys(username)
sshSigningKeysInfo := r.SshSigningKeys(username)
socialsInfo := r.Socials(username)
closeFriendsInfo := r.CloseFriends(username)
commitsInfo := r.Commits(username)
results := map[string]any{
"User": userInfo,
"Orgs": orgsInfo,
"SSHKeys": sshKeysInfo,
"GPGKeys": gpgKeysInfo,
"SSHSigningKeys": sshSigningKeysInfo,
"Socials": socialsInfo,
"Commits": commitsInfo,
"CloseFriends": closeFriendsInfo,
}
if deep {
results["Deep"] = r.Deep(username, excludeRepos)
}
r.WriteJson(results)
}