mirror of
https://github.com/anotherhadi/github-recon.git
synced 2026-10-05 10:58:25 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53dd8ea2d5 | ||
|
|
832e996708 | ||
|
|
8528fe5732 | ||
|
|
85ee3a6333 | ||
|
|
cb694d896d | ||
|
|
1dfa0c1620 | ||
|
|
ef0240fd65 | ||
|
|
d88bc6ae1e | ||
|
|
c460e5c24f | ||
|
|
e572d1326a | ||
|
|
0017d649d3 | ||
|
|
c163fb4ecd | ||
|
|
325397dfef | ||
|
|
dab0ba2b38 |
@@ -195,8 +195,9 @@ privacy and security:
|
||||
information.
|
||||
- **Manage email exposure**: Use GitHub's settings to control which email
|
||||
addresses are visible on your profile and in commit history. You can also use
|
||||
a no-reply email address for commits. Delete/modify any sensitive information
|
||||
in your commit history.
|
||||
a no-reply email address for commits, and an
|
||||
[alias email](https://proton.me/support/addresses-and-aliases) for your
|
||||
account. Delete/modify any sensitive information in your commit history.
|
||||
- **Be Mindful of Repository Content**: Avoid including sensitive information in
|
||||
your repositories, such as API keys, passwords, emails or personal data. Use
|
||||
`.gitignore` to exclude files that contain sensitive information.
|
||||
|
||||
+10
-2
@@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
recon_email "github.com/anotherhadi/github-recon/github-recon/email"
|
||||
recon_username "github.com/anotherhadi/github-recon/github-recon/username"
|
||||
github_recon_settings "github.com/anotherhadi/github-recon/settings"
|
||||
@@ -8,7 +10,10 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
settings := github_recon_settings.GetSettings()
|
||||
settings, err := github_recon_settings.GetSettings()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if !settings.Silent {
|
||||
utils.Header()
|
||||
@@ -23,7 +28,10 @@ func main() {
|
||||
}
|
||||
|
||||
if settings.TargetType == github_recon_settings.TargetUsername {
|
||||
result := recon_username.Username(settings)
|
||||
result, err := recon_username.Username(settings)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
writeJson(settings, result)
|
||||
} else {
|
||||
result := recon_email.Email(settings)
|
||||
|
||||
Generated
+3
-3
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1756787288,
|
||||
"narHash": "sha256-rw/PHa1cqiePdBxhF66V7R+WAP8WekQ0mCDG4CFqT8Y=",
|
||||
"lastModified": 1758427187,
|
||||
"narHash": "sha256-pHpxZ/IyCwoTQPtFIAG2QaxuSm8jWzrzBGjwQZIttJc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d0fc30899600b9b3466ddb260fd83deb486c32f1",
|
||||
"rev": "554be6495561ff07b6c724047bdd7e0716aa7b46",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
(system: f system (import nixpkgs {inherit system;}));
|
||||
|
||||
pname = "github-recon";
|
||||
version = "2.1.0";
|
||||
version = "1.5.3";
|
||||
|
||||
ldflags = ["-s" "-w"];
|
||||
in {
|
||||
@@ -30,7 +30,7 @@
|
||||
cp $GOPATH/bin/cmd $out/bin/github-recon
|
||||
'';
|
||||
|
||||
vendorHash = "sha256-AD0h0k2n8gPqSBz5qqb0ZON/jWiSEWpeO97xR7cYSy8=";
|
||||
vendorHash = "sha256-16mRhQyoyY3M98cWBURsEvvwVT6aR3JWk8YfAFNfm/A=";
|
||||
|
||||
meta = with pkgs.lib; {
|
||||
description = "Retrieves and aggregates public OSINT data about a Github user using Go and the Github API. Finds hidden emails in commit history, previous usernames, friends, other Github accounts, and more.";
|
||||
|
||||
@@ -2,6 +2,7 @@ package recon
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
github_recon_settings "github.com/anotherhadi/github-recon/settings"
|
||||
"github.com/anotherhadi/github-recon/utils"
|
||||
@@ -99,6 +100,9 @@ func Spoofing(s github_recon_settings.Settings) (response *SpoofingResult) {
|
||||
}
|
||||
utils.WaitForRateLimit(s, resp)
|
||||
|
||||
const maxRetries = 5
|
||||
const retryDelay = 2 * time.Second
|
||||
for i := 0; i < maxRetries; i++ {
|
||||
commits, _, err := s.Client.Repositories.ListCommits(s.Ctx, repo.Owner.GetLogin(), name, nil)
|
||||
if err != nil {
|
||||
s.Logger.Error("Error while listing commits", "err", err)
|
||||
@@ -112,8 +116,11 @@ func Spoofing(s github_recon_settings.Settings) (response *SpoofingResult) {
|
||||
response.Email = last.GetAuthor().GetEmail()
|
||||
response.Url = last.GetAuthor().GetHTMLURL()
|
||||
response.AvatarURL = last.GetAuthor().GetAvatarURL()
|
||||
} else {
|
||||
s.Logger.Error("Only one commit found, something went wrong.", "commits", commits)
|
||||
break
|
||||
}
|
||||
|
||||
s.Logger.Info("Only one commit found, retrying...", "attempt", i+1)
|
||||
time.Sleep(retryDelay)
|
||||
}
|
||||
|
||||
if response.Username == "" && response.Name == "" && response.Email == "" {
|
||||
|
||||
@@ -82,7 +82,7 @@ func DeepScan(s github_recon_settings.Settings) (response DeepScanResult) {
|
||||
}
|
||||
|
||||
repositories = append(repositories, Repositorie{
|
||||
Repository: repo.GetCloneURL(),
|
||||
Repository: repo.GetHTMLURL(),
|
||||
Owner: repo.GetOwner().GetLogin(),
|
||||
Name: repo.GetName(),
|
||||
Size: repo.GetSize(),
|
||||
@@ -139,6 +139,11 @@ func DeepScan(s github_recon_settings.Settings) (response DeepScanResult) {
|
||||
}
|
||||
s.Logger.Info("Cloned all repositories", "path", tmp_folder)
|
||||
|
||||
if len(repositories) == 0 {
|
||||
s.Logger.Info("No repositories found for the user, skipping deep scan.")
|
||||
return
|
||||
}
|
||||
|
||||
authorOccurrences := Authors{}
|
||||
mapAuthorToIndex := make(map[string]int)
|
||||
for _, repo := range repositories {
|
||||
|
||||
@@ -27,16 +27,21 @@ type UsernameResult struct {
|
||||
DeepScan DeepScanResult
|
||||
}
|
||||
|
||||
func Username(settings github_recon_settings.Settings) UsernameResult {
|
||||
|
||||
result := UsernameResult{
|
||||
func Username(settings github_recon_settings.Settings) (result UsernameResult, err error) {
|
||||
result = UsernameResult{
|
||||
Target: settings.Target,
|
||||
TargetType: settings.TargetType,
|
||||
DateTime: time.Now().String(),
|
||||
}
|
||||
|
||||
utils.PrintTitle(settings.Silent, "👤 User informations")
|
||||
result.User = User(settings)
|
||||
result.User, err = User(settings)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if result.User == (UserResult{}) {
|
||||
return
|
||||
}
|
||||
utils.PrintAvatar(settings, result.User.AvatarURL)
|
||||
utils.PrintStruct(settings, result.User, 0)
|
||||
|
||||
@@ -74,5 +79,5 @@ func Username(settings github_recon_settings.Settings) UsernameResult {
|
||||
utils.PrintStruct(settings, result.DeepScan, 0)
|
||||
}
|
||||
|
||||
return result
|
||||
return
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ func Orgs(s github_recon_settings.Settings) (response OrgsResult) {
|
||||
for _, org := range orgs {
|
||||
o := OrgResult{
|
||||
Name: org.GetLogin(),
|
||||
URL: org.GetURL(),
|
||||
URL: org.GetHTMLURL(),
|
||||
Description: org.GetDescription(),
|
||||
}
|
||||
response = append(response, o)
|
||||
|
||||
@@ -31,13 +31,13 @@ type UserResult struct {
|
||||
Plan string
|
||||
}
|
||||
|
||||
func User(s github_recon_settings.Settings) (response UserResult) {
|
||||
func User(s github_recon_settings.Settings) (response UserResult, err error) {
|
||||
user, resp, err := s.Client.Users.Get(s.Ctx, s.Target)
|
||||
if resp.StatusCode == 404 {
|
||||
s.Logger.Fatal("User not found with username")
|
||||
return UserResult{}, nil
|
||||
}
|
||||
if err != nil {
|
||||
s.Logger.Fatal("Failed to fetch user's information", "err", err)
|
||||
return UserResult{}, fmt.Errorf("failed to fetch user's information")
|
||||
}
|
||||
|
||||
u := UserResult{
|
||||
@@ -65,5 +65,5 @@ func User(s github_recon_settings.Settings) (response UserResult) {
|
||||
}
|
||||
|
||||
utils.WaitForRateLimit(s, resp)
|
||||
return u
|
||||
return u, nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/anotherhadi/github-recon
|
||||
|
||||
go 1.24.5
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/charmbracelet/lipgloss v1.1.0
|
||||
@@ -26,6 +26,6 @@ require (
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||
golang.org/x/image v0.28.0 // indirect
|
||||
golang.org/x/image v0.38.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
)
|
||||
|
||||
@@ -48,8 +48,8 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavM
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||
golang.org/x/image v0.28.0 h1:gdem5JW1OLS4FbkWgLO+7ZeFzYtL3xClb97GaUzYMFE=
|
||||
golang.org/x/image v0.28.0/go.mod h1:GUJYXtnGKEUgggyzh+Vxt+AviiCcyiwpsl8iQ8MvwGY=
|
||||
golang.org/x/image v0.38.0 h1:5l+q+Y9JDC7mBOMjo4/aPhMDcxEptsX+Tt3GgRQRPuE=
|
||||
golang.org/x/image v0.38.0/go.mod h1:/3f6vaXC+6CEanU4KJxbcUZyEePbyKbaLoDOe4ehFYY=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
|
||||
@@ -68,11 +68,11 @@ func GetDefaultSettings() Settings {
|
||||
}
|
||||
}
|
||||
|
||||
func GetSettings() (settings Settings) {
|
||||
func GetSettings() (settings Settings, err error) {
|
||||
settings = GetDefaultSettings()
|
||||
//// Flag settings
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, "Usage:\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, "github-recon [flags] <target username or email>\n")
|
||||
fmt.Fprintf(os.Stderr, "\n")
|
||||
fmt.Fprintf(os.Stderr, "Flags:\n")
|
||||
@@ -152,7 +152,7 @@ func GetSettings() (settings Settings) {
|
||||
settings.Target = strings.TrimPrefix(settings.Target, "@") // Remove the @ of the username
|
||||
|
||||
if strings.Contains(settings.Target, " ") {
|
||||
settings.Logger.Fatal("Target cannot contain spaces")
|
||||
err = fmt.Errorf("target cannot contain spaces")
|
||||
}
|
||||
|
||||
if strings.Contains(settings.Target, "@") {
|
||||
|
||||
Reference in New Issue
Block a user