Init gravatar recon
Signed-off-by: Hadi <112569860+anotherhadi@users.noreply.github.com>
This commit is contained in:
@@ -4,6 +4,7 @@ go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/anotherhadi/github-recon v1.5.6
|
||||
github.com/anotherhadi/gravatar-recon v1.0.1
|
||||
github.com/charmbracelet/log v0.4.2
|
||||
github.com/gin-gonic/gin v1.10.1
|
||||
github.com/marcboeker/go-duckdb v1.8.5
|
||||
@@ -49,7 +50,7 @@ require (
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||
github.com/saran13raj/go-pixels v0.0.0-20250629121333-58b240a3ae51 // indirect
|
||||
github.com/spf13/pflag v1.0.7 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
|
||||
@@ -2,6 +2,8 @@ github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7X
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/anotherhadi/github-recon v1.5.6 h1:IN3lQZRqqNbPpSyP5fvNoJrYODbM2tNwS5tiRgD+i1s=
|
||||
github.com/anotherhadi/github-recon v1.5.6/go.mod h1:E2tmCmjEZdJeBx8u1J8sSMtnmU8aDQ6IjCoq3ykoHtY=
|
||||
github.com/anotherhadi/gravatar-recon v1.0.1 h1:Js3NCrVXhJb/ShG6PMzma1bsER0lQi9qbFHK1uABMm4=
|
||||
github.com/anotherhadi/gravatar-recon v1.0.1/go.mod h1:cMP1mqW5vxwRCIZDbQGr0gb/SzbAveM2EcdJ/BwXQN8=
|
||||
github.com/apache/arrow-go/v18 v18.1.0 h1:agLwJUiVuwXZdwPYVrlITfx7bndULJ/dggbnLFgDp/Y=
|
||||
github.com/apache/arrow-go/v18 v18.1.0/go.mod h1:tigU/sIgKNXaesf5d7Y95jBBKS5KsxTqYBKXFsvKzo0=
|
||||
github.com/apache/thrift v0.21.0 h1:tdPmh/ptjE1IJnhbhrcl2++TauVjy242rkV/UzJChnE=
|
||||
@@ -115,8 +117,8 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/saran13raj/go-pixels v0.0.0-20250629121333-58b240a3ae51 h1:H/XUfYcLxI3CBmDlgBpnOeTntRgqWvIoUXnqhCF5a0s=
|
||||
github.com/saran13raj/go-pixels v0.0.0-20250629121333-58b240a3ae51/go.mod h1:sqhdZVLvqzTEBtmZBuTnFDUW0Lsryw2X2/wrLgqLEYg=
|
||||
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
||||
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
|
||||
@@ -15,13 +15,14 @@ type LeakResult struct {
|
||||
Duration time.Duration
|
||||
Rows []map[string]string
|
||||
Error string
|
||||
Inactive bool
|
||||
LimitHit bool // Whether the search hit the limit
|
||||
}
|
||||
|
||||
func Search(s *server.Server, queryText, column string, exactMatch bool) LeakResult {
|
||||
if len(*(s.Dataleaks)) == 0 {
|
||||
return LeakResult{
|
||||
Error: "No dataleak configured",
|
||||
Inactive: true,
|
||||
}
|
||||
}
|
||||
now := time.Now()
|
||||
|
||||
@@ -14,15 +14,13 @@ import (
|
||||
type GithubResult struct {
|
||||
Duration time.Duration
|
||||
Error string
|
||||
Inactive bool
|
||||
|
||||
UsernameResult *recon_username.UsernameResult
|
||||
EmailResult *recon_email.EmailResult
|
||||
}
|
||||
|
||||
func Search(s *server.Server, queryText, column string) *GithubResult {
|
||||
if !s.Settings.GithubRecon {
|
||||
return nil
|
||||
}
|
||||
func GithubSearch(s *server.Server, queryText, queryType string) GithubResult {
|
||||
gr := GithubResult{}
|
||||
now := time.Now()
|
||||
settings := github_recon_settings.GetDefaultSettings()
|
||||
@@ -35,56 +33,27 @@ func Search(s *server.Server, queryText, column string) *GithubResult {
|
||||
|
||||
queryText = strings.TrimSpace(queryText)
|
||||
|
||||
if column == "email" || strings.HasSuffix(column, "_email") ||
|
||||
column == "username" || strings.HasSuffix(column, "_username") ||
|
||||
column == "" || column == "all" {
|
||||
if isValidEmail(queryText) {
|
||||
settings.Target = queryText
|
||||
settings.TargetType = github_recon_settings.TargetEmail
|
||||
result := recon_email.Email(settings)
|
||||
gr.EmailResult = &result
|
||||
} else if isValidUsername(queryText) {
|
||||
settings.Target = queryText
|
||||
settings.TargetType = github_recon_settings.TargetUsername
|
||||
result, err := recon_username.Username(settings)
|
||||
if err != nil {
|
||||
gr.Error = err.Error()
|
||||
}
|
||||
if result.User.Username == "" {
|
||||
gr.UsernameResult = nil
|
||||
} else {
|
||||
gr.UsernameResult = &result
|
||||
}
|
||||
if queryType == "email" {
|
||||
settings.Target = queryText
|
||||
settings.TargetType = github_recon_settings.TargetEmail
|
||||
result := recon_email.Email(settings)
|
||||
gr.EmailResult = &result
|
||||
} else if queryType == "username" {
|
||||
settings.Target = queryText
|
||||
settings.TargetType = github_recon_settings.TargetUsername
|
||||
result, err := recon_username.Username(settings)
|
||||
if err != nil {
|
||||
gr.Error = err.Error()
|
||||
}
|
||||
if result.User.Username == "" {
|
||||
gr.UsernameResult = nil
|
||||
} else {
|
||||
return nil
|
||||
gr.UsernameResult = &result
|
||||
}
|
||||
} else {
|
||||
return nil
|
||||
return GithubResult{Inactive: true}
|
||||
}
|
||||
|
||||
gr.Duration = time.Since(now)
|
||||
return &gr
|
||||
}
|
||||
|
||||
func isValidEmail(email string) bool {
|
||||
if !strings.Contains(email, "@") || !strings.Contains(email, ".") {
|
||||
return false
|
||||
}
|
||||
if strings.HasPrefix(email, "@") || strings.HasSuffix(email, "@") {
|
||||
return false
|
||||
}
|
||||
if strings.Contains(email, " ") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isValidUsername(username string) bool {
|
||||
if len(username) < 1 || len(username) > 39 {
|
||||
return false
|
||||
}
|
||||
if strings.Contains(username, " ") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return gr
|
||||
}
|
||||
|
||||
32
back/search/osint/gravatar.go
Normal file
32
back/search/osint/gravatar.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package osint
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/anotherhadi/eleakxir/backend/server"
|
||||
gravatar_recon "github.com/anotherhadi/gravatar-recon"
|
||||
)
|
||||
|
||||
type GravatarResult struct {
|
||||
Duration time.Duration
|
||||
Error string
|
||||
Inactive bool
|
||||
|
||||
Results []gravatar_recon.GravatarProfile
|
||||
}
|
||||
|
||||
func GravatarSearch(s *server.Server, queryText string) GravatarResult {
|
||||
gr := GravatarResult{}
|
||||
now := time.Now()
|
||||
results, err := gravatar_recon.GetGravatarProfiles(queryText)
|
||||
|
||||
if err != nil {
|
||||
gr.Error = err.Error()
|
||||
return gr
|
||||
}
|
||||
|
||||
gr.Results = *results
|
||||
|
||||
gr.Duration = time.Since(now)
|
||||
return gr
|
||||
}
|
||||
@@ -19,8 +19,9 @@ type Query struct {
|
||||
ExactMatch bool // Whether to search for an exact match
|
||||
|
||||
// Services
|
||||
Datawells bool // Whether to include datawells in the search
|
||||
GithubRecon bool // Whether to include github-recon in the search
|
||||
Datawells bool // Whether to include datawells in the search
|
||||
GithubRecon bool // Whether to include github-recon in the search
|
||||
GravatarRecon bool // Whether to include gravatar-recon in the search
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
@@ -29,27 +30,25 @@ type Result struct {
|
||||
Status string // "pending", "completed"
|
||||
Query Query
|
||||
|
||||
LeakResult dataleak.LeakResult
|
||||
GithubResult osint.GithubResult
|
||||
LeakResult dataleak.LeakResult
|
||||
GithubResult osint.GithubResult
|
||||
GravatarResult osint.GravatarResult
|
||||
}
|
||||
|
||||
func Search(s *server.Server, q Query, r *Result, mu *sync.RWMutex) {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
cleanQueryText := strings.TrimPrefix(q.Text, "^")
|
||||
cleanQueryText = strings.TrimSuffix(q.Text, "$")
|
||||
|
||||
mu.Lock()
|
||||
r.Date = time.Now()
|
||||
r.Status = "pending"
|
||||
r.Query = q
|
||||
mu.Unlock()
|
||||
|
||||
wg.Add(2)
|
||||
wg.Add(3)
|
||||
go func() {
|
||||
if !q.Datawells {
|
||||
mu.Lock()
|
||||
r.LeakResult = dataleak.LeakResult{Error: "not enabled"}
|
||||
r.LeakResult = dataleak.LeakResult{Inactive: true}
|
||||
mu.Unlock()
|
||||
wg.Done()
|
||||
return
|
||||
@@ -61,21 +60,52 @@ func Search(s *server.Server, q Query, r *Result, mu *sync.RWMutex) {
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
cleanQueryText := strings.TrimPrefix(q.Text, "^")
|
||||
cleanQueryText = strings.TrimSuffix(q.Text, "$")
|
||||
isEmail := false
|
||||
isUsername := false
|
||||
|
||||
if q.Column == "email" || strings.HasSuffix(q.Column, "_email") ||
|
||||
q.Column == "username" || strings.HasSuffix(q.Column, "_username") ||
|
||||
q.Column == "" || q.Column == "all" {
|
||||
if isValidEmail(cleanQueryText) {
|
||||
isEmail = true
|
||||
} else if isValidUsername(cleanQueryText) {
|
||||
isUsername = true
|
||||
}
|
||||
}
|
||||
|
||||
go func() {
|
||||
if !q.GithubRecon {
|
||||
if !q.GithubRecon || !s.Settings.GithubRecon || (!isEmail && !isUsername) {
|
||||
mu.Lock()
|
||||
r.GithubResult = osint.GithubResult{Error: "not enabled"}
|
||||
r.GithubResult = osint.GithubResult{Inactive: true}
|
||||
mu.Unlock()
|
||||
wg.Done()
|
||||
return
|
||||
}
|
||||
githubResult := osint.Search(s, cleanQueryText, q.Column)
|
||||
mu.Lock()
|
||||
if githubResult == nil {
|
||||
r.GithubResult = osint.GithubResult{}
|
||||
} else {
|
||||
r.GithubResult = *githubResult
|
||||
var githubResult osint.GithubResult
|
||||
if isEmail {
|
||||
githubResult = osint.GithubSearch(s, cleanQueryText, "email")
|
||||
} else if isUsername {
|
||||
githubResult = osint.GithubSearch(s, cleanQueryText, "username")
|
||||
}
|
||||
mu.Lock()
|
||||
r.GithubResult = githubResult
|
||||
mu.Unlock()
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
if !q.GravatarRecon || !s.Settings.GravatarRecon || !isEmail {
|
||||
mu.Lock()
|
||||
r.GravatarResult = osint.GravatarResult{Inactive: true}
|
||||
mu.Unlock()
|
||||
wg.Done()
|
||||
return
|
||||
}
|
||||
gravatarResult := osint.GravatarSearch(s, cleanQueryText)
|
||||
mu.Lock()
|
||||
r.GravatarResult = gravatarResult
|
||||
mu.Unlock()
|
||||
wg.Done()
|
||||
}()
|
||||
@@ -91,3 +121,26 @@ func EncodeQueryID(q Query, dataleaksCount uint64) string {
|
||||
raw, _ := json.Marshal(q)
|
||||
return fmt.Sprintf("%d:%s", dataleaksCount, base64.URLEncoding.EncodeToString(raw))
|
||||
}
|
||||
|
||||
func isValidEmail(email string) bool {
|
||||
if !strings.Contains(email, "@") || !strings.Contains(email, ".") {
|
||||
return false
|
||||
}
|
||||
if strings.HasPrefix(email, "@") || strings.HasSuffix(email, "@") {
|
||||
return false
|
||||
}
|
||||
if strings.Contains(email, " ") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isValidUsername(username string) bool {
|
||||
if len(username) < 1 || len(username) > 39 {
|
||||
return false
|
||||
}
|
||||
if strings.Contains(username, " ") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ type ServerSettings struct {
|
||||
GithubToken string `json:"-"` // Github token for github-recon
|
||||
GithubTokenLoaded bool
|
||||
GithubDeepMode bool // Deep mode for github-recon
|
||||
GravatarRecon bool // Activate gravatar-recon OSINT tool
|
||||
}
|
||||
|
||||
func LoadServerSettings() ServerSettings {
|
||||
@@ -49,6 +50,7 @@ func LoadServerSettings() ServerSettings {
|
||||
GithubRecon: getEnvBoolOrDefault("GITHUB_RECON", true),
|
||||
GithubToken: getEnvStringOrDefault("GITHUB_TOKEN", "null"),
|
||||
GithubDeepMode: getEnvBoolOrDefault("GITHUB_DEEP_MODE", false),
|
||||
GravatarRecon: getEnvBoolOrDefault("GRAVATAR_RECON", true),
|
||||
}
|
||||
|
||||
if ss.GithubToken == "null" || strings.TrimSpace(ss.GithubToken) == "" {
|
||||
|
||||
Reference in New Issue
Block a user