Init the spoofing feature #6

Signed-off-by: Hadi <[email protected]>
This commit is contained in:
Hadi
2025-08-23 10:35:37 +02:00
parent c1d732e03a
commit 6229445251
4 changed files with 134 additions and 4 deletions
+8 -3
View File
@@ -10,7 +10,8 @@ type EmailResult struct {
Target string
TargetType github_recon_settings.TargetType
Commit recon.CommitsResult
Commits recon.CommitsResult
Spoofing recon.SpoofingResult
}
func email(settings github_recon_settings.Settings, datetime string) {
@@ -21,6 +22,10 @@ func email(settings github_recon_settings.Settings, datetime string) {
}
printTitle(settings.Silent, "👤 Commits author")
result.Commit = recon.Email(settings)
printStruct(settings, result.Commit, 0)
result.Commits = recon.Commits(settings)
printStruct(settings, result.Commits, 0)
printTitle(settings.Silent, "🎭 Spoofing test")
result.Spoofing = recon.Spoofing(settings)
printStruct(settings, result.Spoofing, 0)
}
+6
View File
@@ -42,6 +42,8 @@ func printStruct(settings github_recon_settings.Settings, s any, indent int) {
return
}
printed := 0
for i := 0; i < v.NumField(); i++ {
field := t.Field(i).Name
value := v.Field(i)
@@ -55,6 +57,7 @@ func printStruct(settings github_recon_settings.Settings, s any, indent int) {
if (field == "FirstFoundIn" || field == "FoundIn") && !settings.ShowSource {
continue
}
printed++
switch value.Kind() {
case reflect.Struct, reflect.Slice, reflect.Array, reflect.Ptr:
@@ -66,6 +69,9 @@ func printStruct(settings github_recon_settings.Settings, s any, indent int) {
fmt.Printf("%s%s %s\n", prefix, greyStyle.Render(field+":"), greenStyle.Render(fmt.Sprintf("%v", value.Interface())))
}
}
if printed == 0 {
fmt.Println(prefix + greyStyle.Render("No data found"))
}
fmt.Println("")
case reflect.Slice, reflect.Array:
+119
View File
@@ -1 +1,120 @@
package recon
import (
"math/rand"
github_recon_settings "github.com/anotherhadi/github-recon/settings"
"github.com/anotherhadi/github-recon/utils"
"github.com/google/go-github/v72/github"
)
type SpoofingResult struct {
Username string
Name string
Email string
Url string
}
func RandomString(n int) string {
letters := []rune("abcdefghijklmnopqrstuvwxyz")
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
func Spoofing(s github_recon_settings.Settings) (response SpoofingResult) {
// 1) Create repo (auto-init pour avoir une branche par défaut)
name := "gh-recon-spoofing-" + RandomString(8)
private := true
autoInit := true
repo, resp, err := s.Client.Repositories.Create(s.Ctx, "", &github.Repository{
Name: &name,
Private: &private,
AutoInit: &autoInit,
})
if err != nil {
s.Logger.Error("Error while creating repo", "err", err)
return
}
utils.WaitForRateLimit(s, resp)
// branche par défaut (fallback "main")
branch := repo.GetDefaultBranch()
if branch == "" {
branch = "main"
}
refName := "heads/" + branch
// 2) Commit vide avec auteur spoofé (tree identique au parent)
author := &github.CommitAuthor{
Name: github.String("Spoofed Name"),
Email: github.String(s.Target),
}
ref, resp, err := s.Client.Git.GetRef(s.Ctx, repo.Owner.GetLogin(), name, refName)
if err != nil {
s.Logger.Error("Error while getting ref", "err", err)
s.Logger.Warn("The temp repo was left undeleted", "repo", repo.GetHTMLURL())
return
}
utils.WaitForRateLimit(s, resp)
parentCommit, resp, err := s.Client.Git.GetCommit(s.Ctx, repo.Owner.GetLogin(), name, ref.GetObject().GetSHA())
if err != nil {
s.Logger.Error("Error while getting parent commit", "err", err)
s.Logger.Warn("The temp repo was left undeleted", "repo", repo.GetHTMLURL())
return
}
utils.WaitForRateLimit(s, resp)
commit := &github.Commit{
Author: author,
Message: github.String("Spoofed empty commit"),
Tree: &github.Tree{SHA: parentCommit.Tree.SHA}, // même tree => commit vide
Parents: []*github.Commit{parentCommit},
}
newCommit, resp, err := s.Client.Git.CreateCommit(s.Ctx, repo.Owner.GetLogin(), name, commit, nil)
if err != nil {
s.Logger.Error("Error while creating spoofed empty commit", "err", err)
s.Logger.Warn("The temp repo was left undeleted", "repo", repo.GetHTMLURL())
return
}
utils.WaitForRateLimit(s, resp)
ref.Object.SHA = newCommit.SHA
_, resp, err = s.Client.Git.UpdateRef(s.Ctx, repo.Owner.GetLogin(), name, ref, false)
if err != nil {
s.Logger.Error("Error while updating ref to spoofed commit", "err", err)
s.Logger.Warn("The temp repo was left undeleted", "repo", repo.GetHTMLURL())
return
}
utils.WaitForRateLimit(s, resp)
// 3) Get user
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)
s.Logger.Warn("The temp repo was left undeleted", "repo", repo.GetHTMLURL())
return
}
if len(commits) > 0 {
last := commits[0]
response.Username = last.GetAuthor().GetLogin()
response.Name = last.GetAuthor().GetName()
response.Email = last.GetAuthor().GetEmail()
response.Url = last.GetAuthor().GetHTMLURL()
}
// 4) Cleanup
_, err = s.Client.Repositories.Delete(s.Ctx, repo.Owner.GetLogin(), name)
if err != nil {
s.Logger.Error("Error while deleting repo", "err", err)
}
return
}
+1 -1
View File
@@ -110,7 +110,7 @@ func LevenshteinDistance(s1, s2 string) int {
}
func SkipResult(name, email string) bool {
if name == "github-actions[bot]" || name == "dependabot[bot]" || name == "github-actions" {
if name == "github-actions[bot]" || name == "dependabot[bot]" || name == "github-actions" || name == "GitHub Actions" {
return true
}
if email == "github-actions[bot]@users.noreply.github.com" || email == "[email protected]" ||