first commit

This commit is contained in:
Ar1ste1a
2025-05-14 22:00:38 -04:00
commit a4dffe61bf
27 changed files with 4742 additions and 0 deletions
+124
View File
@@ -0,0 +1,124 @@
# Dehasher
## A cli tool built for interaction with the Dehash API
<div align="center">
<img src="https://img.wanman.io/fUSu0/SaCUyEMe87.png/raw" style="width: 350px; height: auto" alt="Ar1ste1a" title="Ar1ste1a Offensive Security">
</div>
# Features
- Output Format Control
- Request Limiting
- Record Limiting
- Regular Expression Handling
- Exact Match Handling
- Error Handling
- Credential Dumping
- Intelligent Token Usage
# Options
```bash-session
usage: Dehasher [-h --help] {-k --key} {-a --authorized-email} [-h --help] [-m --max-records] [-r --max-requests] [-B --print-balance] [-X --exact-match] [-R --regex-match] [-t --list-tokens] [-o --output-file-name] [-T --output-txt] [-J --output-json] [-Y --output-yaml] [-x --output-xml] [-U --username-query] [-E --email-query] [-I --ip-address-query] [-P --password-query] [-Q --hashed-password-query] [-N --name-query] [-C --creds-only]
Dehashed Tool
options:
-h --help show this help message and exit
-m --max-records Maximum amount of records to return
-r --max-requests Maximum number of requests to make
-B --print-balance Print remaining balance after requests
-X --exact-match Use Exact Matching on fields
-R --regex-match Use Regex Matching on fields
-t --list-tokens List the number of tokens remaining
-o --output-file-name File to output results to
-T --output-txt Output to text file
-J --output-json Output to JSON file
-Y --output-yaml Output to YAML file
-x --output-xml Output to XML file
-U --username-query Username Query
-E --email-query Email Query
-I --ip-address-query IP Address Query
-P --password-query Password Query
-Q --hashed-password-query Hashed Password Query
-N --name-query Name Query
-C --creds-only Return Credentials Only
-k --key API Key
-a --authorized-email Email to pair with key for authentication
v1.0
```
# Sample Run
```bash-session
-k ddq<redacted> -a ar1ste1a@<redacted> -E @example.com -C -o example_creds
Making 3 Requests for 10000 Records (30000 Total)
[*] Performing Request...
[*] Retrieved 60 Records
[-] Not Enough Entries, ending queries
[+] Discovered 60 Records
[*] Writing entries file: example_creds.json
[*] Success
```
# Getting Started
To begin, clone the repository
``` bash-session
git clone https://github.com/Ar1ste1a/Dehasher.git
cd Dehasher
go build dehasher.go
```
# Crafting a query
## Simple Query
``` go
# Provide credentials for emails matching @target.com
dehasher -k ddq<redacted> -a ar1ste1a@domain.tld -E @target.com
```
## Simple Credentials Query
``` go
# Provide credentials for emails matching @target.com
dehasher -k ddq<redacted> -a ar1ste1a@domain.tld -E @target.com -C
```
## Simple Query Returning Balance
``` go
# Provide credentials for emails matching @target.com
dehasher -k ddq<redacted> -a ar1ste1a@domain.tld -E @target.com -C -B
```
## Regex Query
``` go
# Return matches for emails matching this given regex query
# -R e: Specify the '-E' field as a regex entry
dehasher -k ddq<redacted> -a ar1ste1a@domain.tld -E '[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)?@target.com' -C -B -R e
```
## Exact Match Query
``` go
# Return matches for usernames exactly matching "admin"
# -X u: Specify the '-U' field as an exact match entry
dehasher -k ddq<redacted> -a ar1ste1a@domain.tld -C -B -U admin -X u
```
## Output Text (default JSON)
``` go
# Return matches for usernames exactly matching "admin" and write to text file 'admins_file.txt'
dehasher -k ddq<redacted> -a ar1ste1a@domain.tld -C -B -U admin -X u -T -o admins_file
```
## Output YAML
``` go
# Return matches for usernames exactly matching "admin" and write to yaml file 'admins_file.yaml'
dehasher -k ddq<redacted> -a ar1ste1a@domain.tld -C -B -U admin -X u -Y -o admins_file
```
## Output XML
``` go
# Return matches for usernames exactly matching "admin" and write to xml file 'admins_file.xml'
dehasher -k ddq<redacted> -a ar1ste1a@domain.tld -C -B -U admin -X u -x -o admins_file
```
+656
View File
@@ -0,0 +1,656 @@
package cmd
import (
"dehasher/internal/export"
"dehasher/internal/files"
"dehasher/internal/pretty"
"dehasher/internal/sqlite"
"encoding/json"
"fmt"
"github.com/spf13/cobra"
"go.uber.org/zap"
"strings"
"time"
)
var (
// DB command flags
dbPath string
// DB query command flags
usernameDBQuery string
emailDBQuery string
ipDBQuery string
passwordDBQuery string
hashDBQuery string
nameDBQuery string
vinDBQuery string
licensePlateDBQuery string
addressDBQuery string
phoneDBQuery string
socialDBQuery string
cryptoCurrencyAddressDBQuery string
domainDBQuery string
limitResultsDB int
exactMatchDBQuery bool
outputFormatDB string
nonEmptyFieldsDBQuery string
displayFieldsDBQuery string
tableTypeDBQuery string
// DB runs command flags
startDateDBRuns string
endDateDBRuns string
containsQueryDBRuns string
lastXRunsDBRuns int
// DB command
dbCmd = &cobra.Command{
Use: "db",
Short: "Database operations for Dehasher",
Long: `Perform database operations like export, import, and query on the local Dehasher database.`,
}
)
func init() {
// Add subcommands to db command
dbCmd.AddCommand(dbExportCmd)
dbCmd.AddCommand(dbQueryCmd)
dbCmd.AddCommand(dbRunsCmd)
dbCmd.AddCommand(dbCredsCmd)
// Add flags specific to db command
dbCmd.PersistentFlags().StringVarP(&dbPath, "db-path", "D", "", "Path to database (default: ~/.local/share/Dehasher/dehashed.db)")
// Add flags specific to db query command
dbQueryCmd.Flags().StringVarP(&usernameDBQuery, "username", "u", "", "Filter by username")
dbQueryCmd.Flags().StringVarP(&emailDBQuery, "email", "e", "", "Filter by email")
dbQueryCmd.Flags().StringVarP(&ipDBQuery, "ip", "i", "", "Filter by IP address")
dbQueryCmd.Flags().StringVarP(&passwordDBQuery, "password", "p", "", "Filter by password")
dbQueryCmd.Flags().StringVarP(&hashDBQuery, "hash", "H", "", "Filter by hashed password")
dbQueryCmd.Flags().StringVarP(&nameDBQuery, "name", "n", "", "Filter by name")
dbQueryCmd.Flags().StringVarP(&vinDBQuery, "vin", "v", "", "Filter by VIN")
dbQueryCmd.Flags().StringVarP(&licensePlateDBQuery, "license", "L", "", "Filter by license plate")
dbQueryCmd.Flags().StringVarP(&addressDBQuery, "address", "a", "", "Filter by address")
dbQueryCmd.Flags().StringVarP(&phoneDBQuery, "phone", "P", "", "Filter by phone number")
dbQueryCmd.Flags().StringVarP(&socialDBQuery, "social", "s", "", "Filter by social media handle")
dbQueryCmd.Flags().StringVarP(&cryptoCurrencyAddressDBQuery, "crypto", "c", "", "Filter by cryptocurrency address")
dbQueryCmd.Flags().StringVarP(&domainDBQuery, "domain", "d", "", "Filter by domain/URL")
dbQueryCmd.Flags().IntVarP(&limitResultsDB, "limit", "l", 100, "Limit number of results")
dbQueryCmd.Flags().BoolVarP(&exactMatchDBQuery, "exact", "x", false, "Use exact matching instead of partial matching")
dbQueryCmd.Flags().StringVarP(&outputFormatDB, "format", "f", "table", "Output format (json, table, simple)")
dbQueryCmd.Flags().StringVar(&nonEmptyFieldsDBQuery, "non-empty", "", "Filter for non-empty fields (comma-separated list, e.g., 'password,email')")
dbQueryCmd.Flags().StringVar(&displayFieldsDBQuery, "display", "", "Fields to display in output (comma-separated list, e.g., 'username,email,password')")
dbQueryCmd.Flags().StringVarP(&tableTypeDBQuery, "table", "t", "results", "Table to query (results, runs, creds)")
// Add flags specific to db runs command
dbRunsCmd.Flags().StringVarP(&startDateDBRuns, "start-date", "s", "", "Start date for filtering runs (format: YYYY-MM-DD)")
dbRunsCmd.Flags().StringVarP(&endDateDBRuns, "end-date", "e", "", "End date for filtering runs (format: YYYY-MM-DD)")
dbRunsCmd.Flags().StringVarP(&containsQueryDBRuns, "contains", "c", "", "Filter runs containing this query string")
dbRunsCmd.Flags().IntVarP(&lastXRunsDBRuns, "last", "x", 0, "Show the last X runs")
dbRunsCmd.Flags().IntVarP(&limitResultsDB, "limit", "l", 100, "Limit number of results")
dbRunsCmd.Flags().StringVarP(&outputFormatDB, "format", "f", "table", "Output format (json, table, simple)")
// Add flags specific to db creds command
dbCredsCmd.Flags().StringVarP(&usernameDBQuery, "username", "u", "", "Filter by username")
dbCredsCmd.Flags().StringVarP(&emailDBQuery, "email", "e", "", "Filter by email")
dbCredsCmd.Flags().StringVarP(&passwordDBQuery, "password", "p", "", "Filter by password")
dbCredsCmd.Flags().IntVarP(&limitResultsDB, "limit", "l", 100, "Limit number of results")
dbCredsCmd.Flags().BoolVarP(&exactMatchDBQuery, "exact", "x", false, "Use exact matching instead of partial matching")
dbCredsCmd.Flags().StringVarP(&outputFormatDB, "format", "f", "table", "Output format (json, table, simple)")
dbCredsCmd.Flags().StringVar(&nonEmptyFieldsDBQuery, "non-empty", "", "Filter for non-empty fields (comma-separated list, e.g., 'password,email')")
dbCredsCmd.Flags().StringVar(&displayFieldsDBQuery, "display", "", "Fields to display in output (comma-separated list, e.g., 'username,email,password')")
}
// DB export command
var dbExportCmd = &cobra.Command{
Use: "export",
Short: "Export database to file",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Exporting database...")
// Create DBOptions with the provided parameters
options := &sqlite.DBOptions{
Username: usernameDBQuery,
Email: emailDBQuery,
IPAddress: ipDBQuery,
Password: passwordDBQuery,
HashedPassword: hashDBQuery,
Name: nameDBQuery,
Limit: limitResultsDB,
ExactMatch: exactMatchDBQuery,
}
// Parse non-empty fields if provided
if nonEmptyFieldsDBQuery != "" {
options.NonEmptyFields = strings.Split(nonEmptyFieldsDBQuery, ",")
}
// Parse display fields if provided
if displayFieldsDBQuery != "" {
options.DisplayFields = strings.Split(displayFieldsDBQuery, ",")
}
// Check if at least one search parameter is provided
if options.Username == "" && options.Email == "" && options.IPAddress == "" &&
options.Password == "" && options.HashedPassword == "" && options.Name == "" &&
len(options.NonEmptyFields) == 0 {
fmt.Println("Error: At least one search parameter is required.")
cmd.Help()
return
}
// Get the count of matching results
count, err := sqlite.GetResultsCount(options)
if err != nil {
fmt.Printf("Error counting results: %v\n", err)
return
}
// Query the database
results, err := sqlite.QueryResults(options)
if err != nil {
fmt.Printf("Error querying database: %v\n", err)
return
}
dhResults := sqlite.DehashedResults{Results: results}
fmt.Printf("Found %d results (showing %d):\n", count, len(results))
// Output results based on format
ft := files.GetFileType(outputFormatDB)
err = export.WriteToFile(dhResults, "dehasher_export", ft)
if err != nil {
zap.L().Error("write_to_file",
zap.String("message", "failed to write to file"),
zap.Error(err),
)
fmt.Printf("Error writing to file: %v\n", err)
return
}
fmt.Printf("Exported successfully to file: dehasher_export%s\n", ft.Extension())
},
}
// DB query command
var dbQueryCmd = &cobra.Command{
Use: "query",
Short: "Query local database",
Long: `Query the local database for previously run dehasher queries based on various parameters.`,
Run: func(cmd *cobra.Command, args []string) {
// Determine which table to query based on the tableTypeDBQuery parameter
switch tableTypeDBQuery {
case "results":
queryResultsTable(cmd)
case "runs":
queryRunsTable()
case "creds":
queryCredsTable(cmd)
default:
fmt.Printf("Error: Unknown table type '%s'. Valid options are: results, runs, creds\n", tableTypeDBQuery)
cmd.Help()
return
}
},
}
func queryRunsTable() {
// Parse date strings to time.Time
var startDate, endDate time.Time
var err error
if startDateDBRuns != "" {
startDate, err = time.Parse("2006-01-02", startDateDBRuns)
if err != nil {
fmt.Printf("Error parsing start date: %v\n", err)
return
}
}
if endDateDBRuns != "" {
endDate, err = time.Parse("2006-01-02", endDateDBRuns)
if err != nil {
fmt.Printf("Error parsing end date: %v\n", err)
return
}
// Set end date to end of day
endDate = endDate.Add(24*time.Hour - time.Second)
}
// Get the count of matching runs
count, err := sqlite.GetRunsCount(lastXRunsDBRuns, startDate, endDate, containsQueryDBRuns)
if err != nil {
fmt.Printf("Error counting runs: %v\n", err)
return
}
// Query the database
runs, err := sqlite.QueryRuns(limitResultsDB, lastXRunsDBRuns, startDate, endDate, containsQueryDBRuns)
if err != nil {
fmt.Printf("Error querying runs: %v\n", err)
return
}
displayRunsResults(count, runs)
}
func displayRunsResults(count int64, runs []sqlite.QueryOptions) {
// Display the results
fmt.Printf("Found %d runs (showing %d):\n", count, len(runs))
if len(runs) == 0 {
fmt.Println("No runs found.")
return
}
// Output results based on format
switch outputFormatDB {
case "json":
data, err := json.MarshalIndent(runs, "", " ")
if err != nil {
fmt.Printf("Error formatting results: %v\n", err)
return
}
fmt.Println(string(data))
case "table":
// Define headers and rows for the table
headers := []string{"ID", "Created At", "Max Records", "Username Query", "Email Query", "IP Query", "Password Query", "Hash Query", "Name Query", "Domain Query"}
rows := make([][]string, len(runs))
for i, run := range runs {
rows[i] = []string{
fmt.Sprintf("%d", run.ID),
run.CreatedAt.Format("2006-01-02 15:04:05"),
fmt.Sprintf("%d", run.MaxRecords),
truncate(run.UsernameQuery, 20),
truncate(run.EmailQuery, 20),
truncate(run.IpQuery, 20),
truncate(run.PassQuery, 20),
truncate(run.HashQuery, 20),
truncate(run.NameQuery, 20),
truncate(run.DomainQuery, 20),
}
}
pretty.Table(headers, rows)
default:
// Simple output
for _, run := range runs {
fmt.Printf("Run ID: %d\n", run.ID)
fmt.Printf(" Created At: %s\n", run.CreatedAt.Format("2006-01-02 15:04:05"))
fmt.Printf(" Max Records: %d\n", run.MaxRecords)
fmt.Printf(" Max Requests: %d\n", run.MaxRequests)
fmt.Printf(" Starting Page: %d\n", run.StartingPage)
fmt.Printf(" Output Format: %s\n", run.OutputFormat.String())
fmt.Printf(" Output File: %s\n", run.OutputFile)
fmt.Printf(" Regex Match: %t\n", run.RegexMatch)
fmt.Printf(" Wildcard Match: %t\n", run.WildcardMatch)
fmt.Printf(" Username Query: %s\n", run.UsernameQuery)
fmt.Printf(" Email Query: %s\n", run.EmailQuery)
fmt.Printf(" IP Query: %s\n", run.IpQuery)
fmt.Printf(" Password Query: %s\n", run.PassQuery)
fmt.Printf(" Hash Query: %s\n", run.HashQuery)
fmt.Printf(" Name Query: %s\n", run.NameQuery)
fmt.Printf(" Domain Query: %s\n", run.DomainQuery)
fmt.Printf(" VIN Query: %s\n", run.VinQuery)
fmt.Printf(" License Plate Query: %s\n", run.LicensePlateQuery)
fmt.Printf(" Address Query: %s\n", run.AddressQuery)
fmt.Printf(" Phone Query: %s\n", run.PhoneQuery)
fmt.Printf(" Social Query: %s\n", run.SocialQuery)
fmt.Printf(" Crypto Address Query: %s\n", run.CryptoAddressQuery)
fmt.Printf(" Print Balance: %t\n", run.PrintBalance)
fmt.Printf(" Creds Only: %t\n", run.CredsOnly)
fmt.Println()
}
}
}
// queryResultsTable queries the results table
func queryResultsTable(cmd *cobra.Command) {
// Create DBOptions with the provided parameters
options := &sqlite.DBOptions{
Username: usernameDBQuery,
Email: emailDBQuery,
IPAddress: ipDBQuery,
Password: passwordDBQuery,
HashedPassword: hashDBQuery,
Name: nameDBQuery,
Vin: vinDBQuery,
LicensePlate: licensePlateDBQuery,
Address: addressDBQuery,
Phone: phoneDBQuery,
Social: socialDBQuery,
CryptoCurrencyAddress: cryptoCurrencyAddressDBQuery,
Domain: domainDBQuery,
Limit: limitResultsDB,
ExactMatch: exactMatchDBQuery,
}
// Parse non-empty fields if provided
if nonEmptyFieldsDBQuery != "" {
options.NonEmptyFields = strings.Split(nonEmptyFieldsDBQuery, ",")
}
// Parse display fields if provided
if displayFieldsDBQuery != "" {
options.DisplayFields = strings.Split(displayFieldsDBQuery, ",")
}
// Check if at least one search parameter is provided
if options.Empty() {
fmt.Println("Error: At least one search parameter is required.")
cmd.Help()
return
}
// Get the count of matching results
count, err := sqlite.GetResultsCount(options)
if err != nil {
fmt.Printf("Error counting results: %v\n", err)
return
}
// Query the database
results, err := sqlite.QueryResults(options)
if err != nil {
fmt.Printf("Error querying database: %v\n", err)
return
}
// Display the results
displayResultsTable(count, results, options)
}
// displayResultsTable displays the results from the results table
func displayResultsTable(count int64, results []sqlite.Result, options *sqlite.DBOptions) {
// Display the results
fmt.Printf("Found %d results (showing %d):\n", count, len(results))
if len(results) == 0 {
fmt.Println("No results found.")
return
}
// Output results based on format
switch outputFormatDB {
case "json":
data, err := json.MarshalIndent(results, "", " ")
if err != nil {
fmt.Printf("Error formatting results: %v\n", err)
return
}
fmt.Println(string(data))
case "table":
// Determine which fields to display
type FieldInfo struct {
Name string
Width int
Getter func(result sqlite.Result) string
}
// Define all available fields
allFields := []FieldInfo{
{"Username", 20, func(r sqlite.Result) string { return truncate(arrayToString(r.Username), 20) }},
{"Email", 30, func(r sqlite.Result) string { return truncate(arrayToString(r.Email), 30) }},
{"IP Address", 15, func(r sqlite.Result) string { return truncate(arrayToString(r.IpAddress), 15) }},
{"Password", 20, func(r sqlite.Result) string { return truncate(arrayToString(r.Password), 20) }},
{"Hashed Password", 20, func(r sqlite.Result) string { return truncate(arrayToString(r.HashedPassword), 20) }},
{"Name", 20, func(r sqlite.Result) string { return truncate(arrayToString(r.Name), 20) }},
{"VIN", 20, func(r sqlite.Result) string { return truncate(arrayToString(r.Vin), 20) }},
{"License Plate", 15, func(r sqlite.Result) string { return truncate(arrayToString(r.LicensePlate), 15) }},
{"Address", 30, func(r sqlite.Result) string { return truncate(arrayToString(r.Address), 30) }},
{"Phone", 15, func(r sqlite.Result) string { return truncate(arrayToString(r.Phone), 15) }},
{"Social", 20, func(r sqlite.Result) string { return truncate(arrayToString(r.Social), 20) }},
{"Crypto Address", 20, func(r sqlite.Result) string { return truncate(arrayToString(r.CryptoCurrencyAddress), 20) }},
{"Domain/URL", 30, func(r sqlite.Result) string { return truncate(arrayToString(r.Url), 30) }},
}
// Select fields to display
var fieldsToDisplay []FieldInfo
var headers []string
if len(options.DisplayFields) > 0 {
// Use specified fields
for _, fieldName := range options.DisplayFields {
fieldName = strings.ToLower(strings.TrimSpace(fieldName))
for _, field := range allFields {
if strings.ToLower(field.Name) == fieldName ||
(fieldName == "ip" && strings.ToLower(field.Name) == "ip address") ||
(fieldName == "hash" && strings.ToLower(field.Name) == "hashed password") ||
(fieldName == "license" && strings.ToLower(field.Name) == "license plate") ||
(fieldName == "crypto" && strings.ToLower(field.Name) == "crypto address") ||
(fieldName == "url" && strings.ToLower(field.Name) == "domain/url") {
fieldsToDisplay = append(fieldsToDisplay, field)
headers = append(headers, field.Name)
break
}
}
}
} else {
// Default fields (first 6)
fieldsToDisplay = allFields[:6]
}
var rows [][]string
for _, result := range results {
rowValues := []string{}
for _, field := range fieldsToDisplay {
rowValues = append(rowValues, field.Getter(result))
}
rows = append(rows, rowValues)
}
pretty.Table(headers, rows)
default:
// Simple output
for i, result := range results {
fmt.Printf("Result %d:\n", i+1)
// Determine which fields to display
if len(options.DisplayFields) > 0 {
// Display only specified fields
for _, field := range options.DisplayFields {
field = strings.ToLower(strings.TrimSpace(field))
switch field {
case "username":
fmt.Printf(" Username: %s\n", result.Username)
case "email":
fmt.Printf(" Email: %s\n", result.Email)
case "ip", "ipaddress", "ip_address":
fmt.Printf(" IP Address: %s\n", result.IpAddress)
case "password":
fmt.Printf(" Password: %s\n", result.Password)
case "hash", "hashed_password":
fmt.Printf(" Hashed Password: %s\n", result.HashedPassword)
case "name":
fmt.Printf(" Name: %s\n", result.Name)
case "vin":
fmt.Printf(" VIN: %s\n", result.Vin)
case "license", "license_plate":
fmt.Printf(" License Plate: %s\n", result.LicensePlate)
case "address":
fmt.Printf(" Address: %s\n", result.Address)
case "phone":
fmt.Printf(" Phone: %s\n", result.Phone)
case "social":
fmt.Printf(" Social: %s\n", result.Social)
case "crypto", "cryptocurrency_address":
fmt.Printf(" Crypto Address: %s\n", result.CryptoCurrencyAddress)
case "domain", "url":
fmt.Printf(" Domain/URL: %s\n", result.Url)
}
}
} else {
// Display default fields
fmt.Printf(" Username: %s\n", result.Username)
fmt.Printf(" Email: %s\n", result.Email)
fmt.Printf(" IP Address: %s\n", result.IpAddress)
fmt.Printf(" Password: %s\n", result.Password)
fmt.Printf(" Hashed Password: %s\n", result.HashedPassword)
fmt.Printf(" Name: %s\n", result.Name)
}
fmt.Println()
}
}
}
// truncate truncates a string to the specified length and adds ellipsis if needed
func truncate(s string, length int) string {
if len(s) <= length {
return s
}
return s[:length-3] + "..."
}
func arrayToString(a []string) string {
return strings.Join(a, ", ")
}
// DB runs command
var dbRunsCmd = &cobra.Command{
Use: "runs",
Short: "Query previous query runs",
Long: `Query the database for previous query runs (QueryOptions) based on date range and query content.`,
Run: func(cmd *cobra.Command, args []string) {
// Call queryRunsTable directly
queryRunsTable()
},
}
// DB creds command
var dbCredsCmd = &cobra.Command{
Use: "creds",
Short: "Query credentials",
Long: `Query the database for credentials based on username, email, and password.`,
Run: func(cmd *cobra.Command, args []string) {
// Call queryCredsTable directly
queryCredsTable(cmd)
},
}
// queryCredsTable queries the credentials table
func queryCredsTable(cmd *cobra.Command) {
// Create DBOptions with the provided parameters
options := &sqlite.DBOptions{
Username: usernameDBQuery,
Email: emailDBQuery,
Password: passwordDBQuery,
Limit: limitResultsDB,
ExactMatch: exactMatchDBQuery,
}
// Parse non-empty fields if provided
if nonEmptyFieldsDBQuery != "" {
options.NonEmptyFields = strings.Split(nonEmptyFieldsDBQuery, ",")
}
// Parse display fields if provided
if displayFieldsDBQuery != "" {
options.DisplayFields = strings.Split(displayFieldsDBQuery, ",")
}
// Check if at least one search parameter is provided
if options.Username == "" && options.Email == "" && options.Password == "" && len(options.NonEmptyFields) == 0 {
fmt.Println("Error: At least one search parameter is required.")
cmd.Help()
return
}
// Get the count of matching credentials
count, err := sqlite.GetCredsCount(options)
if err != nil {
fmt.Printf("Error counting credentials: %v\n", err)
return
}
// Query the database
creds, err := sqlite.QueryCreds(options)
if err != nil {
fmt.Printf("Error querying credentials: %v\n", err)
return
}
// Display the results
displayCredsResults(count, creds)
}
// displayCredsResults displays the results from the creds table
func displayCredsResults(count int64, creds []sqlite.Creds) {
// Display the results
fmt.Printf("Found %d credentials (showing %d):\n", count, len(creds))
if len(creds) == 0 {
fmt.Println("No credentials found.")
return
}
// Output results based on format
switch outputFormatDB {
case "json":
data, err := json.MarshalIndent(creds, "", " ")
if err != nil {
fmt.Printf("Error formatting results: %v\n", err)
return
}
fmt.Println(string(data))
case "table":
// Define all available fields
type FieldInfo struct {
Name string
Getter func(cred sqlite.Creds) string
}
allFields := []FieldInfo{
{"ID", func(c sqlite.Creds) string { return fmt.Sprintf("%d", c.ID) }},
{"Created At", func(c sqlite.Creds) string { return c.CreatedAt.Format("2006-01-02 15:04:05") }},
{"Email", func(c sqlite.Creds) string { return c.Email }},
{"Username", func(c sqlite.Creds) string { return c.Username }},
{"Password", func(c sqlite.Creds) string { return c.Password }},
}
// Select fields to display
var fieldsToDisplay []FieldInfo
var headers []string
if len(displayFieldsDBQuery) > 0 {
// Use specified display fields
displayFields := strings.Split(displayFieldsDBQuery, ",")
for _, fieldName := range displayFields {
fieldName = strings.ToLower(strings.TrimSpace(fieldName))
for _, field := range allFields {
if strings.ToLower(field.Name) == fieldName {
fieldsToDisplay = append(fieldsToDisplay, field)
headers = append(headers, field.Name)
break
}
}
}
} else {
// Default fields
fieldsToDisplay = allFields
for _, field := range fieldsToDisplay {
headers = append(headers, field.Name)
}
}
// Create rows
rows := make([][]string, len(creds))
for i, cred := range creds {
rowValues := []string{}
for _, field := range fieldsToDisplay {
rowValues = append(rowValues, field.Getter(cred))
}
rows[i] = rowValues
}
pretty.Table(headers, rows)
default:
// Simple output
for _, cred := range creds {
fmt.Printf("Credential ID: %d\n", cred.ID)
fmt.Printf(" Created At: %s\n", cred.CreatedAt.Format("2006-01-02 15:04:05"))
fmt.Printf(" Email: %s\n", cred.Email)
fmt.Printf(" Username: %s\n", cred.Username)
fmt.Printf(" Password: %s\n", cred.Password)
fmt.Println()
}
}
}
+137
View File
@@ -0,0 +1,137 @@
package cmd
import (
"dehasher/internal/badger"
"dehasher/internal/query"
"dehasher/internal/sqlite"
"fmt"
"github.com/spf13/cobra"
)
var (
// Query command flags
maxRecords int
maxRequests int
startingPage int
credsOnly bool
printBalance bool
regexMatch bool
wildcardMatch bool
outputFormat string
outputFile string
usernameQuery string
emailQuery string
ipQuery string
passwordQuery string
hashQuery string
nameQuery string
domainQuery string
vinQuery string
licensePlateQuery string
addressQuery string
phoneQuery string
socialQuery string
cryptoCurrencyAddressQuery string
// Query command
queryCmd = &cobra.Command{
Use: "query",
Short: "Query the Dehashed API",
Long: `Query the Dehashed API for emails, usernames, passwords, hashes, IP addresses, and names.`,
Run: func(cmd *cobra.Command, args []string) {
// Check if API key and email are provided
key := apiKey
email := apiEmail
// If not provided as flags, try to get from stored values
if key == "" {
key = getStoredApiKey()
}
if email == "" {
email = getStoredApiEmail()
}
// Validate credentials
if key == "" || email == "" {
fmt.Println("API key and email are required. Use --key and --email flags or set them with set-key and set-email commands.")
return
}
// Create new QueryOptions
queryOptions := sqlite.NewQueryOptions(
maxRecords,
maxRequests,
startingPage,
outputFormat,
outputFile,
usernameQuery,
emailQuery,
ipQuery,
passwordQuery,
hashQuery,
nameQuery,
domainQuery,
vinQuery,
licensePlateQuery,
addressQuery,
phoneQuery,
socialQuery,
cryptoCurrencyAddressQuery,
regexMatch,
wildcardMatch,
printBalance,
credsOnly,
)
// Create new Dehasher
dehasher := query.NewDehasher(queryOptions)
dehasher.SetClientCredentials(
key,
)
// Start querying
dehasher.Start()
fmt.Println("\n[*] Completing Process")
sqlite.StoreQueryOptions(queryOptions)
},
}
)
func init() {
// Add flags specific to query command
queryCmd.Flags().IntVarP(&maxRecords, "max-records", "m", 30000, "Maximum amount of records to return")
queryCmd.Flags().IntVarP(&maxRequests, "max-requests", "r", -1, "Maximum number of requests to make")
queryCmd.Flags().IntVarP(&startingPage, "starting-page", "s", 1, "Starting page for requests")
queryCmd.Flags().BoolVarP(&printBalance, "print-balance", "b", false, "Print remaining balance after requests")
queryCmd.Flags().BoolVarP(&regexMatch, "regex-match", "R", false, "Use regex matching on query fields")
queryCmd.Flags().BoolVarP(&wildcardMatch, "wildcard-match", "W", false, "Use wildcard matching on query fields (Use ? to replace a single character, and * for multiple characters)")
queryCmd.Flags().BoolVarP(&credsOnly, "creds-only", "C", false, "Return credentials only")
queryCmd.Flags().StringVarP(&outputFormat, "format", "f", "json", "Output format (json, yaml, xml, txt)")
queryCmd.Flags().StringVarP(&outputFile, "output", "o", "query", "File to output results to including extension")
queryCmd.Flags().StringVarP(&usernameQuery, "username", "U", "", "Username query")
queryCmd.Flags().StringVarP(&emailQuery, "email-query", "E", "", "Email query")
queryCmd.Flags().StringVarP(&ipQuery, "ip", "I", "", "IP address query")
queryCmd.Flags().StringVarP(&domainQuery, "domain", "D", "", "Domain query")
queryCmd.Flags().StringVarP(&passwordQuery, "password", "P", "", "Password query")
queryCmd.Flags().StringVarP(&vinQuery, "vin", "V", "", "VIN query")
queryCmd.Flags().StringVarP(&licensePlateQuery, "license", "L", "", "License plate query")
queryCmd.Flags().StringVarP(&addressQuery, "address", "A", "", "Address query")
queryCmd.Flags().StringVarP(&phoneQuery, "phone", "M", "", "Phone query")
queryCmd.Flags().StringVarP(&socialQuery, "social", "S", "", "Social query")
queryCmd.Flags().StringVarP(&cryptoCurrencyAddressQuery, "crypto", "B", "", "Crypto currency address query")
queryCmd.Flags().StringVarP(&hashQuery, "hash", "Q", "", "Hashed password query")
queryCmd.Flags().StringVarP(&nameQuery, "name", "N", "", "Name query")
// Add mutually exclusive flags to exact match and regex match
queryCmd.MarkFlagsMutuallyExclusive("regex-match", "wildcard-match")
}
// Helper functions to get stored API credentials
func getStoredApiKey() string {
return badger.GetKey()
}
func getStoredApiEmail() string {
return badger.GetEmail()
}
+126
View File
@@ -0,0 +1,126 @@
package cmd
import (
"dehasher/internal/badger"
"fmt"
"github.com/spf13/cobra"
"go.uber.org/zap"
"os"
)
var (
// Global Flags
apiKey string
apiEmail string
// rootCmd is the base command for the CLI.
rootCmd = &cobra.Command{
Use: "dehasher",
Short: `Dehasher is a cli tool for querying query.`,
Long: fmt.Sprintf(
"%s\n%s",
`
______ _______ _______ _______ _______ _______
( __ \ ( ____ \|\ /|( ___ )( ____ \|\ /|( ____ \( ____ )
| ( \ )| ( \/| ) ( || ( ) || ( \/| ) ( || ( \/| ( )|
| | ) || (__ | (___) || (___) || (_____ | (___) || (__ | (____)|
| | | || __) | ___ || ___ |(_____ )| ___ || __) | __)
| | ) || ( | ( ) || ( ) | ) || ( ) || ( | (\ (
| (__/ )| (____/\| ) ( || ) ( |/\____) || ) ( || (____/\| ) \ \__
(______/ (_______/|/ \||/ \|\_______)|/ \|(_______/|/ \__/
An Ar1ste1a Project
`,
`––•–√\/––√\/––•––––•–√\/––√\/––•––––•–√\/––√\/––•––√\/––•––––•–√\/––√\/––•––
Dehasher can query the query API for:
- Emails - Usernames - Password
- Hashes - IP Addresses - Names
- VINs - License Plates - Addresses
- Phones - Social Media - Crypto Currency Addresses
Dehasher supports:
- Regex Matching
- Exact Matching
––•–√\/––√\/––•––––•–√\/––√\/––•––––•–√\/––√\/––•––√\/––•––––•–√\/––√\/––•––
`,
),
Version: "v1.0",
}
)
// Execute adds all child commands to the root command and sets flags appropriately.
func Execute() {
if err := rootCmd.Execute(); err != nil {
zap.L().Fatal("execute_root_command",
zap.String("message", "failed to execute root command"),
zap.Error(err),
)
fmt.Printf("[!] %v", err)
os.Exit(1)
}
}
func init() {
// Hide the default help command
rootCmd.CompletionOptions.HiddenDefaultCmd = true
// Add global flags for API key and email
rootCmd.PersistentFlags().StringVarP(&apiKey, "key", "k", "", "API Key for authentication")
// Add subcommands
rootCmd.AddCommand(dbCmd)
rootCmd.AddCommand(queryCmd)
rootCmd.AddCommand(setKeyCmd)
rootCmd.AddCommand(setEmailCmd)
}
// Command to set API key
var setKeyCmd = &cobra.Command{
Use: "set-key [key]",
Short: "Set and store API key",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
key := args[0]
// Store key in badger DB
err := storeApiKey(key)
if err != nil {
fmt.Printf("Error storing API key: %v\n", err)
return
}
fmt.Println("API key stored successfully")
},
}
// Command to set API email
var setEmailCmd = &cobra.Command{
Use: "set-email [email]",
Short: "Set and store API email",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
email := args[0]
// Store email in badger DB
err := storeApiEmail(email)
if err != nil {
fmt.Printf("Error storing API email: %v\n", err)
return
}
fmt.Println("API email stored successfully")
},
}
// Helper functions to store API credentials
func storeApiKey(key string) error {
err := badger.StoreKey(key)
if err != nil {
fmt.Printf("Error storing API key: %v\n", err)
return err
}
return nil
}
func storeApiEmail(email string) error {
err := badger.StoreEmail(email)
if err != nil {
fmt.Printf("Error storing API email: %v\n", err)
return err
}
return nil
}
+303
View File
@@ -0,0 +1,303 @@
package cmd
import (
"dehasher/internal/sqlite"
"dehasher/internal/whois"
"fmt"
"github.com/spf13/cobra"
"go.uber.org/zap"
"strings"
)
var (
// WHOIS command flags
whoisDomain string
whoisIPAddress string
whoisMXAddress string
whoisNSAddress string
whoisInclude string
whoisExclude string
whoisReverseType string
whoisOutputFormat string
whoisShowCredits bool
whoisHistory bool
whoisSubdomainScan bool
// WHOIS command
whoisCmd = &cobra.Command{
Use: "whois",
Short: "Dehashed WHOIS lookups and reverse WHOIS searches",
Long: `Perform WHOIS lookups, history searches, reverse WHOIS searches, IP lookups, MX lookups, NS lookups, and subdomain scans.`,
Run: func(cmd *cobra.Command, args []string) {
// Check if API key is provided
key := apiKey
// If not provided as flag, try to get from stored value
if key == "" {
key = getStoredApiKey()
}
// Validate credentials
if key == "" {
fmt.Println("API key is required. Use --key flag or set it with set-key command.")
return
}
// Show credits if requested
if whoisShowCredits {
fmt.Println("[*] Getting WHOIS credits...")
credits, err := whois.GetWHOISCredits(key)
if err != nil {
zap.L().Error("get_whois_credits",
zap.String("message", "failed to get whois credits"),
zap.Error(err),
)
fmt.Printf("Error getting WHOIS credits: %v\n", err)
return
}
fmt.Printf("WHOIS Credits: %d\n", credits.WhoisCredits)
return
}
// Check if domain is provided for history and subdomain scan
if whoisHistory || whoisSubdomainScan {
if whoisDomain == "" {
fmt.Println("Domain is required for history and subdomain scan.")
return
}
}
// Determine which operation to perform based on flags
if whoisDomain != "" {
fmt.Println("[*] Performing WHOIS lookup...")
// Domain lookup
result, err := whois.WhoisSearch(whoisDomain, key)
if err != nil {
zap.L().Error("whois_search",
zap.String("message", "failed to perform whois search"),
zap.Error(err),
)
fmt.Printf("Error performing WHOIS lookup: %v\n", err)
return
}
// Fix the output format to use proper formatting
fmt.Printf("WHOIS Lookup Result:\n%+v\n", result.Data.WhoisRecord)
// Store the record
err = sqlite.StoreWhoisRecord(result.Data.WhoisRecord)
if err != nil {
zap.L().Error("store_whois_record",
zap.String("message", "failed to store whois record"),
zap.Error(err),
)
fmt.Printf("Error storing WHOIS record: %v\n", err)
// Continue execution even if storage fails
}
if whoisHistory {
fmt.Println("[*] Performing WHOIS history search...")
// Perform history search
history, err := whois.WhoisHistory(whoisDomain, key)
if err != nil {
zap.L().Error("whois_history",
zap.String("message", "failed to perform whois history lookup"),
zap.Error(err),
)
fmt.Printf("Error performing WHOIS history lookup: %v\n", err)
} else {
fmt.Println("\nWHOIS History:")
fmt.Println(history)
}
err = sqlite.StoreHistoryRecord(history.Data.Records)
if err != nil {
zap.L().Error("store_history_record",
zap.String("message", "failed to store history record"),
zap.Error(err),
)
fmt.Printf("Error storing WHOIS history record: %v\n", err)
}
}
// Perform subdomain scan
if whoisSubdomainScan {
fmt.Println("[*] Performing WHOIS subdomain scan...")
subdomains, err := whois.WhoisSubdomainScan(whoisDomain, key)
if err != nil {
zap.L().Error("whois_subdomain_scan",
zap.String("message", "failed to perform subdomain scan"),
zap.Error(err),
)
fmt.Printf("Error performing subdomain scan: %v\n", err)
} else {
fmt.Println("\nSubdomain Scan:")
fmt.Println(subdomains)
}
err = sqlite.StoreSubdomainRecord(subdomains.Data.Result.Records)
if err != nil {
zap.L().Error("store_subdomain_record",
zap.String("message", "failed to store subdomain record"),
zap.Error(err),
)
fmt.Printf("Error storing WHOIS subdomain record: %v\n", err)
}
}
// Get credits
credits, err := whois.GetWHOISCredits(key)
if err != nil {
zap.L().Error("get_whois_credits",
zap.String("message", "failed to get whois credits"),
zap.Error(err),
)
fmt.Printf("Error getting WHOIS credits: %v\n", err)
return
}
fmt.Printf("\nWHOIS Credits Remaining: %d\n", credits.WhoisCredits)
return
}
if whoisIPAddress != "" {
fmt.Println("[*] Performing reverse IP lookup...")
// IP lookup
result, err := whois.WhoisIP(whoisIPAddress, key)
if err != nil {
zap.L().Error("whois_ip",
zap.String("message", "failed to perform ip lookup"),
zap.Error(err),
)
fmt.Printf("Error performing IP lookup: %v\n", err)
return
}
fmt.Println("IP Lookup Result:")
fmt.Println(string(result))
// Get credits
credits, err := whois.GetWHOISCredits(key)
if err != nil {
zap.L().Error("get_whois_credits",
zap.String("message", "failed to get whois credits"),
zap.Error(err),
)
fmt.Printf("Error getting WHOIS credits: %v\n", err)
return
}
fmt.Printf("\nWHOIS Credits Remaining: %d\n", credits.WhoisCredits)
return
}
if whoisMXAddress != "" {
fmt.Println("[*] Performing reverse MX lookup...")
// MX lookup
result, err := whois.WhoisMX(whoisMXAddress, key)
if err != nil {
zap.L().Error("whois_mx",
zap.String("message", "failed to perform mx lookup"),
zap.Error(err),
)
fmt.Printf("Error performing MX lookup: %v\n", err)
return
}
// todo unmarshal mx lookup
fmt.Println("MX Lookup Result:")
fmt.Println(result)
// Get credits
credits, err := whois.GetWHOISCredits(key)
if err != nil {
zap.L().Error("get_whois_credits",
zap.String("message", "failed to get whois credits"),
zap.Error(err),
)
fmt.Printf("Error getting WHOIS credits: %v\n", err)
return
}
fmt.Printf("\nWHOIS Credits Remaining: %d\n", credits.WhoisCredits)
return
}
if whoisNSAddress != "" {
fmt.Println("[*] Performing reverse NS lookup...")
// NS lookup
result, err := whois.WhoisNS(whoisNSAddress, key)
if err != nil {
zap.L().Error("whois_ns",
zap.String("message", "failed to perform ns lookup"),
zap.Error(err),
)
fmt.Printf("Error performing NS lookup: %v\n", err)
return
}
fmt.Println("NS Lookup Result:")
fmt.Println(result)
// Get credits
credits, err := whois.GetWHOISCredits(key)
if err != nil {
zap.L().Error("get_whois_credits",
zap.String("message", "failed to get whois credits"),
zap.Error(err),
)
fmt.Printf("Error getting WHOIS credits: %v\n", err)
return
}
fmt.Printf("\nWHOIS Credits Remaining: %d\n", credits.WhoisCredits)
return
}
if whoisInclude != "" || whoisExclude != "" {
// Reverse WHOIS
includeTerms := []string{}
if whoisInclude != "" {
includeTerms = strings.Split(whoisInclude, ",")
}
excludeTerms := []string{}
if whoisExclude != "" {
excludeTerms = strings.Split(whoisExclude, ",")
}
if whoisReverseType == "" {
whoisReverseType = "registrant"
}
fmt.Println("[*] Performing reverse WHOIS lookup...")
result, err := whois.ReverseWHOIS(includeTerms, excludeTerms, whoisReverseType, key)
if err != nil {
fmt.Printf("Error performing reverse WHOIS: %v\n", err)
return
}
fmt.Println("Reverse WHOIS Result:")
fmt.Println(result)
return
}
// If no specific operation was requested
cmd.Help()
},
}
)
func init() {
// Add whois command to root command
rootCmd.AddCommand(whoisCmd)
// Add flags specific to whois command
whoisCmd.Flags().StringVarP(&whoisDomain, "domain", "d", "", "Domain for WHOIS lookup, history search, and subdomain scan")
whoisCmd.Flags().StringVarP(&whoisIPAddress, "ip", "i", "", "IP address for reverse IP lookup")
whoisCmd.Flags().StringVarP(&whoisMXAddress, "mx", "m", "", "MX address for reverse MX lookup")
whoisCmd.Flags().StringVarP(&whoisNSAddress, "ns", "n", "", "NS address for reverse NS lookup")
whoisCmd.Flags().StringVarP(&whoisInclude, "include", "I", "", "Terms to include in reverse WHOIS search (comma-separated)")
whoisCmd.Flags().StringVarP(&whoisExclude, "exclude", "E", "", "Terms to exclude in reverse WHOIS search (comma-separated)")
whoisCmd.Flags().StringVarP(&whoisReverseType, "type", "t", "registrant", "Type of reverse WHOIS search (registrant, email, organization, address, phone)")
whoisCmd.Flags().StringVarP(&whoisOutputFormat, "format", "f", "text", "Output format (text, json)")
whoisCmd.Flags().BoolVarP(&whoisShowCredits, "credits", "c", false, "Show remaining WHOIS credits")
whoisCmd.Flags().BoolVarP(&whoisHistory, "history", "H", false, "Perform WHOIS history search [25 Credits]")
whoisCmd.Flags().BoolVarP(&whoisSubdomainScan, "subdomains", "s", false, "Perform WHOIS subdomain scan")
// Add API key flag
whoisCmd.Flags().StringVarP(&apiKey, "key", "k", "", "Dehashed API key")
}
+235
View File
@@ -0,0 +1,235 @@
[*] Performing WHOIS lookup...
WHOIS Lookup Result: %v
{{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} {2025-03-10 15:29:09 UTC 2025-03-10 15:29:09 UTC} abuse@godaddy.com 2001-09-23T21:20:52Z 2001-09-23 21:20:52 UTC counseltrust.com .com 8633 2025-09-23T21:20:52Z 2025-09-23 21:20:52 UTC {[NS51.DOMAINCONTROL.COM NS52.DOMAINCONTROL.COM] [] NS51.DOMAINCONTROL.COM
NS52.DOMAINCONTROL.COM
} 3259 Domain Name: counseltrust.com
Registry Domain ID: 77675771_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.godaddy.com
Registrar URL: https://www.godaddy.com
Updated Date: 2024-09-24T12:17:56Z
Creation Date: 2001-09-23T21:20:52Z
Registrar Registration Expiration Date: 2025-09-23T21:20:52Z
Registrar: GoDaddy.com, LLC
Registrar IANA ID: 146
Registrar Abuse Contact Email: abuse@godaddy.com
Registrar Abuse Contact Phone: +1.4806242505
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited
Registry Registrant ID: Not Available From Registry
Registrant Name: Registration Private
Registrant Organization: Domains By Proxy, LLC
Registrant Street: DomainsByProxy.com
Registrant Street: 100 S. Mill Ave, Suite 1600
Registrant City: Tempe
Registrant State/Province: Arizona
Registrant Postal Code: 85281
Registrant Country: US
Registrant Phone: +1.4806242599
Registrant Phone Ext:
Registrant Fax:
Registrant Fax Ext:
Registrant Email: Select Contact Domain Holder link at https://www.godaddy.com/whois/results.aspx?domain=counseltrust.com
Registry Tech ID: Not Available From Registry
Tech Name: Registration Private
Tech Organization: Domains By Proxy, LLC
Tech Street: DomainsByProxy.com
Tech Street: 100 S. Mill Ave, Suite 1600
Tech City: Tempe
Tech State/Province: Arizona
Tech Postal Code: 85281
Tech Country: US
Tech Phone: +1.4806242599
Tech Phone Ext:
Tech Fax:
Tech Fax Ext:
Tech Email: Select Contact Domain Holder link at https://www.godaddy.com/whois/results.aspx?domain=counseltrust.com
Name Server: NS51.DOMAINCONTROL.COM
Name Server: NS52.DOMAINCONTROL.COM
DNSSEC: unsigned
URL of the ICANN WHOIS Data Problem Reporting System: http://wdprs.internic.net/
>>> Last update of WHOIS database: 2025-03-10T15:29:08Z <<<
For more information on Whois status codes, please visit https://icann.org/epp
TERMS OF USE: The data contained in this registrar's Whois database, while believed by the
registrar to be reliable, is provided "as is" with no guarantee or warranties regarding its
accuracy. This information is provided for the sole purpose of assisting you in obtaining
information about domain name registration records. Any use of this data for any other purpose
is expressly forbidden without the prior written permission of this registrar. By submitting
an inquiry, you agree to these terms and limitations of warranty. In particular, you agree not
to use this data to allow, enable, or otherwise support the dissemination or collection of this
data, in part or in its entirety, for any purpose, such as transmission by e-mail, telephone,
postal mail, facsimile or other means of mass unsolicited, commercial advertising or solicitations
of any kind, including spam. You further agree not to use this data to enable high volume, automated
or robotic electronic processes designed to collect or compile this data for any purpose, including
mining this data for your own personal or commercial purposes. Failure to comply with these terms
may result in termination of access to the Whois database. These terms may be subject to modification
at any time without notice.
**NOTICE** This WHOIS server is being retired. Please use our RDAP service instead. {Tempe UNITED STATES US Registration Private Domains By Proxy, LLC 85281 Registrant Name: Registration Private
Registrant Organization: Domains By Proxy, LLC
Registrant Street: DomainsByProxy.com
Registrant Street: 100 S. Mill Ave, Suite 1600
Registrant City: Tempe
Registrant State/Province: Arizona
Registrant Postal Code: 85281
Registrant Country: US
Registrant Phone: +1.4806242599
Registrant Email: Select Contact Domain Holder link at https://www.godaddy.com/whois/results.aspx?domain=counseltrust.com Arizona DomainsByProxy.com
100 S. Mill Ave, Suite 1600 14806242599} 146 GoDaddy.com, LLC {{2025-03-10 15:29:04 UTC 2025-03-10 15:29:04 UTC} 2001-09-24T02:20:52Z 2001-09-24 02:20:52 UTC counseltrust.com 2025-09-24T02:20:52Z 2025-09-24 02:20:52 UTC {[NS51.DOMAINCONTROL.COM NS52.DOMAINCONTROL.COM] [] NS51.DOMAINCONTROL.COM
NS52.DOMAINCONTROL.COM
} 251 Domain Name: COUNSELTRUST.COM
Registry Domain ID: 77675771_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.godaddy.com
Registrar URL: http://www.godaddy.com
Updated Date: 2024-09-24T17:17:57Z
Creation Date: 2001-09-24T02:20:52Z
Registry Expiry Date: 2025-09-24T02:20:52Z
Registrar: GoDaddy.com, LLC
Registrar IANA ID: 146
Registrar Abuse Contact Email: abuse@godaddy.com
Registrar Abuse Contact Phone: 480-624-2505
Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited
Name Server: NS51.DOMAINCONTROL.COM
Name Server: NS52.DOMAINCONTROL.COM
DNSSEC: unsigned
URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
>>> Last update of whois database: 2025-03-10T15:28:57Z <<<
For more information on Whois status codes, please visit https://icann.org/epp
NOTICE: The expiration date displayed in this record is the date the
registrar's sponsorship of the domain name registration in the registry is
currently set to expire. This date does not necessarily reflect the expiration
date of the domain name registrant's agreement with the sponsoring
registrar. Users may consult the sponsoring registrar's Whois database to
view the registrar's reported date of expiration for this registration.
TERMS OF USE: You are not authorized to access or query our Whois
database through the use of electronic processes that are high-volume and
automated except as reasonably necessary to register domain names or
modify existing registrations; the Data in VeriSign Global Registry
Services' ("VeriSign") Whois database is provided by VeriSign for
information purposes only, and to assist persons in obtaining information
about or related to a domain name registration record. VeriSign does not
guarantee its accuracy. By submitting a Whois query, you agree to abide
by the following terms of use: You agree that you may use this Data only
for lawful purposes and that under no circumstances will you use this Data
to: (1) allow, enable, or otherwise support the transmission of mass
unsolicited, commercial advertising or solicitations via e-mail, telephone,
or facsimile; or (2) enable high volume, automated, electronic processes
that apply to VeriSign (or its computer systems). The compilation,
repackaging, dissemination or other use of this Data is expressly
prohibited without the prior written consent of VeriSign. You agree not to
use electronic processes that are automated and high-volume to access or
query the Whois database except as reasonably necessary to register
domain names or modify existing registrations. VeriSign reserves the right
to restrict your access to the Whois database in its sole discretion to ensure
operational stability. VeriSign may restrict or terminate your access to the
Whois database for failure to abide by these terms of use. VeriSign
reserves the right to modify these terms at any time.
The Registry database contains ONLY .COM, .NET, .EDU domains and
Registrars. 146 GoDaddy.com, LLC clientDeleteProhibited clientRenewProhibited clientTransferProhibited clientUpdateProhibited Domain Name: COUNSELTRUST.COM
Registry Domain ID: 77675771_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.godaddy.com
Registrar URL: http://www.godaddy.com
Updated Date: 2024-09-24T17:17:57Z
Creation Date: 2001-09-24T02:20:52Z
Registry Expiry Date: 2025-09-24T02:20:52Z
Registrar: GoDaddy.com, LLC
Registrar IANA ID: 146
Registrar Abuse Contact Email: abuse@godaddy.com
Registrar Abuse Contact Phone: 480-624-2505
Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited
Name Server: NS51.DOMAINCONTROL.COM
Name Server: NS52.DOMAINCONTROL.COM
DNSSEC: unsigned
URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
>>> Last update of whois database: 2025-03-10T15:28:57Z <<<
For more information on Whois status codes, please visit https://icann.org/epp
NOTICE: The expiration date displayed in this record is the date the
registrar's sponsorship of the domain name registration in the registry is
currently set to expire. This date does not necessarily reflect the expiration
date of the domain name registrant's agreement with the sponsoring
registrar. Users may consult the sponsoring registrar's Whois database to
view the registrar's reported date of expiration for this registration.
TERMS OF USE: You are not authorized to access or query our Whois
database through the use of electronic processes that are high-volume and
automated except as reasonably necessary to register domain names or
modify existing registrations; the Data in VeriSign Global Registry
Services' ("VeriSign") Whois database is provided by VeriSign for
information purposes only, and to assist persons in obtaining information
about or related to a domain name registration record. VeriSign does not
guarantee its accuracy. By submitting a Whois query, you agree to abide
by the following terms of use: You agree that you may use this Data only
for lawful purposes and that under no circumstances will you use this Data
to: (1) allow, enable, or otherwise support the transmission of mass
unsolicited, commercial advertising or solicitations via e-mail, telephone,
or facsimile; or (2) enable high volume, automated, electronic processes
that apply to VeriSign (or its computer systems). The compilation,
repackaging, dissemination or other use of this Data is expressly
prohibited without the prior written consent of VeriSign. You agree not to
use electronic processes that are automated and high-volume to access or
query the Whois database except as reasonably necessary to register
domain names or modify existing registrations. VeriSign reserves the right
to restrict your access to the Whois database in its sole discretion to ensure
operational stability. VeriSign may restrict or terminate your access to the
Whois database for failure to abide by these terms of use. VeriSign
reserves the right to modify these terms at any time.
The Registry database contains ONLY .COM, .NET, .EDU domains and
Registrars.
2024-09-24T17:17:57Z 2024-09-24 17:17:57 UTC whois.godaddy.com} clientTransferProhibited clientUpdateProhibited clientRenewProhibited clientDeleteProhibited Domain Name: counseltrust.com
Registrar WHOIS Server: whois.godaddy.com
Registrar URL: https://www.godaddy.com
Updated Date: 2024-09-24T12:17:56Z
Creation Date: 2001-09-23T21:20:52Z
Registrar Registration Expiration Date: 2025-09-23T21:20:52Z
Registrar: GoDaddy.com, LLC
Registrar IANA ID: 146
Registrar Abuse Contact Email: abuse@godaddy.com
Registrar Abuse Contact Phone: +1.4806242505
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited
Registrant Name: Registration Private
Registrant Organization: Domains By Proxy, LLC
Registrant Street: DomainsByProxy.com
Registrant Street: 100 S. Mill Ave, Suite 1600
Registrant City: Tempe
Registrant State/Province: Arizona
Registrant Postal Code: 85281
Registrant Country: US
Registrant Phone: +1.4806242599
Registrant Email: Select Contact Domain Holder link at https://www.godaddy.com/whois/results.aspx?domain=counseltrust.com
Tech Name: Registration Private
Tech Organization: Domains By Proxy, LLC
Tech Street: DomainsByProxy.com
Tech Street: 100 S. Mill Ave, Suite 1600
Tech City: Tempe
Tech State/Province: Arizona
Tech Postal Code: 85281
Tech Country: US
Tech Phone: +1.4806242599
Tech Email: Select Contact Domain Holder link at https://www.godaddy.com/whois/results.aspx?domain=counseltrust.com
Name Server: NS51.DOMAINCONTROL.COM
Name Server: NS52.DOMAINCONTROL.COM
{Tempe UNITED STATES US Registration Private Domains By Proxy, LLC 85281 Tech Name: Registration Private
Tech Organization: Domains By Proxy, LLC
Tech Street: DomainsByProxy.com
Tech Street: 100 S. Mill Ave, Suite 1600
Tech City: Tempe
Tech State/Province: Arizona
Tech Postal Code: 85281
Tech Country: US
Tech Phone: +1.4806242599
Tech Email: Select Contact Domain Holder link at https://www.godaddy.com/whois/results.aspx?domain=counseltrust.com Arizona DomainsByProxy.com
100 S. Mill Ave, Suite 1600 14806242599} 2024-09-24T12:17:56Z 2024-09-24 12:17:56 UTC}
+241
View File
@@ -0,0 +1,241 @@
[*] Performing WHOIS lookup...
WHOIS Lookup Result:
{Model:{ID:0 CreatedAt:0001-01-01 00:00:00 +0000 UTC UpdatedAt:0001-01-01 00:00:00 +0000 UTC DeletedAt:{Time:0001-01-01 00:00:00 +0000 UTC Valid:false}} Audit:{CreatedDate:2025-03-10 15:29:09 UTC UpdatedDate:2025-03-10 15:29:09 UTC} ContactEmail:abuse@godaddy.com CreatedDate:2001-09-23T21:20:52Z CreatedDateNormalized:2001-09-23 21:20:52 UTC DomainName:counseltrust.com DomainNameExt:.com EstimatedDomainAge:8633 ExpiresDate:2025-09-23T21:20:52Z ExpiresDateNormalized:2025-09-23 21:20:52 UTC Footer: Header: NameServers:{HostNames:[NS51.DOMAINCONTROL.COM NS52.DOMAINCONTROL.COM] IPs:[] RawText:NS51.DOMAINCONTROL.COM
NS52.DOMAINCONTROL.COM
} ParseCode:3259 RawText:Domain Name: counseltrust.com
Registry Domain ID: 77675771_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.godaddy.com
Registrar URL: https://www.godaddy.com
Updated Date: 2024-09-24T12:17:56Z
Creation Date: 2001-09-23T21:20:52Z
Registrar Registration Expiration Date: 2025-09-23T21:20:52Z
Registrar: GoDaddy.com, LLC
Registrar IANA ID: 146
Registrar Abuse Contact Email: abuse@godaddy.com
Registrar Abuse Contact Phone: +1.4806242505
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited
Registry Registrant ID: Not Available From Registry
Registrant Name: Registration Private
Registrant Organization: Domains By Proxy, LLC
Registrant Street: DomainsByProxy.com
Registrant Street: 100 S. Mill Ave, Suite 1600
Registrant City: Tempe
Registrant State/Province: Arizona
Registrant Postal Code: 85281
Registrant Country: US
Registrant Phone: +1.4806242599
Registrant Phone Ext:
Registrant Fax:
Registrant Fax Ext:
Registrant Email: Select Contact Domain Holder link at https://www.godaddy.com/whois/results.aspx?domain=counseltrust.com
Registry Tech ID: Not Available From Registry
Tech Name: Registration Private
Tech Organization: Domains By Proxy, LLC
Tech Street: DomainsByProxy.com
Tech Street: 100 S. Mill Ave, Suite 1600
Tech City: Tempe
Tech State/Province: Arizona
Tech Postal Code: 85281
Tech Country: US
Tech Phone: +1.4806242599
Tech Phone Ext:
Tech Fax:
Tech Fax Ext:
Tech Email: Select Contact Domain Holder link at https://www.godaddy.com/whois/results.aspx?domain=counseltrust.com
Name Server: NS51.DOMAINCONTROL.COM
Name Server: NS52.DOMAINCONTROL.COM
DNSSEC: unsigned
URL of the ICANN WHOIS Data Problem Reporting System: http://wdprs.internic.net/
>>> Last update of WHOIS database: 2025-03-10T15:29:08Z <<<
For more information on Whois status codes, please visit https://icann.org/epp
TERMS OF USE: The data contained in this registrar's Whois database, while believed by the
registrar to be reliable, is provided "as is" with no guarantee or warranties regarding its
accuracy. This information is provided for the sole purpose of assisting you in obtaining
information about domain name registration records. Any use of this data for any other purpose
is expressly forbidden without the prior written permission of this registrar. By submitting
an inquiry, you agree to these terms and limitations of warranty. In particular, you agree not
to use this data to allow, enable, or otherwise support the dissemination or collection of this
data, in part or in its entirety, for any purpose, such as transmission by e-mail, telephone,
postal mail, facsimile or other means of mass unsolicited, commercial advertising or solicitations
of any kind, including spam. You further agree not to use this data to enable high volume, automated
or robotic electronic processes designed to collect or compile this data for any purpose, including
mining this data for your own personal or commercial purposes. Failure to comply with these terms
may result in termination of access to the Whois database. These terms may be subject to modification
at any time without notice.
**NOTICE** This WHOIS server is being retired. Please use our RDAP service instead. Registrant:{City:Tempe Country:UNITED STATES CountryCode:US Name:Registration Private Organization:Domains By Proxy, LLC PostalCode:85281 RawText:Registrant Name: Registration Private
Registrant Organization: Domains By Proxy, LLC
Registrant Street: DomainsByProxy.com
Registrant Street: 100 S. Mill Ave, Suite 1600
Registrant City: Tempe
Registrant State/Province: Arizona
Registrant Postal Code: 85281
Registrant Country: US
Registrant Phone: +1.4806242599
Registrant Email: Select Contact Domain Holder link at https://www.godaddy.com/whois/results.aspx?domain=counseltrust.com State:Arizona Street1:DomainsByProxy.com
100 S. Mill Ave, Suite 1600 Telephone:14806242599} RegistrarIANAID:146 RegistrarName:GoDaddy.com, LLC RegistryData:{Audit:{CreatedDate:2025-03-10 15:29:04 UTC UpdatedDate:2025-03-10 15:29:04 UTC} CreatedDate:2001-09-24T02:20:52Z CreatedDateNormalized:2001-09-24 02:20:52 UTC DomainName:counseltrust.com ExpiresDate:2025-09-24T02:20:52Z ExpiresDateNormalized:2025-09-24 02:20:52 UTC Footer: Header: NameServers:{HostNames:[NS51.DOMAINCONTROL.COM NS52.DOMAINCONTROL.COM] IPs:[] RawText:NS51.DOMAINCONTROL.COM
NS52.DOMAINCONTROL.COM
} ParseCode:251 RawText:Domain Name: COUNSELTRUST.COM
Registry Domain ID: 77675771_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.godaddy.com
Registrar URL: http://www.godaddy.com
Updated Date: 2024-09-24T17:17:57Z
Creation Date: 2001-09-24T02:20:52Z
Registry Expiry Date: 2025-09-24T02:20:52Z
Registrar: GoDaddy.com, LLC
Registrar IANA ID: 146
Registrar Abuse Contact Email: abuse@godaddy.com
Registrar Abuse Contact Phone: 480-624-2505
Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited
Name Server: NS51.DOMAINCONTROL.COM
Name Server: NS52.DOMAINCONTROL.COM
DNSSEC: unsigned
URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
>>> Last update of whois database: 2025-03-10T15:28:57Z <<<
For more information on Whois status codes, please visit https://icann.org/epp
NOTICE: The expiration date displayed in this record is the date the
registrar's sponsorship of the domain name registration in the registry is
currently set to expire. This date does not necessarily reflect the expiration
date of the domain name registrant's agreement with the sponsoring
registrar. Users may consult the sponsoring registrar's Whois database to
view the registrar's reported date of expiration for this registration.
TERMS OF USE: You are not authorized to access or query our Whois
database through the use of electronic processes that are high-volume and
automated except as reasonably necessary to register domain names or
modify existing registrations; the Data in VeriSign Global Registry
Services' ("VeriSign") Whois database is provided by VeriSign for
information purposes only, and to assist persons in obtaining information
about or related to a domain name registration record. VeriSign does not
guarantee its accuracy. By submitting a Whois query, you agree to abide
by the following terms of use: You agree that you may use this Data only
for lawful purposes and that under no circumstances will you use this Data
to: (1) allow, enable, or otherwise support the transmission of mass
unsolicited, commercial advertising or solicitations via e-mail, telephone,
or facsimile; or (2) enable high volume, automated, electronic processes
that apply to VeriSign (or its computer systems). The compilation,
repackaging, dissemination or other use of this Data is expressly
prohibited without the prior written consent of VeriSign. You agree not to
use electronic processes that are automated and high-volume to access or
query the Whois database except as reasonably necessary to register
domain names or modify existing registrations. VeriSign reserves the right
to restrict your access to the Whois database in its sole discretion to ensure
operational stability. VeriSign may restrict or terminate your access to the
Whois database for failure to abide by these terms of use. VeriSign
reserves the right to modify these terms at any time.
The Registry database contains ONLY .COM, .NET, .EDU domains and
Registrars. RegistrarIANAID:146 RegistrarName:GoDaddy.com, LLC Status:clientDeleteProhibited clientRenewProhibited clientTransferProhibited clientUpdateProhibited StrippedText:Domain Name: COUNSELTRUST.COM
Registry Domain ID: 77675771_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.godaddy.com
Registrar URL: http://www.godaddy.com
Updated Date: 2024-09-24T17:17:57Z
Creation Date: 2001-09-24T02:20:52Z
Registry Expiry Date: 2025-09-24T02:20:52Z
Registrar: GoDaddy.com, LLC
Registrar IANA ID: 146
Registrar Abuse Contact Email: abuse@godaddy.com
Registrar Abuse Contact Phone: 480-624-2505
Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited
Name Server: NS51.DOMAINCONTROL.COM
Name Server: NS52.DOMAINCONTROL.COM
DNSSEC: unsigned
URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
>>> Last update of whois database: 2025-03-10T15:28:57Z <<<
For more information on Whois status codes, please visit https://icann.org/epp
NOTICE: The expiration date displayed in this record is the date the
registrar's sponsorship of the domain name registration in the registry is
currently set to expire. This date does not necessarily reflect the expiration
date of the domain name registrant's agreement with the sponsoring
registrar. Users may consult the sponsoring registrar's Whois database to
view the registrar's reported date of expiration for this registration.
TERMS OF USE: You are not authorized to access or query our Whois
database through the use of electronic processes that are high-volume and
automated except as reasonably necessary to register domain names or
modify existing registrations; the Data in VeriSign Global Registry
Services' ("VeriSign") Whois database is provided by VeriSign for
information purposes only, and to assist persons in obtaining information
about or related to a domain name registration record. VeriSign does not
guarantee its accuracy. By submitting a Whois query, you agree to abide
by the following terms of use: You agree that you may use this Data only
for lawful purposes and that under no circumstances will you use this Data
to: (1) allow, enable, or otherwise support the transmission of mass
unsolicited, commercial advertising or solicitations via e-mail, telephone,
or facsimile; or (2) enable high volume, automated, electronic processes
that apply to VeriSign (or its computer systems). The compilation,
repackaging, dissemination or other use of this Data is expressly
prohibited without the prior written consent of VeriSign. You agree not to
use electronic processes that are automated and high-volume to access or
query the Whois database except as reasonably necessary to register
domain names or modify existing registrations. VeriSign reserves the right
to restrict your access to the Whois database in its sole discretion to ensure
operational stability. VeriSign may restrict or terminate your access to the
Whois database for failure to abide by these terms of use. VeriSign
reserves the right to modify these terms at any time.
The Registry database contains ONLY .COM, .NET, .EDU domains and
Registrars.
UpdatedDate:2024-09-24T17:17:57Z UpdatedDateNormalized:2024-09-24 17:17:57 UTC WhoisServer:whois.godaddy.com} Status:clientTransferProhibited clientUpdateProhibited clientRenewProhibited clientDeleteProhibited StrippedText:Domain Name: counseltrust.com
Registrar WHOIS Server: whois.godaddy.com
Registrar URL: https://www.godaddy.com
Updated Date: 2024-09-24T12:17:56Z
Creation Date: 2001-09-23T21:20:52Z
Registrar Registration Expiration Date: 2025-09-23T21:20:52Z
Registrar: GoDaddy.com, LLC
Registrar IANA ID: 146
Registrar Abuse Contact Email: abuse@godaddy.com
Registrar Abuse Contact Phone: +1.4806242505
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited
Registrant Name: Registration Private
Registrant Organization: Domains By Proxy, LLC
Registrant Street: DomainsByProxy.com
Registrant Street: 100 S. Mill Ave, Suite 1600
Registrant City: Tempe
Registrant State/Province: Arizona
Registrant Postal Code: 85281
Registrant Country: US
Registrant Phone: +1.4806242599
Registrant Email: Select Contact Domain Holder link at https://www.godaddy.com/whois/results.aspx?domain=counseltrust.com
Tech Name: Registration Private
Tech Organization: Domains By Proxy, LLC
Tech Street: DomainsByProxy.com
Tech Street: 100 S. Mill Ave, Suite 1600
Tech City: Tempe
Tech State/Province: Arizona
Tech Postal Code: 85281
Tech Country: US
Tech Phone: +1.4806242599
Tech Email: Select Contact Domain Holder link at https://www.godaddy.com/whois/results.aspx?domain=counseltrust.com
Name Server: NS51.DOMAINCONTROL.COM
Name Server: NS52.DOMAINCONTROL.COM
TechnicalContact:{City:Tempe Country:UNITED STATES CountryCode:US Name:Registration Private Organization:Domains By Proxy, LLC PostalCode:85281 RawText:Tech Name: Registration Private
Tech Organization: Domains By Proxy, LLC
Tech Street: DomainsByProxy.com
Tech Street: 100 S. Mill Ave, Suite 1600
Tech City: Tempe
Tech State/Province: Arizona
Tech Postal Code: 85281
Tech Country: US
Tech Phone: +1.4806242599
Tech Email: Select Contact Domain Holder link at https://www.godaddy.com/whois/results.aspx?domain=counseltrust.com State:Arizona Street1:DomainsByProxy.com
100 S. Mill Ave, Suite 1600 Telephone:14806242599} UpdatedDate:2024-09-24T12:17:56Z UpdatedDateNormalized:2024-09-24 12:17:56 UTC}
[*] Performing WHOIS subdomain scan...
Subdomain Scan:
{220 {{13 [{{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} cpanel.counseltrust.com 1621908519 1621908519} {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} cpcalendars.counseltrust.com 1621908519 1621908519} {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} sslvpn.counseltrust.com 1546654106 1546654106} {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} stocks.counseltrust.com 1546654702 1546654702} {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} cpcontacts.counseltrust.com 1621908519 1621908519} {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} ftp.counseltrust.com 1737657659 1737657659} {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} mail.counseltrust.com 1621908519 1621908519} {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} webmail.counseltrust.com 1621908519 1621908519} {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} webdisk.counseltrust.com 1621908519 1621908519} {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} autodiscover.counseltrust.com 1743219849 1745735288} {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} www.laserfiche.counseltrust.com 1649336639 1712556962} {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} laserfiche.counseltrust.com 1565348884 1712556962} {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} www.counseltrust.com 1517184000 1745798400}]} counseltrust.com}}
WHOIS Credits Remaining: 220
Executable
BIN
View File
Binary file not shown.
+94
View File
@@ -0,0 +1,94 @@
package main
import (
"dehasher/cmd"
"dehasher/internal/badger"
"dehasher/internal/sqlite"
"fmt"
"github.com/winking324/rzap"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
"os"
"path/filepath"
)
var (
basePath string
logPath string
storePath string
dbPath string
)
func init() {
basePath = filepath.Join(os.Getenv("HOME"), ".local", "share", "Dehasher")
logPath = filepath.Join(basePath, "logs")
storePath = filepath.Join(basePath, "keystore")
dbPath = filepath.Join(basePath, "db")
}
func createDirectories() {
var err error
if _, err = os.Stat(basePath); os.IsNotExist(err) {
err = os.MkdirAll(basePath, 0755)
if err != nil {
zap.L().Error("Error creating directory", zap.Error(err))
fmt.Printf("[!] Error creating base directory: %v", err)
os.Exit(-1)
}
}
for _, dir := range []string{"logs", "keystore", "db"} {
if _, err := os.Stat(filepath.Join(basePath, dir)); os.IsNotExist(err) {
err = os.MkdirAll(filepath.Join(basePath, dir), 0755)
if err != nil {
zap.L().Error("Error creating directory", zap.Error(err), zap.String("directory", dir))
fmt.Printf("[!] Error creating directory: %v", err)
os.Exit(-1)
}
}
}
}
func initializeLogger() {
rzap.NewGlobalLogger([]zapcore.Core{
rzap.NewCore(&lumberjack.Logger{
Filename: filepath.Join(logPath, "info.log"),
}, zap.LevelEnablerFunc(func(level zapcore.Level) bool {
return level <= zap.InfoLevel
})),
rzap.NewCore(&lumberjack.Logger{
Filename: filepath.Join(logPath, "error.log"),
}, zap.LevelEnablerFunc(func(level zapcore.Level) bool {
return level > zap.InfoLevel
})),
})
zap.L().Info("some message", zap.Int("status", 0))
}
func main() {
initializeLogger()
zap.L().Info("creating_directories")
createDirectories()
zap.L().Info("initializing_database")
_, err := sqlite.InitDB(dbPath)
if err != nil {
zap.L().Error("init_db",
zap.String("message", "failed to initialize database"),
zap.Error(err),
)
fmt.Printf("[!] Error initializing database: %v", err)
os.Exit(1)
}
zap.L().Info("starting_badger")
db := badger.Start(storePath)
defer db.Close()
zap.L().Info("executing_command")
cmd.Execute()
}
+54
View File
@@ -0,0 +1,54 @@
module dehasher
go 1.23.0
toolchain go1.24.3
require (
github.com/charmbracelet/lipgloss v1.1.0
github.com/dgraph-io/badger/v4 v4.7.0
github.com/spf13/cobra v1.9.1
github.com/winking324/rzap v0.1.0
go.uber.org/zap v1.20.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/sqlite v1.5.7
gorm.io/gorm v1.26.1
)
require (
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
github.com/charmbracelet/x/ansi v0.8.0 // indirect
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect
github.com/dgraph-io/ristretto/v2 v2.2.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/flatbuffers v25.2.10+incompatible // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/spf13/pflag v1.0.6 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.35.0 // indirect
go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.23.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
)
+160
View File
@@ -0,0 +1,160 @@
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30=
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgraph-io/badger/v4 v4.7.0 h1:Q+J8HApYAY7UMpL8d9owqiB+odzEc0zn/aqOD9jhc6Y=
github.com/dgraph-io/badger/v4 v4.7.0/go.mod h1:He7TzG3YBy3j4f5baj5B7Zl2XyfNe5bl4Udl0aPemVA=
github.com/dgraph-io/ristretto/v2 v2.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM=
github.com/dgraph-io/ristretto/v2 v2.2.0/go.mod h1:RZrm63UmcBAaYWC1DotLYBmTvgkrs0+XhBd7Npn7/zI=
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38=
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q=
github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/winking324/rzap v0.1.0 h1:otHb5JwO2l9Alr1MPeww8FAzF+YcmiZMR0EvBZnmlqo=
github.com/winking324/rzap v0.1.0/go.mod h1:C7Ui70QKYWiN5h4Qk2U0qaTN5yC3ujpKsRgHcXsFWhI=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.20.0 h1:N4oPlghZwYG55MlU6LXk/Zp00FVNE9X9wrYO8CEs4lc=
go.uber.org/zap v1.20.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I=
gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
gorm.io/gorm v1.26.1 h1:ghB2gUI9FkS46luZtn6DLZ0f6ooBJ5IbVej2ENFDjRw=
gorm.io/gorm v1.26.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
+174
View File
@@ -0,0 +1,174 @@
package badger
import (
"crypto/sha256"
"github.com/dgraph-io/badger/v4"
"go.uber.org/zap"
"log"
"os"
"os/user"
"path/filepath"
"runtime"
"strings"
"sync"
)
var (
encryptionKey []byte // must be 32 bytes
db *badger.DB
rootDir string
once sync.Once
)
func GetHardwareEntropy() []byte {
// Get hostname
hostname, err := os.Hostname()
if err != nil {
hostname = "unknown-host"
log.Printf("Error getting hostname: %v", err)
}
// Get username
currentUser, err := user.Current()
username := "unknown-user"
if err == nil && currentUser != nil {
username = currentUser.Username
}
// Get OS and architecture info
osInfo := runtime.GOOS + "-" + runtime.GOARCH
// Combine all information for a unique but consistent fingerprint
fingerprint := strings.Join([]string{
hostname,
username,
osInfo,
// You could add a static salt here for additional security
"Dehasher-static-salt-value",
}, ":")
// Hash the fingerprint to get a 32-byte key
sum := sha256.Sum256([]byte(fingerprint))
return sum[:]
}
func Start(dirPath string) *badger.DB {
var err error
zap.L().Info("Starting Badger DB", zap.String("directory", dirPath))
zap.L().Info("Badger DB Directory Path", zap.String("directory", dirPath))
once.Do(func() {
if !strings.HasSuffix(dirPath, "db") {
dirPath = filepath.Join(dirPath, "db")
}
rootDir = dirPath
encryptionKey = GetHardwareEntropy()
if err != nil {
zap.L().Fatal("get_encryption_key",
zap.String("message", "failed to get encryption key"),
zap.Error(err),
)
}
badgerDB := filepath.Join(rootDir, "badger.db")
opts := badger.DefaultOptions(badgerDB).
WithEncryptionKey(encryptionKey).
WithIndexCacheSize(10 << 20). // 10MB
WithLoggingLevel(badger.ERROR)
db, err = badger.Open(opts)
if err != nil {
zap.L().Fatal("new_badger_db",
zap.String("message", "failed to open badger database"),
zap.Error(err),
)
}
})
return db
}
func Close() {
err := db.Close()
if err != nil {
zap.L().Fatal("new_badger_db",
zap.String("message", "failed to close badger database"),
zap.Error(err),
)
}
}
func GetKey() string {
var apiKey string
err := db.View(func(txn *badger.Txn) error {
item, err := txn.Get([]byte("cfg:api_key"))
if err != nil {
return err // could be ErrKeyNotFound
}
return item.Value(func(val []byte) error {
apiKey = string(val)
return nil
})
})
if err != nil {
zap.L().Error("get_api_key",
zap.String("message", "failed to get api_key"),
zap.Error(err),
)
}
return apiKey
}
func GetEmail() string {
var email string
err := db.View(func(txn *badger.Txn) error {
item, err := txn.Get([]byte("cfg:email"))
if err != nil {
return err // could be ErrKeyNotFound
}
return item.Value(func(val []byte) error {
email = string(val)
return nil
})
})
if err != nil {
zap.L().Error("get_email",
zap.String("message", "failed to get email"),
zap.Error(err),
)
}
return email
}
func StoreKey(apiKey string) error {
err := db.Update(func(txn *badger.Txn) error {
return txn.Set([]byte("cfg:api_key"), []byte(apiKey))
})
if err != nil {
zap.L().Error("set_api_key",
zap.String("message", "failed to set api_key"),
zap.Error(err),
)
}
return err
}
func StoreEmail(email string) error {
err := db.Update(func(txn *badger.Txn) error {
return txn.Set([]byte("cfg:email"), []byte(email))
})
if err != nil {
zap.L().Error("set_email",
zap.String("message", "failed to set email"),
zap.Error(err),
)
}
return err
}
+77
View File
@@ -0,0 +1,77 @@
package export
import (
"dehasher/internal/files"
"dehasher/internal/sqlite"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
"gopkg.in/yaml.v3"
"io/ioutil"
"os"
"strings"
)
func WriteCredsToFile(creds []sqlite.Creds, outputFile string, fileType files.FileType) error {
var data []byte
var err error
switch fileType {
case files.JSON:
data, err = json.MarshalIndent(creds, "", " ")
case files.XML:
data, err = xml.MarshalIndent(creds, "", " ")
case files.YAML:
data, err = yaml.Marshal(creds)
case files.TEXT:
var outStrings []string
for _, c := range creds {
outStrings = append(outStrings, c.ToString()+"\n")
}
data = []byte(strings.Join(outStrings, ""))
default:
return errors.New("unsupported file type")
}
if err != nil {
return err
}
filePath := fmt.Sprintf("%s.%s", outputFile, fileType.String())
return os.WriteFile(filePath, data, 0644)
}
func WriteToFile(results sqlite.DehashedResults, outputFile string, fileType files.FileType) error {
var data []byte
var err error
result := results.Results
switch fileType {
case files.JSON:
data, err = json.MarshalIndent(result, "", " ")
case files.XML:
data, err = xml.MarshalIndent(result, "", " ")
case files.YAML:
data, err = yaml.Marshal(result)
case files.TEXT:
var outStrings []string
for _, r := range result {
out := fmt.Sprintf(
"Id: %s\nEmail: %s\nIpAddress: %s\nUsername: %s\nPassword: %s\nHashedPassword: %s\nHashType: %s\nName: %s\nVin: %s\nAddress: %s\nPhone: %s\nDatabaseName: %s\n\n",
r.DehashedId, r.Email, r.IpAddress, r.Username, r.Password, r.HashedPassword, r.HashType, r.Name, r.Vin, r.Address, r.Phone, r.DatabaseName)
outStrings = append(outStrings, out)
}
data = []byte(strings.Join(outStrings, ""))
default:
return errors.New("unsupported file type")
}
if err != nil {
return err
}
filePath := fmt.Sprintf("%s.%s", outputFile, fileType)
return ioutil.WriteFile(filePath, data, 0644)
}
+44
View File
@@ -0,0 +1,44 @@
package files
type FileType int32
const (
JSON FileType = iota
XML
YAML
TEXT
)
func GetFileType(filetype string) FileType {
switch filetype {
case "json":
return JSON
case "xml":
return XML
case "yaml":
return YAML
case "txt":
return TEXT
default:
return JSON
}
}
func (ft FileType) String() string {
switch ft {
case JSON:
return "json"
case XML:
return "xml"
case YAML:
return "yaml"
case TEXT:
return "txt"
default:
return "json"
}
}
func (ft FileType) Extension() string {
return "." + ft.String()
}
+48
View File
@@ -0,0 +1,48 @@
package pretty
import (
"fmt"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/table"
)
var (
rows = [][]string{
{"Chinese", "您好", "你好"},
{"Japanese", "こんにちは", "やあ"},
{"Arabic", "أهلين", "أهلا"},
{"Russian", "Здравствуйте", "Привет"},
{"Spanish", "Hola", "¿Qué tal?"},
}
purple = lipgloss.Color("99")
gray = lipgloss.Color("245")
lightGray = lipgloss.Color("241")
headerStyle = lipgloss.NewStyle().Foreground(purple).Bold(true).Align(lipgloss.Center)
cellStyle = lipgloss.NewStyle().Padding(0, 1)
oddRowStyle = cellStyle.Foreground(gray)
evenRowStyle = cellStyle.Foreground(lightGray)
)
func Table(headers []string, rows [][]string) {
t := table.New().
Border(lipgloss.NormalBorder()).
BorderStyle(lipgloss.NewStyle().Foreground(purple)).
StyleFunc(func(row, col int) lipgloss.Style {
switch {
case row == table.HeaderRow:
return headerStyle
case row%2 == 0:
return evenRowStyle
default:
return oddRowStyle
}
}).
Headers(headers...).
Rows(rows...)
// You can also add tables row-by-row
//t.Row("English", "You look absolutely fabulous.", "How's it going?")
fmt.Println(t)
}
+111
View File
@@ -0,0 +1,111 @@
package query
import (
"dehasher/internal/sqlite"
"fmt"
"log"
"net/http"
"net/url"
"os"
"strings"
)
type DehashedClient struct {
key string
email string
results []sqlite.Result
client *http.Client
query string
params string
printBal bool
total int
balance int
}
var baseUrl = "https://api.dehashed.com/v2/search"
func NewDehashedClient(key, email string, printBal bool) *DehashedClient {
return &DehashedClient{key: key, email: email, results: make([]sqlite.Result, 0), client: &http.Client{}, printBal: printBal}
}
func (dc *DehashedClient) getKey() string {
return dc.key
}
func (dc *DehashedClient) getEmail() string {
return dc.email
}
func (dc *DehashedClient) GetResults() sqlite.DehashedResults {
return sqlite.DehashedResults{Results: dc.results}
}
func (dc *DehashedClient) buildQuery(params map[string]string) {
urlParams := url.Values{}
urlString := baseUrl
if len(params) > 0 {
urlString += "?query="
for k, v := range params {
if len(v) > 0 {
urlParams.Add(k, v)
}
}
}
tmp, _ := url.QueryUnescape(urlParams.Encode())
tmp2 := strings.Replace(tmp, "=", ":", -1)
dc.params = tmp2
urlString += dc.params
dc.query = urlString
}
func (dc *DehashedClient) setResults(results int) {
dc.query = fmt.Sprintf("%s?query=%s&size=%d", baseUrl, dc.params, results)
}
func (dc *DehashedClient) setPage(page int) {
dc.query = fmt.Sprintf("%s&nextPage=%d", dc.query, page)
}
func (dc *DehashedClient) Do() int {
fmt.Printf("\n\t[*] Performing Request...")
req, err := http.NewRequest("GET", dc.query, nil)
if err != nil {
fmt.Printf("[!] Error constructing request: %v", err)
os.Exit(-1)
}
dc.setAuth(req)
req.Header.Add("Dehashed-Api-Key", dc.getKey())
req.Header.Add("Accept", "application/json")
resp, err := dc.client.Do(req)
if err != nil {
fmt.Printf("[!] Error performing request: %s\n%v", dc.query, err)
os.Exit(-1)
}
if resp.StatusCode != 200 {
dhErr := GetDehashedError(resp.StatusCode)
fmt.Println()
log.Fatal(dhErr.Error())
}
entries, balance, total := sqlite.NewDehashedResults(resp.Body)
dc.results = append(dc.results, entries...)
dc.balance = balance
dc.total += total
if dc.printBal {
fmt.Printf("\n\t\t[*] Balance Remaining: %d", balance)
}
return total
}
func (dc *DehashedClient) setAuth(r *http.Request) {
r.SetBasicAuth(dc.email, dc.key)
}
func (dc *DehashedClient) GetDomains() int {
return dc.balance
}
+193
View File
@@ -0,0 +1,193 @@
package query
import (
"bytes"
"crypto/sha256"
"dehasher/internal/sqlite"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"go.uber.org/zap"
"io"
"net/http"
"strings"
)
type DehashedParameter string
const (
Username DehashedParameter = "username"
Email DehashedParameter = "email"
Password DehashedParameter = "password"
HashedPassword DehashedParameter = "hashed_password"
Name DehashedParameter = "name"
IpAddress DehashedParameter = "ip_address"
Domain DehashedParameter = "domain"
Vin DehashedParameter = "vin"
LicensePlate DehashedParameter = "license_plate"
Address DehashedParameter = "address"
Phone DehashedParameter = "phone"
Social DehashedParameter = "social"
CryptoAddress DehashedParameter = "cryptocurrency_address"
)
func (dp DehashedParameter) GetArgumentString(arg string) string {
return fmt.Sprintf("%s:%s", string(dp), arg)
}
type DehashedSearchRequest struct {
ForcePlaintext bool `json:"-"`
Page int `json:"page"`
Query string `json:"query"`
Size int `json:"size"`
Wildcard bool `json:"wildcard"`
Regex bool `json:"regex"`
DeDupe bool `json:"de_dupe"`
}
func NewDehashedSearchRequest(page, size int, wildcard, regex, forcePlaintext bool) *DehashedSearchRequest {
return &DehashedSearchRequest{Page: page, Query: "", Size: size, Wildcard: wildcard, Regex: regex, DeDupe: true, ForcePlaintext: forcePlaintext}
}
func (dsr *DehashedSearchRequest) buildQuery(query string, param DehashedParameter) {
if len(dsr.Query) > 0 {
dsr.Query = fmt.Sprintf("%s&%s", strings.TrimSpace(dsr.Query), strings.TrimSpace(query))
} else {
dsr.Query = query
}
}
func (dsr *DehashedSearchRequest) AddUsernameQuery(query string) {
query = strings.TrimSpace(query)
dsr.buildQuery(Username.GetArgumentString(query), Username)
}
func (dsr *DehashedSearchRequest) AddEmailQuery(query string) {
query = strings.TrimSpace(query)
dsr.buildQuery(Email.GetArgumentString(query), Email)
}
func (dsr *DehashedSearchRequest) AddIpAddressQuery(query string) {
query = strings.TrimSpace(query)
dsr.buildQuery(IpAddress.GetArgumentString(query), IpAddress)
}
func (dsr *DehashedSearchRequest) AddDomainQuery(query string) {
query = strings.TrimSpace(query)
dsr.buildQuery(Domain.GetArgumentString(query), Domain)
}
func (dsr *DehashedSearchRequest) AddPasswordQuery(query string) {
if dsr.ForcePlaintext {
dsr.buildQuery(Password.GetArgumentString(query), Password)
return
}
hash := sha256.Sum256([]byte(query))
query = hex.EncodeToString(hash[:])
dsr.AddHashedPasswordQuery(query)
}
func (dsr *DehashedSearchRequest) AddVinQuery(query string) {
query = strings.TrimSpace(query)
dsr.buildQuery(Vin.GetArgumentString(query), Vin)
}
func (dsr *DehashedSearchRequest) AddLicensePlateQuery(query string) {
query = strings.TrimSpace(query)
dsr.buildQuery(LicensePlate.GetArgumentString(query), LicensePlate)
}
func (dsr *DehashedSearchRequest) AddAddressQuery(query string) {
query = strings.TrimSpace(query)
dsr.buildQuery(Address.GetArgumentString(query), Address)
}
func (dsr *DehashedSearchRequest) AddPhoneQuery(query string) {
query = strings.TrimSpace(query)
dsr.buildQuery(Phone.GetArgumentString(query), Phone)
}
func (dsr *DehashedSearchRequest) AddSocialQuery(query string) {
query = strings.TrimSpace(query)
dsr.buildQuery(Social.GetArgumentString(query), Social)
}
func (dsr *DehashedSearchRequest) AddCryptoAddressQuery(query string) {
query = strings.TrimSpace(query)
dsr.buildQuery(CryptoAddress.GetArgumentString(query), CryptoAddress)
}
func (dsr *DehashedSearchRequest) AddHashedPasswordQuery(query string) {
dsr.buildQuery(HashedPassword.GetArgumentString(query), HashedPassword)
}
func (dsr *DehashedSearchRequest) AddNameQuery(query string) {
query = strings.TrimSpace(query)
dsr.buildQuery(Name.GetArgumentString(query), Name)
}
type DehashedClientV2 struct {
apiKey string
results []sqlite.Result
}
func NewDehashedClientV2(apiKey string) *DehashedClientV2 {
return &DehashedClientV2{apiKey: apiKey}
}
func (dcv2 *DehashedClientV2) Search(searchRequest DehashedSearchRequest) (int, error) {
reqBody, _ := json.Marshal(searchRequest)
req, err := http.NewRequest("POST", "https://api.dehashed.com/v2/search", bytes.NewReader(reqBody))
if err != nil {
return -1, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Dehashed-Api-Key", dcv2.apiKey)
res, err := http.DefaultClient.Do(req)
if res != nil {
defer res.Body.Close()
}
if err != nil {
zap.L().Error("v2_search",
zap.String("message", "failed to perform request"),
zap.Error(err),
)
return -1, err
}
if res == nil {
zap.L().Error("v2_search",
zap.String("message", "response was nil"),
)
return -1, errors.New("response was nil")
}
b, err := io.ReadAll(res.Body)
if err != nil {
zap.L().Error("v2_search",
zap.String("message", "failed to read response body"),
zap.Error(err),
)
return -1, err
}
var responseResults sqlite.DehashedResponse
err = json.Unmarshal(b, &responseResults)
if err != nil {
zap.L().Error("v2_search",
zap.String("message", "failed to unmarshal response body"),
zap.Error(err),
)
return -1, err
}
dcv2.results = append(dcv2.results, responseResults.Entries...)
return responseResults.TotalResults, nil
}
func (dcv2 *DehashedClientV2) GetResults() sqlite.DehashedResults {
return sqlite.DehashedResults{Results: dcv2.results}
}
func (dcv2 *DehashedClientV2) GetTotalResults() int {
return len(dcv2.results)
}
+206
View File
@@ -0,0 +1,206 @@
package query
import (
"dehasher/internal/export"
"dehasher/internal/sqlite"
"encoding/json"
"fmt"
"go.uber.org/zap"
"os"
)
// Dehasher is a struct for querying the Dehashed API
type Dehasher struct {
options sqlite.QueryOptions
nextPage int
request *DehashedSearchRequest
client *DehashedClientV2
}
// NewDehasher creates a new Dehasher
func NewDehasher(options *sqlite.QueryOptions) *Dehasher {
dh := &Dehasher{
options: *options,
nextPage: options.StartingPage + 1,
}
dh.setQueries()
dh.request = NewDehashedSearchRequest(dh.options.StartingPage, dh.options.MaxRecords, dh.options.WildcardMatch, dh.options.RegexMatch, false)
dh.buildRequest()
return dh
}
// SetClientCredentials sets the client credentials for the dehasher
func (dh *Dehasher) SetClientCredentials(key string) {
dh.client = NewDehashedClientV2(key)
}
func (dh *Dehasher) getNextPage() int {
nextPage := dh.nextPage
dh.nextPage += 1
return nextPage
}
// setQueries sets the number of queries to make based on the number of records and requests
func (dh *Dehasher) setQueries() {
var numQueries int
switch {
case dh.options.MaxRequests == 0:
zap.L().Error("max requests cannot be zero")
fmt.Println("[!] Max Requests cannot be zero")
os.Exit(1)
case dh.options.MaxRecords <= 10000 || dh.options.MaxRequests == 1:
numQueries = 1
if dh.options.MaxRecords > 10000 {
dh.options.MaxRecords = 10000
}
zap.L().Info("max requests set to 1", zap.Int("max_records", dh.options.MaxRecords))
case dh.options.MaxRequests < 0 && dh.options.MaxRecords > 20000:
numQueries = 3
dh.options.MaxRecords = 10000
zap.L().Info("max requests set to 3", zap.Int("max_records", dh.options.MaxRecords))
case dh.options.MaxRequests < 0 && dh.options.MaxRecords > 10000:
numQueries = 2
dh.options.MaxRecords = 10000
zap.L().Info("max requests set to 2", zap.Int("max_records", dh.options.MaxRecords))
case dh.options.MaxRecords < 0 && dh.options.MaxRecords < 10000:
numQueries = 1
zap.L().Info("max requests set to 1", zap.Int("max_records", dh.options.MaxRecords))
case dh.options.MaxRequests == 2 && dh.options.MaxRecords > 20000:
numQueries = 2
dh.options.MaxRecords = 10000
zap.L().Info("max requests set to 2", zap.Int("max_records", dh.options.MaxRecords))
case dh.options.MaxRequests == 2 && dh.options.MaxRecords <= 10000:
numQueries = 1
zap.L().Info("max requests set to 1", zap.Int("max_records", dh.options.MaxRecords))
default:
numQueries = 3
dh.options.MaxRecords = 10000
zap.L().Info("max requests set to 3", zap.Int("max_records", dh.options.MaxRecords))
}
dh.options.MaxRequests = numQueries
fmt.Printf("Making %d Requests for %d Records (%d Total)\n", dh.options.MaxRequests, dh.options.MaxRecords, dh.options.MaxRequests*dh.options.MaxRecords)
}
// Start starts the querying process
func (dh *Dehasher) Start() {
fmt.Println("[*] Querying Dehashed API...")
for i := 0; i < dh.options.MaxRequests; i++ {
fmt.Printf("\n\t[*] Performing Request...")
count, err := dh.client.Search(*dh.request)
if err != nil {
fmt.Printf("[!] Error performing request: %v", err)
os.Exit(-1)
}
if count < dh.options.MaxRecords {
fmt.Printf("\n\t\t[+] Retrieved %d Records", count)
fmt.Printf("\n[-] Not Enough Entries, ending queries")
break
} else {
fmt.Printf("\n\t\t[+] Retrieved %d Records", dh.options.MaxRecords)
}
dh.request.Page = dh.getNextPage()
}
dh.parseResults()
}
// buildRequest constructs the query map
func (dh *Dehasher) buildRequest() {
if len(dh.options.UsernameQuery) > 0 {
dh.request.AddUsernameQuery(dh.options.UsernameQuery)
}
if len(dh.options.EmailQuery) > 0 {
dh.request.AddEmailQuery(dh.options.EmailQuery)
}
if len(dh.options.IpQuery) > 0 {
dh.request.AddIpAddressQuery(dh.options.IpQuery)
}
if len(dh.options.HashQuery) > 0 {
dh.request.AddHashedPasswordQuery(dh.options.HashQuery)
}
if len(dh.options.PassQuery) > 0 {
dh.request.AddPasswordQuery(dh.options.PassQuery)
}
if len(dh.options.NameQuery) > 0 {
dh.request.AddNameQuery(dh.options.NameQuery)
}
if len(dh.options.DomainQuery) > 0 {
dh.request.AddDomainQuery(dh.options.DomainQuery)
}
if len(dh.options.VinQuery) > 0 {
dh.request.AddVinQuery(dh.options.VinQuery)
}
if len(dh.options.LicensePlateQuery) > 0 {
dh.request.AddLicensePlateQuery(dh.options.LicensePlateQuery)
}
if len(dh.options.AddressQuery) > 0 {
dh.request.AddAddressQuery(dh.options.AddressQuery)
}
if len(dh.options.PhoneQuery) > 0 {
dh.request.AddPhoneQuery(dh.options.PhoneQuery)
}
if len(dh.options.SocialQuery) > 0 {
dh.request.AddSocialQuery(dh.options.SocialQuery)
}
if len(dh.options.CryptoAddressQuery) > 0 {
dh.request.AddCryptoAddressQuery(dh.options.CryptoAddressQuery)
}
}
// parseResults parses the results and writes them to a file
func (dh *Dehasher) parseResults() {
var data []byte
zap.L().Info("extracting_credentials")
results := dh.client.GetResults()
creds := results.ExtractCredentials()
fmt.Printf("\n\t[*] Discovered %d Credentials", len(creds))
err := sqlite.StoreCreds(creds)
if err != nil {
zap.L().Error("store_creds",
zap.String("message", "failed to store creds"),
zap.Error(err),
)
}
zap.L().Info("creds_stored", zap.Int("count", len(creds)))
zap.L().Info("storing_results")
err = sqlite.StoreResults(results)
if err != nil {
zap.L().Error("store_results",
zap.String("message", "failed to store results"),
zap.Error(err),
)
}
zap.L().Info("results_stored", zap.Int("count", len(results.Results)))
if len(results.Results) > 0 {
fmt.Printf("\n\t[*] Writing entries to file: %s.%s", dh.options.OutputFile, dh.options.OutputFormat.String())
if !dh.options.CredsOnly {
err := export.WriteToFile(results, dh.options.OutputFile, dh.options.OutputFormat)
if err != nil {
fmt.Printf("\n[!] Error Writing to file: %v\n\tOutputting to terminal.", err)
data, err = json.MarshalIndent(results, "", " ")
fmt.Println(string(data))
os.Exit(0)
} else {
fmt.Println("\n\t\t[*] Success\n")
}
} else {
creds := results.ExtractCredentials()
err := export.WriteCredsToFile(creds, dh.options.OutputFile, dh.options.OutputFormat)
if err != nil {
fmt.Printf("\n[!] Error Writing to file: %v\n\tOutputting to terminal.", err)
data, err = json.MarshalIndent(creds, "", " ")
fmt.Println(string(data))
os.Exit(0)
} else {
fmt.Println("\n\t\t[*] Success\n")
}
}
}
}
+33
View File
@@ -0,0 +1,33 @@
package query
type DehashError struct {
Message string
Code int
}
type DehashResponseError struct {
HttpResponse int `json:"HTTP Response Code"`
}
func (de *DehashError) Error() string {
return de.Message
}
func GetDehashedError(c int) DehashError {
switch c {
case 400:
return DehashError{Code: 400, Message: "There is an issue with authentication. Please check your API key and email. If you haven't, refresh your API Key "}
case 401:
return DehashError{Code: 401, Message: "You need a search subscription and API credits to use the API, please purchase a search subscription and add credits to your account."}
case 403:
return DehashError{Code: 403, Message: "Insufficient Credits"}
case 404:
return DehashError{Code: 404, Message: "Method not permitted"}
case 429:
return DehashError{Code: 420, Message: "Rate Limited"}
case 302:
return DehashError{Code: 302, Message: "Invalid/Missing Query"}
default:
return DehashError{Code: -1, Message: "An unknown error has occurred"}
}
}
+365
View File
@@ -0,0 +1,365 @@
package sqlite
import (
"fmt"
"go.uber.org/zap"
"gorm.io/gorm"
"time"
)
// QueryResults queries the database for results based on the provided options
func QueryResults(options *DBOptions) ([]Result, error) {
db := GetDB()
var results []Result
query := db.Model(&Result{})
// Apply filters based on the provided options
query = applyFilters(query, options)
// Apply limit
if options.Limit > 0 {
query = query.Limit(options.Limit)
}
// Execute the query
if err := query.Find(&results).Error; err != nil {
zap.L().Error("query_results",
zap.String("message", "failed to query results"),
zap.Error(err),
)
return nil, fmt.Errorf("failed to query results: %w", err)
}
return results, nil
}
// applyFilters applies filters to the query based on the provided options
func applyFilters(query *gorm.DB, options *DBOptions) *gorm.DB {
// Helper function to apply filter based on exact match setting
applyFilter := func(field, value string) *gorm.DB {
if value == "" {
return query
}
if options.ExactMatch {
return query.Where(field+" = ?", value)
} else {
return query.Where(field+" LIKE ?", "%"+value+"%")
}
}
// Apply filters for each field if provided
if options.Email != "" {
query = applyFilter("email", options.Email)
}
if options.Username != "" {
query = applyFilter("username", options.Username)
}
if options.IPAddress != "" {
query = applyFilter("ip_address", options.IPAddress)
}
if options.Password != "" {
query = applyFilter("password", options.Password)
}
if options.HashedPassword != "" {
query = applyFilter("hashed_password", options.HashedPassword)
}
if options.Name != "" {
query = applyFilter("name", options.Name)
}
if options.Vin != "" {
query = applyFilter("vin", options.Vin)
}
if options.LicensePlate != "" {
query = applyFilter("license_plate", options.LicensePlate)
}
if options.Address != "" {
query = applyFilter("address", options.Address)
}
if options.Phone != "" {
query = applyFilter("phone", options.Phone)
}
if options.Social != "" {
query = applyFilter("social", options.Social)
}
if options.CryptoCurrencyAddress != "" {
query = applyFilter("cryptocurrency_address", options.CryptoCurrencyAddress)
}
if options.Domain != "" {
query = applyFilter("url", options.Domain)
}
// Apply non-empty field filters
for _, field := range options.NonEmptyFields {
switch field {
case "username":
query = query.Where("JSON_ARRAY_LENGTH(username) > 0")
case "email":
query = query.Where("JSON_ARRAY_LENGTH(email) > 0")
case "ip_address", "ipaddress", "ip":
query = query.Where("JSON_ARRAY_LENGTH(ip_address) > 0")
case "password":
query = query.Where("JSON_ARRAY_LENGTH(password) > 0")
case "hashed_password", "hash":
query = query.Where("JSON_ARRAY_LENGTH(hashed_password) > 0")
case "name":
query = query.Where("JSON_ARRAY_LENGTH(name) > 0")
case "vin":
query = query.Where("JSON_ARRAY_LENGTH(vin) > 0")
case "license_plate", "license":
query = query.Where("JSON_ARRAY_LENGTH(license_plate) > 0")
case "address":
query = query.Where("JSON_ARRAY_LENGTH(address) > 0")
case "phone":
query = query.Where("JSON_ARRAY_LENGTH(phone) > 0")
case "social":
query = query.Where("JSON_ARRAY_LENGTH(social) > 0")
case "cryptocurrency_address", "crypto":
query = query.Where("JSON_ARRAY_LENGTH(cryptocurrency_address) > 0")
case "url", "domain":
query = query.Where("JSON_ARRAY_LENGTH(url) > 0")
}
}
return query
}
// GetResultsCount returns the count of results matching the provided options
func GetResultsCount(options *DBOptions) (int64, error) {
db := GetDB()
var count int64
query := db.Model(&Result{})
// Apply filters based on the provided options
query = applyFilters(query, options)
// Count the results
if err := query.Count(&count).Error; err != nil {
zap.L().Error("get_results_count",
zap.String("message", "failed to count results"),
zap.Error(err),
)
return 0, fmt.Errorf("failed to count results: %w", err)
}
return count, nil
}
// QueryRuns queries the database for previous query runs (QueryOptions) based on the provided filters
func QueryRuns(limit, lastXRuns int, startDate, endDate time.Time, containsQuery string) ([]QueryOptions, error) {
db := GetDB()
var runs []QueryOptions
query := db.Model(&QueryOptions{})
// Apply date range filter if provided
if lastXRuns > 0 {
query = query.Order("created_at DESC").Limit(lastXRuns)
} else if !startDate.IsZero() && !endDate.IsZero() {
query = query.Where("created_at BETWEEN ? AND ?", startDate, endDate)
} else if !startDate.IsZero() {
query = query.Where("created_at >= ?", startDate)
} else if !endDate.IsZero() {
query = query.Where("created_at <= ?", endDate)
}
// Apply query filter if provided
if containsQuery != "" {
// Search in all query fields
query = query.Where(
"username_query LIKE ? OR "+
"email_query LIKE ? OR "+
"ip_query LIKE ? OR "+
"pass_query LIKE ? OR "+
"hash_query LIKE ? OR "+
"name_query LIKE ? OR "+
"domain_query LIKE ? OR "+
"vin_query LIKE ? OR "+
"license_plate_query LIKE ? OR "+
"address_query LIKE ? OR "+
"phone_query LIKE ? OR "+
"social_query LIKE ? OR "+
"crypto_address_query LIKE ?",
"%"+containsQuery+"%", "%"+containsQuery+"%", "%"+containsQuery+"%",
"%"+containsQuery+"%", "%"+containsQuery+"%", "%"+containsQuery+"%",
"%"+containsQuery+"%", "%"+containsQuery+"%", "%"+containsQuery+"%",
"%"+containsQuery+"%", "%"+containsQuery+"%", "%"+containsQuery+"%",
"%"+containsQuery+"%",
)
}
// Apply limit
if limit > 0 {
query = query.Limit(limit)
}
// Order by most recent first
query = query.Order("created_at DESC")
// Execute the query
if err := query.Find(&runs).Error; err != nil {
zap.L().Error("query_runs",
zap.String("message", "failed to query runs"),
zap.Error(err),
)
return nil, fmt.Errorf("failed to query runs: %w", err)
}
return runs, nil
}
// GetRunsCount returns the count of runs matching the provided filters
func GetRunsCount(lastXRuns int, startDate, endDate time.Time, containsQuery string) (int64, error) {
db := GetDB()
var count int64
query := db.Model(&QueryOptions{})
// Apply date range filter if provided
if lastXRuns > 0 {
query = query.Order("created_at DESC").Limit(lastXRuns)
} else if !startDate.IsZero() && !endDate.IsZero() {
query = query.Where("created_at BETWEEN ? AND ?", startDate, endDate)
} else if !startDate.IsZero() {
query = query.Where("created_at >= ?", startDate)
} else if !endDate.IsZero() {
query = query.Where("created_at <= ?", endDate)
}
// Apply query filter if provided
if containsQuery != "" {
// Search in all query fields
query = query.Where(
"username_query LIKE ? OR "+
"email_query LIKE ? OR "+
"ip_query LIKE ? OR "+
"pass_query LIKE ? OR "+
"hash_query LIKE ? OR "+
"name_query LIKE ? OR "+
"domain_query LIKE ? OR "+
"vin_query LIKE ? OR "+
"license_plate_query LIKE ? OR "+
"address_query LIKE ? OR "+
"phone_query LIKE ? OR "+
"social_query LIKE ? OR "+
"crypto_address_query LIKE ?",
"%"+containsQuery+"%", "%"+containsQuery+"%", "%"+containsQuery+"%",
"%"+containsQuery+"%", "%"+containsQuery+"%", "%"+containsQuery+"%",
"%"+containsQuery+"%", "%"+containsQuery+"%", "%"+containsQuery+"%",
"%"+containsQuery+"%", "%"+containsQuery+"%", "%"+containsQuery+"%",
"%"+containsQuery+"%",
)
}
// Count the results
if err := query.Count(&count).Error; err != nil {
zap.L().Error("get_runs_count",
zap.String("message", "failed to count runs"),
zap.Error(err),
)
return 0, fmt.Errorf("failed to count runs: %w", err)
}
return count, nil
}
// QueryCreds queries the database for credentials based on the provided filters
func QueryCreds(options *DBOptions) ([]Creds, error) {
db := GetDB()
var creds []Creds
query := db.Model(&Creds{})
// Apply filters based on the provided options
if options.Username != "" {
if options.ExactMatch {
query = query.Where("username = ?", options.Username)
} else {
query = query.Where("username LIKE ?", "%"+options.Username+"%")
}
}
if options.Email != "" {
if options.ExactMatch {
query = query.Where("email = ?", options.Email)
} else {
query = query.Where("email LIKE ?", "%"+options.Email+"%")
}
}
if options.Password != "" {
if options.ExactMatch {
query = query.Where("password = ?", options.Password)
} else {
query = query.Where("password LIKE ?", "%"+options.Password+"%")
}
}
// Apply limit
if options.Limit > 0 {
query = query.Limit(options.Limit)
}
// Execute the query
if err := query.Find(&creds).Error; err != nil {
zap.L().Error("query_creds",
zap.String("message", "failed to query credentials"),
zap.Error(err),
)
return nil, fmt.Errorf("failed to query credentials: %w", err)
}
return creds, nil
}
// GetCredsCount returns the count of credentials matching the provided filters
func GetCredsCount(options *DBOptions) (int64, error) {
db := GetDB()
var count int64
query := db.Model(&Creds{})
// Apply filters based on the provided options
if options.Username != "" {
if options.ExactMatch {
query = query.Where("username = ?", options.Username)
} else {
query = query.Where("username LIKE ?", "%"+options.Username+"%")
}
}
if options.Email != "" {
if options.ExactMatch {
query = query.Where("email = ?", options.Email)
} else {
query = query.Where("email LIKE ?", "%"+options.Email+"%")
}
}
if options.Password != "" {
if options.ExactMatch {
query = query.Where("password = ?", options.Password)
} else {
query = query.Where("password LIKE ?", "%"+options.Password+"%")
}
}
// Count the results
if err := query.Count(&count).Error; err != nil {
zap.L().Error("get_creds_count",
zap.String("message", "failed to count credentials"),
zap.Error(err),
)
return 0, fmt.Errorf("failed to count credentials: %w", err)
}
return count, nil
}
+209
View File
@@ -0,0 +1,209 @@
package sqlite
import (
"fmt"
"go.uber.org/zap"
"gorm.io/gorm/clause"
"os"
"path/filepath"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var DB *gorm.DB
// InitDB initializes the database connection
func InitDB(dbDir string) (*gorm.DB, error) {
zap.L().Info("Initializing database")
// Create directory if it doesn't exist
if err := os.MkdirAll(dbDir, 0755); err != nil {
zap.L().Error("Failed to create database directory", zap.Error(err))
return nil, fmt.Errorf("failed to create database directory: %w", err)
}
dbPath := filepath.Join(dbDir, "dehashed.sqlite")
db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
if err != nil {
zap.L().Error("Failed to connect to database", zap.Error(err))
return nil, fmt.Errorf("failed to connect to database: %w", err)
}
// Auto migrate your models
err = db.AutoMigrate(&Result{}, &Creds{}, QueryOptions{}, Creds{}, WhoisRecord{}, SubdomainRecord{}, HistoryRecord{})
if err != nil {
zap.L().Error("Failed to migrate database", zap.Error(err))
return nil, fmt.Errorf("failed to migrate database: %w", err)
}
DB = db
return db, nil
}
// GetDB returns the database connection
func GetDB() *gorm.DB {
if DB == nil {
zap.L().Error("database not initialized")
fmt.Println("sqlite database not initialized")
os.Exit(1)
}
return DB
}
func StoreResults(results DehashedResults) error {
if len(results.Results) == 0 {
return nil
}
zap.L().Info("Storing results", zap.Int("count", len(results.Results)))
db := GetDB()
// Use batch insert with conflict handling
const batchSize = 100
var lastErr error
// Extract the slice of results
resultSlice := results.Results
for i := 0; i < len(resultSlice); i += batchSize {
end := i + batchSize
if end > len(resultSlice) {
end = len(resultSlice)
}
batch := resultSlice[i:end]
// Use Clauses with OnConflict DoNothing to skip conflicts
err := db.Clauses(clause.OnConflict{DoNothing: true}).CreateInBatches(&batch, batchSize).Error
if err != nil {
zap.L().Warn("Error storing some results", zap.Error(err))
lastErr = err
// Continue with next batch despite error
}
}
return lastErr
}
func StoreCreds(creds []Creds) error {
if len(creds) == 0 {
return nil
}
zap.L().Info("Storing credentials", zap.Int("count", len(creds)))
db := GetDB()
// Use batch insert with conflict handling
// This will insert records in batches and continue even if some fail
const batchSize = 100
var lastErr error
for i := 0; i < len(creds); i += batchSize {
end := i + batchSize
if end > len(creds) {
end = len(creds)
}
batch := creds[i:end]
// Use Clauses with OnConflict DoNothing to skip conflicts
err := db.Clauses(clause.OnConflict{DoNothing: true}).CreateInBatches(&batch, batchSize).Error
if err != nil {
zap.L().Warn("Error storing some credentials", zap.Error(err))
lastErr = err
// Continue with next batch despite error
}
}
return lastErr
}
func StoreQueryOptions(queryOptions *QueryOptions) error {
db := GetDB()
return db.Create(queryOptions).Error
}
func StoreWhoisRecord(whoisRecord WhoisRecord) error {
// Create a pointer to the record to make it addressable
recordPtr := &whoisRecord
zap.L().Info("Storing WHOIS record",
zap.String("domain", whoisRecord.DomainName))
db := GetDB()
// Use OnConflict clause to handle duplicates
err := db.Clauses(clause.OnConflict{DoNothing: true}).Create(recordPtr).Error
if err != nil {
zap.L().Error("store_whois_record",
zap.String("message", "failed to store whois record"),
zap.Error(err))
return err
}
return nil
}
func StoreSubdomainRecord(subdomainRecords []SubdomainRecord) error {
if len(subdomainRecords) == 0 {
return nil
}
zap.L().Info("Storing subdomain records", zap.Int("count", len(subdomainRecords)))
db := GetDB()
// Use batch insert with conflict handling
const batchSize = 100
var lastErr error
for i := 0; i < len(subdomainRecords); i += batchSize {
end := i + batchSize
if end > len(subdomainRecords) {
end = len(subdomainRecords)
}
batch := subdomainRecords[i:end]
// Use Clauses with OnConflict DoNothing to skip conflicts
err := db.Clauses(clause.OnConflict{DoNothing: true}).CreateInBatches(&batch, batchSize).Error
if err != nil {
zap.L().Warn("Error storing some subdomain records", zap.Error(err))
lastErr = err
// Continue with next batch despite error
}
}
return lastErr
}
func StoreHistoryRecord(historyRecords []HistoryRecord) error {
if len(historyRecords) == 0 {
return nil
}
zap.L().Info("Storing history records", zap.Int("count", len(historyRecords)))
db := GetDB()
// Use batch insert with conflict handling
const batchSize = 100
var lastErr error
for i := 0; i < len(historyRecords); i += batchSize {
end := i + batchSize
if end > len(historyRecords) {
end = len(historyRecords)
}
batch := historyRecords[i:end]
// Use Clauses with OnConflict DoNothing to skip conflicts
err := db.Clauses(clause.OnConflict{DoNothing: true}).CreateInBatches(&batch, batchSize).Error
if err != nil {
zap.L().Warn("Error storing some history records", zap.Error(err))
lastErr = err
// Continue with next batch despite error
}
}
return lastErr
}
+20
View File
@@ -0,0 +1,20 @@
package sqlite
type DehashedSearchRequest struct {
Page int `json:"page"`
Query string `json:"query"`
Size int `json:"size"`
Wildcard bool `json:"wildcard"`
Regex bool `json:"regex"`
DeDupe bool `json:"de_dupe"`
}
func NewDehashedSearchRequest(size int, wildcard, regex bool) *DehashedSearchRequest {
return &DehashedSearchRequest{
Page: 0,
Size: size,
Wildcard: false,
Regex: false,
DeDupe: true,
}
}
+90
View File
@@ -0,0 +1,90 @@
package sqlite
import (
"encoding/json"
"fmt"
"go.uber.org/zap"
"gorm.io/gorm"
"io"
"os"
)
type DehashedResponse struct {
Balance int `json:"balance"`
Entries []Result `json:"entries"`
Success bool `json:"success"`
Took string `json:"took"`
TotalResults int `json:"total"`
}
type Result struct {
gorm.Model
DehashedId string `json:"id" xml:"id" yaml:"id" gorm:"uniqueIndex"`
Email []string `json:"email,omitempty" xml:"email,omitempty" yaml:"email,omitempty" gorm:"serializer:json"`
IpAddress []string `json:"ip_address,omitempty" xml:"ip_address,omitempty" yaml:"ip_address,omitempty" gorm:"serializer:json"`
Username []string `json:"username,omitempty" xml:"username,omitempty" yaml:"username,omitempty" gorm:"serializer:json"`
Password []string `json:"password,omitempty" xml:"password,omitempty" yaml:"password,omitempty" gorm:"serializer:json"`
HashedPassword []string `json:"hashed_password,omitempty" xml:"hashed_password,omitempty" yaml:"hashed_password,omitempty" gorm:"serializer:json"`
HashType string `json:"hash_type,omitempty" xml:"hash_type,omitempty" yaml:"hash_type,omitempty"`
Name []string `json:"name,omitempty" xml:"name,omitempty" yaml:"name,omitempty" gorm:"serializer:json"`
Vin []string `json:"vin,omitempty" xml:"vin,omitempty" yaml:"vin,omitempty" gorm:"serializer:json"`
LicensePlate []string `json:"license_plate,omitempty" xml:"license_plate,omitempty" yaml:"license_plate,omitempty" gorm:"serializer:json"`
Url []string `json:"url,omitempty" xml:"url,omitempty" yaml:"url,omitempty" gorm:"serializer:json"`
Social []string `json:"social,omitempty" xml:"social,omitempty" yaml:"social,omitempty" gorm:"serializer:json"`
CryptoCurrencyAddress []string `json:"cryptocurrency_address,omitempty" xml:"cryptocurrency_address,omitempty" yaml:"cryptocurrency_address,omitempty" gorm:"serializer:json"`
Address []string `json:"address,omitempty" xml:"address,omitempty" yaml:"address,omitempty" gorm:"serializer:json"`
Phone []string `json:"phone,omitempty" xml:"phone,omitempty" yaml:"phone,omitempty" gorm:"serializer:json"`
Company []string `json:"company,omitempty" xml:"company,omitempty" yaml:"company,omitempty" gorm:"serializer:json"`
DatabaseName string `json:"database_name,omitempty" xml:"database_name,omitempty" yaml:"database_name,omitempty"`
}
type DehashedResults struct {
Results []Result `json:"results"`
}
func (dr *DehashedResults) ExtractCredentials() []Creds {
var creds []Creds
results := dr.Results
for _, r := range results {
if len(r.Password) > 0 {
// Get first email if available
email := ""
if len(r.Email) > 0 {
email = r.Email[0]
}
// Get first password
password := r.Password[0]
cred := Creds{Email: email, Password: password}
creds = append(creds, cred)
}
}
go func() {
err := StoreCreds(creds)
if err != nil {
zap.L().Error("store_creds",
zap.String("message", "failed to store creds"),
zap.Error(err),
)
fmt.Printf("Error Storing Results: %v", err)
}
}()
return creds
}
func NewDehashedResults(body io.Reader) ([]Result, int, int) {
var response DehashedResponse
err := json.NewDecoder(body).Decode(&response)
if err != nil {
fmt.Printf("Error Parsing Response Body: %v", err)
os.Exit(-1)
}
return response.Entries, response.Balance, response.TotalResults
}
+108
View File
@@ -0,0 +1,108 @@
package sqlite
import (
"dehasher/internal/files"
"fmt"
"gorm.io/gorm"
)
type DBOptions struct {
Username string
Email string
IPAddress string
Password string
HashedPassword string
Name string
Vin string
LicensePlate string
Address string
Phone string
Social string
CryptoCurrencyAddress string
Domain string
Limit int
ExactMatch bool
NonEmptyFields []string // Fields that should not be empty
DisplayFields []string // Fields to display in output
}
func NewDBOptions() *DBOptions {
return &DBOptions{
Limit: 100, // Default limit
ExactMatch: false,
NonEmptyFields: []string{},
DisplayFields: []string{},
}
}
func (o *DBOptions) Empty() bool {
return o.Username == "" && o.Email == "" && o.IPAddress == "" &&
o.Password == "" && o.HashedPassword == "" && o.Name == "" &&
o.Vin == "" && o.LicensePlate == "" && o.Address == "" &&
o.Phone == "" && o.Social == "" && o.CryptoCurrencyAddress == "" && o.Domain == "" &&
len(o.NonEmptyFields) == 0
}
type QueryOptions struct {
gorm.Model
MaxRecords int `json:"max_records"`
MaxRequests int `json:"max_requests"`
StartingPage int `json:"starting_page"`
OutputFormat files.FileType `json:"output_format"`
OutputFile string `json:"output_file"`
RegexMatch bool `json:"regex_match"`
WildcardMatch bool `json:"wildcard_match"`
UsernameQuery string `json:"username_query"`
EmailQuery string `json:"email_query"`
IpQuery string `json:"ip_query"`
PassQuery string `json:"pass_query"`
HashQuery string `json:"hash_query"`
NameQuery string `json:"name_query"`
DomainQuery string `json:"domain_query"`
VinQuery string `json:"vin_query"`
LicensePlateQuery string `json:"license_plate_query"`
AddressQuery string `json:"address_query"`
PhoneQuery string `json:"phone_query"`
SocialQuery string `json:"social_query"`
CryptoAddressQuery string `json:"crypto_address_query"`
PrintBalance bool `json:"print_balance"`
CredsOnly bool `json:"creds_only"`
}
func NewQueryOptions(maxRecords, maxRequests, startingPage int, outputFormat, outputFile, usernameQuery, emailQuery, ipQuery, passQuery, hashQuery, nameQuery, domainQuery, vinQuery, licensePlateQuery, addressQuery, phoneQuery, socialQuery, cryptoAddressQuery string, regexMatch, wildcardMatch, printBalance, credsOnly bool) *QueryOptions {
return &QueryOptions{
MaxRecords: maxRecords,
MaxRequests: maxRequests,
StartingPage: startingPage,
OutputFormat: files.GetFileType(outputFormat),
OutputFile: outputFile,
PrintBalance: printBalance,
CredsOnly: credsOnly,
RegexMatch: regexMatch,
WildcardMatch: wildcardMatch,
UsernameQuery: usernameQuery,
EmailQuery: emailQuery,
IpQuery: ipQuery,
PassQuery: passQuery,
HashQuery: hashQuery,
NameQuery: nameQuery,
DomainQuery: domainQuery,
VinQuery: vinQuery,
LicensePlateQuery: licensePlateQuery,
AddressQuery: addressQuery,
PhoneQuery: phoneQuery,
SocialQuery: socialQuery,
CryptoAddressQuery: cryptoAddressQuery,
}
}
type Creds struct {
gorm.Model
Email string `json:"email" yaml:"email" xml:"email"`
Username string `json:"username" yaml:"username" xml:"username"`
Password string `json:"password" yaml:"password" xml:"password"`
}
func (c Creds) ToString() string {
return fmt.Sprintf("%s%s%s", c.Username, "%", c.Password)
}
+160
View File
@@ -0,0 +1,160 @@
package sqlite
import "gorm.io/gorm"
type WhoIsLookupResult struct {
RemainingCredits int `json:"remaining_credits"`
Data Data `json:"data"`
}
type Data struct {
WhoisRecord WhoisRecord `json:"WhoisRecord"`
}
type WhoisRecord struct {
gorm.Model
Audit Audit `json:"audit" gorm:"serializer:json"`
ContactEmail string `json:"contactEmail"`
CreatedDate string `json:"createdDate"`
CreatedDateNormalized string `json:"createdDateNormalized"`
DomainName string `json:"domainName"`
DomainNameExt string `json:"domainNameExt"`
EstimatedDomainAge int `json:"estimatedDomainAge"`
ExpiresDate string `json:"expiresDate"`
ExpiresDateNormalized string `json:"expiresDateNormalized"`
Footer string `json:"footer"`
Header string `json:"header"`
NameServers NameServers `json:"nameServers" gorm:"serializer:json"`
ParseCode int `json:"parseCode"`
RawText string `json:"rawText"`
Registrant Contact `json:"registrant" gorm:"serializer:json"`
RegistrarIANAID string `json:"registrarIANAID"`
RegistrarName string `json:"registrarName"`
RegistryData RegistryData `json:"registryData" gorm:"serializer:json"`
Status string `json:"status"`
StrippedText string `json:"strippedText"`
TechnicalContact Contact `json:"technicalContact" gorm:"serializer:json"`
UpdatedDate string `json:"updatedDate"`
UpdatedDateNormalized string `json:"updatedDateNormalized"`
}
type Audit struct {
CreatedDate string `json:"createdDate"`
UpdatedDate string `json:"updatedDate"`
}
type NameServers struct {
HostNames []string `json:"hostNames"`
IPs []string `json:"ips"`
RawText string `json:"rawText"`
}
type Contact struct {
City string `json:"city"`
Country string `json:"country"`
CountryCode string `json:"countryCode"`
Name string `json:"name"`
Organization string `json:"organization"`
PostalCode string `json:"postalCode"`
RawText string `json:"rawText"`
State string `json:"state"`
Street1 string `json:"street1"`
Telephone string `json:"telephone"`
}
type RegistryData struct {
Audit Audit `json:"audit"`
CreatedDate string `json:"createdDate"`
CreatedDateNormalized string `json:"createdDateNormalized"`
DomainName string `json:"domainName"`
ExpiresDate string `json:"expiresDate"`
ExpiresDateNormalized string `json:"expiresDateNormalized"`
Footer string `json:"footer"`
Header string `json:"header"`
NameServers NameServers `json:"nameServers"`
ParseCode int `json:"parseCode"`
RawText string `json:"rawText"`
RegistrarIANAID string `json:"registrarIANAID"`
RegistrarName string `json:"registrarName"`
Status string `json:"status"`
StrippedText string `json:"strippedText"`
UpdatedDate string `json:"updatedDate"`
UpdatedDateNormalized string `json:"updatedDateNormalized"`
WhoisServer string `json:"whoisServer"`
}
type WhoIsSubdomainScan struct {
RemainingCredits int `json:"remaining_credits"`
Data ScanData `json:"data"`
}
type ScanData struct {
Result ScanResult `json:"result"`
Search string `json:"search"`
}
type ScanResult struct {
Count int `json:"count"`
Records []SubdomainRecord `json:"records"`
}
type SubdomainRecord struct {
gorm.Model
Domain string `json:"domain"`
FirstSeen int64 `json:"firstSeen"`
LastSeen int64 `json:"lastSeen"`
}
type WhoIsHistory struct {
RemainingCredits int `json:"remaining_credits"`
Data HistoryData `json:"data"`
}
type HistoryData struct {
Records []HistoryRecord `json:"records"`
RecordsCount int `json:"recordsCount"`
}
type HistoryRecord struct {
gorm.Model
AdministrativeContact ContactInfo `json:"administrativeContact" gorm:"serializer:json"`
Audit Audit `json:"audit" gorm:"serializer:json"`
BillingContact ContactInfo `json:"billingContact" gorm:"serializer:json"`
CleanText string `json:"cleanText"`
CreatedDateISO8601 string `json:"createdDateISO8601"`
CreatedDateRaw string `json:"createdDateRaw"`
DomainName string `json:"domainName"`
DomainType string `json:"domainType"`
ExpiresDateISO8601 string `json:"expiresDateISO8601"`
ExpiresDateRaw string `json:"expiresDateRaw"`
NameServers []string `json:"nameServers" gorm:"serializer:json"`
RawText string `json:"rawText"`
RegistrantContact ContactInfo `json:"registrantContact" gorm:"serializer:json"`
RegistrarName string `json:"registrarName"`
Status []string `json:"status" gorm:"serializer:json"`
TechnicalContact ContactInfo `json:"technicalContact" gorm:"serializer:json"`
UpdatedDateISO8601 string `json:"updatedDateISO8601"`
UpdatedDateRaw string `json:"updatedDateRaw"`
WhoisServer string `json:"whoisServer"`
ZoneContact ContactInfo `json:"zoneContact" gorm:"serializer:json"`
}
type ContactInfo struct {
City string `json:"city"`
Country string `json:"country"`
Email string `json:"email"`
Fax string `json:"fax"`
FaxExt string `json:"faxExt"`
Name string `json:"name"`
Organization string `json:"organization"`
PostalCode string `json:"postalCode"`
RawText string `json:"rawText"`
State string `json:"state"`
Street string `json:"street"`
Telephone string `json:"telephone"`
TelephoneExt string `json:"telephoneExt"`
}
type WhoIsCredits struct {
WhoisCredits int `json:"whois_credits"`
}
+319
View File
@@ -0,0 +1,319 @@
package whois
import (
"bytes"
"dehasher/internal/sqlite"
"encoding/json"
"errors"
"fmt"
"go.uber.org/zap"
"io"
"net/http"
)
type DehashedWHOISSearchRequest struct {
Include []string `json:"include,omitempty"`
Exclude []string `json:"exclude,omitempty"`
IPAddress string `json:"ip_address,omitempty"`
ReverseType string `json:"reverse_type,omitempty"`
Domain string `json:"domain,omitempty"`
MXAddress string `json:"mx_address,omitempty"`
NSAddress string `json:"ns_address,omitempty"`
SearchType string `json:"search_type,omitempty"`
}
func WhoisSearch(domain, apiKey string) (sqlite.WhoIsLookupResult, error) {
var whois sqlite.WhoIsLookupResult
whoisSearchRequest := DehashedWHOISSearchRequest{
Domain: domain,
SearchType: "whois",
}
reqBody, _ := json.Marshal(whoisSearchRequest)
req, err := http.NewRequest("POST", "https://api.dehashed.com/v2/whois/search", bytes.NewReader(reqBody))
if err != nil {
return whois, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Dehashed-Api-Key", apiKey)
res, err := http.DefaultClient.Do(req)
if res != nil {
defer res.Body.Close()
}
if err != nil {
return whois, err
}
if res == nil {
return whois, errors.New("response was nil")
}
b, err := io.ReadAll(res.Body)
if err != nil {
return whois, err
}
err = json.Unmarshal(b, &whois)
if err != nil {
zap.L().Error("whois_search",
zap.String("message", "failed to unmarshal response body"),
zap.Error(err),
)
fmt.Println("Error unmarshalling response body:", err)
fmt.Println("Response body:", string(b))
return whois, err
}
return whois, nil
}
func WhoisHistory(domain, apiKey string) (sqlite.WhoIsHistory, error) {
var whois sqlite.WhoIsHistory
whoisSearchRequest := DehashedWHOISSearchRequest{
Domain: domain,
SearchType: "whois-history",
}
reqBody, _ := json.Marshal(whoisSearchRequest)
req, err := http.NewRequest("POST", "https://api.dehashed.com/v2/whois/search", bytes.NewReader(reqBody))
if err != nil {
return whois, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Dehashed-Api-Key", apiKey)
res, err := http.DefaultClient.Do(req)
if res != nil {
zap.L().Info("whois_history",
zap.String("message", "response was not nil"),
)
defer res.Body.Close()
}
if err != nil {
zap.L().Error("whois_history",
zap.String("message", "failed to perform request"),
zap.Error(err),
)
return whois, err
}
if res == nil {
zap.L().Error("whois_history",
zap.String("message", "response was nil"),
)
return whois, errors.New("response was nil")
}
b, err := io.ReadAll(res.Body)
if err != nil {
zap.L().Error("whois_history",
zap.String("message", "failed to read response body"),
zap.Error(err),
)
return whois, err
}
err = json.Unmarshal(b, &whois)
if err != nil {
zap.L().Error("whois_history",
zap.String("message", "failed to unmarshal response body"),
zap.Error(err),
)
fmt.Println("Error unmarshalling response body:", err)
fmt.Println("Response body:", string(b))
return whois, err
}
return whois, nil
}
func ReverseWHOIS(include []string, exclude []string, reverseType, apiKey string) (string, error) {
whoisSearchRequest := DehashedWHOISSearchRequest{
Include: include,
Exclude: exclude,
ReverseType: reverseType,
SearchType: "reverse-whois",
}
reqBody, _ := json.Marshal(whoisSearchRequest)
req, err := http.NewRequest("POST", "https://api.dehashed.com/v2/whois/search", bytes.NewReader(reqBody))
if err != nil {
return "", err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Dehashed-Api-Key", apiKey)
res, err := http.DefaultClient.Do(req)
if res != nil {
defer res.Body.Close()
}
if err != nil {
return "", err
}
if res == nil {
return "", errors.New("response was nil")
}
b, err := io.ReadAll(res.Body)
if err != nil {
return "", err
}
return string(b), nil
}
func WhoisIP(ipAddress, apiKey string) ([]byte, error) {
whoisSearchRequest := DehashedWHOISSearchRequest{
IPAddress: ipAddress,
SearchType: "reverse-ip",
}
reqBody, _ := json.Marshal(whoisSearchRequest)
req, err := http.NewRequest("POST", "https://api.dehashed.com/v2/whois/search", bytes.NewReader(reqBody))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Dehashed-Api-Key", apiKey)
res, err := http.DefaultClient.Do(req)
if res != nil {
defer res.Body.Close()
}
if err != nil {
return nil, err
}
if res == nil {
return nil, errors.New("response was nil")
}
b, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}
return b, nil
}
func WhoisMX(mxAddress, apiKey string) (string, error) {
whoisSearchRequest := DehashedWHOISSearchRequest{
MXAddress: mxAddress,
SearchType: "reverse-mx",
}
reqBody, _ := json.Marshal(whoisSearchRequest)
req, err := http.NewRequest("POST", "https://api.dehashed.com/v2/whois/search", bytes.NewReader(reqBody))
if err != nil {
return "", err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Dehashed-Api-Key", apiKey)
res, err := http.DefaultClient.Do(req)
if res != nil {
defer res.Body.Close()
}
if err != nil {
return "", err
}
if res == nil {
return "", errors.New("response was nil")
}
b, err := io.ReadAll(res.Body)
if err != nil {
return "", err
}
return string(b), nil
}
func WhoisNS(nsAddress, apiKey string) (string, error) {
whoisSearchRequest := DehashedWHOISSearchRequest{
NSAddress: nsAddress,
SearchType: "reverse-ns",
}
reqBody, _ := json.Marshal(whoisSearchRequest)
req, err := http.NewRequest("POST", "https://api.dehashed.com/v2/whois/search", bytes.NewReader(reqBody))
if err != nil {
return "", err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Dehashed-Api-Key", apiKey)
res, err := http.DefaultClient.Do(req)
if res != nil {
defer res.Body.Close()
}
if err != nil {
return "", err
}
if res == nil {
return "", errors.New("response was nil")
}
b, err := io.ReadAll(res.Body)
if err != nil {
return "", err
}
return string(b), nil
}
func WhoisSubdomainScan(domain, apiKey string) (sqlite.WhoIsSubdomainScan, error) {
var whois sqlite.WhoIsSubdomainScan
whoisSearchRequest := DehashedWHOISSearchRequest{
Domain: domain,
SearchType: "subdomain-scan",
}
reqBody, _ := json.Marshal(whoisSearchRequest)
req, err := http.NewRequest("POST", "https://api.dehashed.com/v2/whois/search", bytes.NewReader(reqBody))
if err != nil {
return whois, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Dehashed-Api-Key", apiKey)
res, err := http.DefaultClient.Do(req)
if res != nil {
defer res.Body.Close()
}
if err != nil {
return whois, err
}
if res == nil {
return whois, errors.New("response was nil")
}
b, err := io.ReadAll(res.Body)
if err != nil {
return whois, err
}
err = json.Unmarshal(b, &whois)
if err != nil {
zap.L().Error("whois_subdomain_scan",
zap.String("message", "failed to unmarshal response body"),
zap.Error(err),
)
fmt.Println("Error unmarshalling response body:", err)
fmt.Println("Response body:", string(b))
return whois, err
}
return whois, nil
}
func GetWHOISCredits(apiKey string) (sqlite.WhoIsCredits, error) {
var whoisCredits sqlite.WhoIsCredits
req, err := http.NewRequest("GET", "https://api.dehashed.com/v2/whois/credits", nil)
if err != nil {
return whoisCredits, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Dehashed-Api-Key", apiKey)
res, err := http.DefaultClient.Do(req)
if res != nil {
defer res.Body.Close()
}
if err != nil {
return whoisCredits, err
}
if res == nil {
return whoisCredits, errors.New("response was nil")
}
b, err := io.ReadAll(res.Body)
if err != nil {
return whoisCredits, err
}
err = json.Unmarshal(b, &whoisCredits)
if err != nil {
zap.L().Error("get_whois_credits",
zap.String("message", "failed to unmarshal response body"),
zap.Error(err),
)
fmt.Println("Error unmarshalling response body:", err)
fmt.Println("Response body:", string(b))
return whoisCredits, err
}
return whoisCredits, nil
}
+455
View File
@@ -0,0 +1,455 @@
Id: Uhs6wdMRv-jq3VAHW_Wc
Email: [selby@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: []
HashType:
Name: [BRIAN SELBY]
Vin: []
Address: [224 SAINT CHARLES WAY STE 100, YORK, PA, 17402, US]
Phone: [7177181611]
DatabaseName: DemandScience by Pure Incubation
Id: nWaSwdMRbgUelnkGA_uI
Email: [kriddle@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [counseltrust.com:None||Cisco-PIX(MD5) COUNSELTRUST.COM:None||Cisco-PIX(MD5)]
HashType:
Name: [KATHY RIDDLE]
Vin: []
Address: [224 ST CHARLES WAY STE 100, YORK, PA, 17402, US]
Phone: [7177181600]
DatabaseName: DemandScience by Pure Incubation
Id: kRypwYMRZd5-FWZi9grp
Email: [david@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [COUNSELTRUST.COM:None||Cisco-PIX(MD5)]
HashType:
Name: [DAVID DOLAN]
Vin: []
Address: [224 ST CHARLES WAY SUITE 100, YORK, PA, 17402, US]
Phone: [7177181600]
DatabaseName: DemandScience by Pure Incubation
Id: AqCvwYMRs35batudGTqf
Email: [jpaff@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [COUNSELTRUST.COM:None||Cisco-PIX(MD5)]
HashType:
Name: []
Vin: []
Address: []
Phone: [7177181600]
DatabaseName: DemandScience by Pure Incubation
Id: IxLfwdMRkvXBjMmbeqpV
Email: [gplatt@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: []
HashType:
Name: []
Vin: []
Address: []
Phone: []
DatabaseName: Evite
Id: zBbozYMRs35batudWm6j
Email: [stiles@counseltrust.com]
IpAddress: []
Username: [df34221016bc31f1b86c14519]
Password: []
HashedPassword: []
HashType:
Name: [stiles@counseltrustcom]
Vin: []
Address: []
Phone: []
DatabaseName: ShareThis.com
Id: 37u0wdMRZd5-FWZiMghr
Email: [jyonkovitch@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: []
HashType:
Name: [JASON YONKOVITCH]
Vin: []
Address: [224 SAINT CHARLES WAY STE 100, YORK, PA, 17402, US]
Phone: [7177181611]
DatabaseName: DemandScience by Pure Incubation
Id: N0VExYMRkvXBjMmbnULI
Email: [stiles@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: []
HashType:
Name: []
Vin: []
Address: []
Phone: []
DatabaseName: Adobe
Id: 1_I0wNMRv-jq3VAHQBKZ
Email: [dwells@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: []
HashType:
Name: [David Wells]
Vin: []
Address: [PO BOX 993, MADISON, AL]
Phone: [7174656685]
DatabaseName: Luxottica
Id: TF69z5MRkvXBjMmbM3Mt
Email: [WCHILCOAT@COUNSELTRUST.COM]
IpAddress: []
Username: []
Password: []
HashedPassword: [*16CpSaOtR9Ew=:None||UNKNOWN]
HashType:
Name: [WANDA CHILCOAT]
Vin: []
Address: [2740 CLEARVIEW WAY, YORK, PA, 17403 2740 CLEARVIEW WAY YORK, PA, 17403]
Phone: [7177414611]
DatabaseName: AT&T
Id: uxOYwdMRZd5-FWZiD3PA
Email: [paul.stevenson@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [COUNSELTRUST.COM:None||Cisco-PIX(MD5)]
HashType:
Name: [PAUL STEVENSON]
Vin: []
Address: [224 ST CHARLES WAY SUITE 100, YORK, PA, 17402, US]
Phone: [7177181600]
DatabaseName: DemandScience by Pure Incubation
Id: SGGjwNMRbgUelnkGHZSP
Email: [david.dolan@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [counseltrust.com:None||Cisco-PIX(MD5) COUNSELTRUST.COM:None||Cisco-PIX(MD5)]
HashType:
Name: [DAVID DOLAN]
Vin: []
Address: [224 SAINT CHARLES WAY STE 100, YORK, PA, 17402-4665, US 224 St. Charles Way Suite 100, York, PA, 17402, US]
Phone: [7177181601]
DatabaseName: DemandScience by Pure Incubation
Id: o5ixwYMRv-jq3VAHfzI5
Email: [stiles@counseltrust.com]
IpAddress: []
Username: [http://www.linkedin.com/in/bonnie-stiles-6a75b69]
Password: []
HashedPassword: [counseltrust.com:None||Cisco-PIX(MD5)]
HashType:
Name: [Bonnie M. Stiles]
Vin: []
Address: [224 Saint Charles Way, York, PA, 17402, US]
Phone: [7177181601]
DatabaseName: DemandScience by Pure Incubation
Id: S37Qz5MRkvXBjMmbhwiO
Email: [stiles@counseltrust.com]
IpAddress: []
Username: []
Password: [stryker]
HashedPassword: [ebe73849058b47ae5eb163ecb134a4c4:||MD5 2cbf1f833918150abc54fa50c53dc8dbd0266a7e:||SHA1 09792abb14956e93ecf2a709affde76344ca3ed396e57ffcbf65436cce83fe3c:||SHA256 49301fa88e4fa3d5547c0074fdfd8f56c7e4468222fcfe181882a0c97970b9e79b8598ec13d7437791b5dfb201a1f9188a25dffeaf3ccb7342364cdc29f9317d:||SHA512 c3RyeWtlcg==:||BASE64]
HashType:
Name: []
Vin: []
Address: []
Phone: []
DatabaseName: trustupdates.com (Cit0day)
Id: Z8kqQdURkHaJUned-bBv
Email: [pstevenson@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [counseltrust.com:None||Cisco-PIX(MD5) COUNSELTRUST.COM:None||Cisco-PIX(MD5)]
HashType:
Name: [PAUL STEVENSON]
Vin: []
Address: [224 SAINT CHARLES WAY STE 100, YORK, PA, 17402-4665, US]
Phone: [7177181601]
DatabaseName: DemandScience by Pure Incubation
Id: YrsEwdMRs35batudzJVH
Email: [lkauffman@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: []
HashType:
Name: []
Vin: []
Address: []
Phone: []
DatabaseName: Evite
Id: QRFKzdMRs35batud9GZ5
Email: [DDOLAN@COUNSELTRUST.COM]
IpAddress: []
Username: []
Password: []
HashedPassword: [*0x7gMMV53xScLt+SqJEA1hw==:None||UNKNOWN *0+HSfRH0LZIc=:None||UNKNOWN]
HashType:
Name: [DAVID DOLAN]
Vin: []
Address: [3023 S ATLANTIC AV, DAYB SHR, FL, 32118 1330 HICKORY RUN DR, elizabethtown pa 17022-9202 ELIZABETHTOWN, PA, 17022]
Phone: [7178584702]
DatabaseName: AT&T
Id: AapPzdMRbgUelnkGzAZi
Email: [ecrooks@counseltrust.com]
IpAddress: []
Username: [edcrooks]
Password: []
HashedPassword: []
HashType:
Name: []
Vin: []
Address: []
Phone: []
DatabaseName: MyFitnessPal
Id: iPykdNMRZd5-FWZi6NTb
Email: [ddolan@counseltrust.com]
IpAddress: []
Username: []
Password: [5c480f68b]
HashedPassword: [35452b0e9763678ce20606aff52e399c:||MD5 ff7f60425e953d03e14024a7ed0a9f90bf2ea90e:||SHA1 0ba12cc8988083b4b1db7cecdb319bb6e6a01f19c383cfc01194ac79356e96ee:||SHA256 001ec68783cb044cc83a8d5f396916ff94a4550c37c056dbb0ee9dceede14736fccd39102575cf2f92d69c23822164b5644df77939b5364bae2e0f303c0ca5ce:||SHA512 NWM0ODBmNjhi:||BASE64]
HashType:
Name: []
Vin: []
Address: []
Phone: []
DatabaseName: Collections
Id: y6tqwdMRZd5-FWZiayk2
Email: [crooks@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [counseltrust.com:None||Cisco-PIX(MD5) COUNSELTRUST.COM:None||Cisco-PIX(MD5)]
HashType:
Name: [Brandon Crooks]
Vin: []
Address: [224 Saint Charles Way Ste 100, York, PA, 17402, US]
Phone: [7177181611]
DatabaseName: DemandScience by Pure Incubation
Id: iLTwwYMRbgUelnkGiiW6
Email: [paul@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [COUNSELTRUST.COM:None||Cisco-PIX(MD5)]
HashType:
Name: [PAUL STEVENSON]
Vin: []
Address: [224 ST CHARLES WAY SUITE 100, YORK, PA, 17402, US]
Phone: [7177181600]
DatabaseName: DemandScience by Pure Incubation
Id: mqOPwYMRv-jq3VAHGN4o
Email: [crooks@counseltrust.com]
IpAddress: []
Username: [https://www.linkedin.com/in/brandon-crooks-733a315/]
Password: []
HashedPassword: [counseltrust.com:None||Cisco-PIX(MD5)]
HashType:
Name: [Brandon Crooks]
Vin: []
Address: [224 Saint Charles Way Ste 100, York, PA, 17402, US]
Phone: [7177181611]
DatabaseName: DemandScience by Pure Incubation
Id: lZ0LwdMRbgUelnkGVn_G
Email: [ecrooks@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [counseltrust.com:None||Cisco-PIX(MD5)]
HashType:
Name: [EDWARD CROOKS]
Vin: []
Address: [224 SAINT CHARLES WAY, YORK, PA, 17402-4664, US]
Phone: [7177181601]
DatabaseName: DemandScience by Pure Incubation
Id: 5t5mwYMRiA0xW47jCGZa
Email: [ddolan@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [counseltrust.com:None||Cisco-PIX(MD5) COUNSELTRUST.COM:None||Cisco-PIX(MD5)]
HashType:
Name: [David Dolan]
Vin: []
Address: [224 Saint Charles Way, York, PA, 17402-4644, US]
Phone: [7177181601]
DatabaseName: DemandScience by Pure Incubation
Id: 877zwNMRbgUelnkG9SWf
Email: [pstevenson@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [$2y$10$/UdtWJ1fbpOa0yJMAyDzkeuBHktRBahxlNkwZ2zW11DQiawcc3O8G:None||Blowfish(OpenBSD)]
HashType:
Name: [PAUL STEVENSON]
Vin: []
Address: [224 SAINT CHARLES WAY STE 100, YORK, PA, 17402-4665, US]
Phone: [7177181601]
DatabaseName: DemandScience by Pure Incubation
Id: PF7owNMRs35batud-AC5
Email: [stiles@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [counseltrust.com:None||Cisco-PIX(MD5) COUNSELTRUST.COM:None||Cisco-PIX(MD5)]
HashType:
Name: [Bonnie M. Stiles]
Vin: []
Address: [224 Saint Charles Way, York, PA, 17402, US]
Phone: [7177181601]
DatabaseName: DemandScience by Pure Incubation
Id: g1K4wdMRbgUelnkGiwtt
Email: [dolan@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [COUNSELTRUST.COM:None||Cisco-PIX(MD5)]
HashType:
Name: [DAVID DOLAN]
Vin: []
Address: [224 SCHARLES WY, YORK, PA, 17402, US]
Phone: [7177181601]
DatabaseName: DemandScience by Pure Incubation
Id: 5uGAzYMRiA0xW47jZ0SG
Email: [gplatt@counseltrust.com]
IpAddress: []
Username: [871fc67187061029d70c29640]
Password: []
HashedPassword: []
HashType:
Name: [gplatt@counseltrustcom]
Vin: []
Address: []
Phone: []
DatabaseName: ShareThis.com
Id: vfJvwYMRiA0xW47jrHLh
Email: [onnie@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [COUNSELTRUST.COM:None||Cisco-PIX(MD5)]
HashType:
Name: [BONNIE STILES]
Vin: []
Address: [224 ST CHARLES WAY SUITE 100, YORK, PA, 17402, US]
Phone: [7177181600]
DatabaseName: DemandScience by Pure Incubation
Id: GHKcwdMRbgUelnkGrEIP
Email: [onnie.stiles@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [COUNSELTRUST.COM:None||Cisco-PIX(MD5)]
HashType:
Name: [BONNIE STILES]
Vin: []
Address: [224 ST CHARLES WAY SUITE 100, YORK, PA, 17402, US]
Phone: [7177181600]
DatabaseName: DemandScience by Pure Incubation
Id: W56-x5MRv-jq3VAHVOq9
Email: [stiles@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: []
HashType:
Name: []
Vin: []
Address: []
Phone: []
DatabaseName: LinkedIn
Id: DuS0wYMRbgUelnkG2EyB
Email: [gplatt@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [$2a$05$b8axmc6a1T7pXoZXGq/KR.OGSSM.swfjqCMNRbGsIjL5is6stNX5S:None||Blowfish(OpenBSD)]
HashType:
Name: []
Vin: []
Address: []
Phone: []
DatabaseName: ParkMobile
Id: 11M_wYMRs35batud_mIn
Email: [pstevenson@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: []
HashType:
Name: []
Vin: []
Address: []
Phone: []
DatabaseName: LinkedIn
Id: QooWwdMRv-jq3VAH6-uY
Email: [gplatt@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: []
HashType:
Name: [GEOFFREY PLATT]
Vin: []
Address: [224 SAINT CHARLES WAY STE 100, YORK, PA, 17402, US]
Phone: [7177181611]
DatabaseName: DemandScience by Pure Incubation
Id: AItfnYMRv-jq3VAHEtYB
Email: [dwells@counseltrust.com]
IpAddress: []
Username: []
Password: []
HashedPassword: [19a673bd64ef80608f70626c1441d578:None||MD5]
HashType:
Name: []
Vin: []
Address: [NU]
Phone: []
DatabaseName: Chegg