diff --git a/cmd/db.go b/cmd/db.go index d8361c9..3c9abe2 100644 --- a/cmd/db.go +++ b/cmd/db.go @@ -1,656 +1,218 @@ 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" + "os" "strings" - "time" ) var ( - // DB command flags - dbPath string + dbQueryTableName string + dbQueryLimitRows int + dbQueryNotNull string + dbQueryColumns string + dbQueryUserQuery string + dbQueryRawQuery string + dbQueryListAll bool - // 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{ + databaseQueryCmd = &cobra.Command{ Use: "db", - Short: "Database operations for Dehasher", - Long: `Perform database operations like export, import, and query on the local Dehasher database.`, + Short: "Query the database", + Long: `Query the database for various information.`, + Run: func(cmd *cobra.Command, args []string) { + // If Raw Query is set, execute it and return + if dbQueryRawQuery != "" { + fmt.Println("[*] Executing Raw Query...") + rawDBQuery() + os.Exit(1) + } + + // Determine which table to query based on the tableTypeDBQuery parameter + table := GetTable(dbQueryTableName) + if table == UnknownTable { + fmt.Printf("Error: Unknown table type '%s'.\n", dbQueryTableName) + cmd.Help() + return + } + fmt.Println("[*] Querying Database...") + tableQuery(table) + }, } ) func init() { - // Add subcommands to db command - dbCmd.AddCommand(dbExportCmd) - dbCmd.AddCommand(dbQueryCmd) - dbCmd.AddCommand(dbRunsCmd) - dbCmd.AddCommand(dbCredsCmd) + // Add whois command to root command + rootCmd.AddCommand(databaseQueryCmd) - // 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 whois command + databaseQueryCmd.Flags().StringVarP(&dbQueryTableName, "table", "t", "", "Table to query (results, creds, whois, subdomains, history, query_options)") + databaseQueryCmd.Flags().IntVarP(&dbQueryLimitRows, "limit", "l", 100, "Limit number of results") + databaseQueryCmd.Flags().StringVarP(&dbQueryNotNull, "not-null", "n", "", "Filter for non-null values (comma-separated list, e.g., 'password,email')") + databaseQueryCmd.Flags().StringVarP(&dbQueryColumns, "columns", "c", "", "Columns to display in output (comma-separated list, e.g., 'username,email,password')") + databaseQueryCmd.Flags().StringVarP(&dbQueryUserQuery, "query", "q", "", "User query to execute") + databaseQueryCmd.Flags().StringVarP(&dbQueryRawQuery, "raw-query", "r", "", "Raw SQL query to execute") + databaseQueryCmd.Flags().BoolVarP(&dbQueryListAll, "list-all", "a", false, "List all columns") - // 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')") + // Add mutually exclusive flags to query and raw-query + // Cannot use query and raw-query at the same time + databaseQueryCmd.MarkFlagsMutuallyExclusive("query", "raw-query") + // Raw query does not require a table + databaseQueryCmd.MarkFlagsMutuallyExclusive("query", "table") + // List all columns does not require a query or raw-query + databaseQueryCmd.MarkFlagsMutuallyExclusive("raw-query", "list-all") } -// 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, +func tableQuery(table Table) { + + // Get the columns to query + columns := []string{"*"} + if dbQueryColumns != "" { + columns = strings.Split(dbQueryColumns, ",") + } + + // Get the not null fields + notNullFields := []string{} + if dbQueryNotNull != "" { + notNullFields = strings.Split(dbQueryNotNull, ",") + } + + // Get the user query + userQuery := "" + if dbQueryUserQuery != "" { + userQuery = dbQueryUserQuery + } + + // Get the limit + limit := dbQueryLimitRows + + // Get the object for the table + object := table.Object() + + // Query the database + db := sqlite.GetDB() + query := db.Model(object).Select(columns) + if len(notNullFields) > 0 { + for _, field := range notNullFields { + query = query.Where(fmt.Sprintf("%s IS NOT NULL", field)) } + } + if userQuery != "" { + query = query.Where(userQuery) + } + if limit > 0 { + query = query.Limit(limit) + } + rows, err := query.Rows() + if err != nil { + zap.L().Error("db_query", + zap.String("message", "failed to execute query"), + zap.Error(err), + ) + fmt.Printf("[!] Error executing query: %v\n", err) + } + defer rows.Close() - // Parse non-empty fields if provided - if nonEmptyFieldsDBQuery != "" { - options.NonEmptyFields = strings.Split(nonEmptyFieldsDBQuery, ",") + // Get the columns + cols, err := rows.Columns() + if err != nil { + zap.L().Error("db_query", + zap.String("message", "failed to get columns from query"), + zap.Error(err), + ) + fmt.Printf("[!] Error getting columns from query: %v\n", err) + } + + // Prepare data for pretty.Table + headers := cols + var tableRows [][]string + + // Process the rows + for rows.Next() { + values := make([]interface{}, len(cols)) + pointers := make([]interface{}, len(cols)) + for i := range values { + pointers[i] = &values[i] } - - // 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"), + if err := rows.Scan(pointers...); err != nil { + zap.L().Error("db_query", + zap.String("message", "failed to scan row from query"), 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), - } + fmt.Printf("[!] Error scanning row from query: %v\n", err) } - 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) - } - } + // Convert row values to strings + rowStrings := make([]string, len(values)) + for i, value := range values { + if value == nil { + rowStrings[i] = " " } 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) + rowStrings[i] = fmt.Sprintf("%v", value) } - fmt.Println() } + tableRows = append(tableRows, rowStrings) } + + // Display the table + pretty.Table(headers, tableRows) } -// 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) +func rawDBQuery() { + db := sqlite.GetDB() + rows, err := db.Raw(dbQueryRawQuery).Rows() if err != nil { - fmt.Printf("Error counting credentials: %v\n", err) - return + zap.L().Error("raw_query", + zap.String("message", "failed to execute raw query"), + zap.Error(err), + ) + fmt.Printf("[!] Error executing raw query: %v\n", err) } + defer rows.Close() - // Query the database - creds, err := sqlite.QueryCreds(options) + columns, err := rows.Columns() if err != nil { - fmt.Printf("Error querying credentials: %v\n", err) - return + zap.L().Error("raw_query", + zap.String("message", "failed to get columns from raw query"), + zap.Error(err), + ) + fmt.Printf("[!] Error getting columns from raw query: %v\n", err) } - // 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() - } - } + // Prepare data for pretty.Table + headers := columns + var tableRows [][]string + + // Process the rows + for rows.Next() { + values := make([]interface{}, len(columns)) + pointers := make([]interface{}, len(columns)) + for i := range values { + pointers[i] = &values[i] + } + if err := rows.Scan(pointers...); err != nil { + zap.L().Error("raw_query", + zap.String("message", "failed to scan row from raw query"), + zap.Error(err), + ) + fmt.Printf("[!] Error scanning row from raw query: %v\n", err) + } + + // Convert row values to strings + rowStrings := make([]string, len(values)) + for i, value := range values { + if value == nil { + rowStrings[i] = " " + } else { + rowStrings[i] = fmt.Sprintf("%v", value) + } + } + tableRows = append(tableRows, rowStrings) + } + + // Display the table + pretty.Table(headers, tableRows) } diff --git a/cmd/export.go b/cmd/export.go new file mode 100644 index 0000000..bef66e5 --- /dev/null +++ b/cmd/export.go @@ -0,0 +1,46 @@ +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" +) + +func init() { + // Add Subcommand to db command + rootCmd.AddCommand(exportCmd) + +} + +// DB export command +var ( + exportLimitRows int + exportListAll bool + exportTableName string + exportNotNull string + exportColumns string + exportUserQuery string + exportRawQuery string + exportFormat string + exportFile string + + exportCmd = &cobra.Command{ + Use: "export", + Short: "Export database to file", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("Exporting database...") + }, + } +) + +func init() { + // Add flags specific to export command + exportCmd.Flags().IntVarP(&exportLimitRows, "limit", "l", 100, "Limit number of results") + exportCmd.Flags().BoolVarP(&exportListAll, "list-all", "a", false, "List all columns") + exportCmd.Flags().StringVarP(&exportTableName, "table", "t", "", "Table to export") + exportCmd.Flags().StringVarP(&exportNotNull, "not-null", "n", "", "Filter for non-null values (comma-separated list, e.g., 'password,email')") + exportCmd.Flags().StringVarP(&exportColumns, "columns", "c", "", "Columns to display in output (comma-separated list, e.g., 'username,email,password')") + exportCmd.Flags().StringVarP(&exportUserQuery, "query", "q", "", "User query to execute") + exportCmd.Flags().StringVarP(&exportRawQuery, "raw-query", "r", "", "Raw SQL query to execute") + exportCmd.Flags().StringVarP(&exportFormat, "format", "f", "json", "Output format (json, yaml, xml, txt)") + exportCmd.Flags().StringVarP(&exportFile, "file", "o", "export", "File to output results to including extension") +} diff --git a/cmd/helpers.go b/cmd/helpers.go new file mode 100644 index 0000000..6b7075c --- /dev/null +++ b/cmd/helpers.go @@ -0,0 +1,56 @@ +package cmd + +import ( + "dehasher/internal/sqlite" + "strings" +) + +type Table int64 + +const ( + ResultsTable Table = iota + RunsTable + CredsTable + WhoIsTable + SubdomainsTable + HistoryTable + UnknownTable +) + +func GetTable(userInput string) Table { + switch strings.ToLower(userInput) { + case "results": + return ResultsTable + case "runs": + return RunsTable + case "creds": + return CredsTable + case "whois": + return WhoIsTable + case "subdomains": + return SubdomainsTable + case "history": + return HistoryTable + default: + return UnknownTable + } +} + +func (t Table) Object() interface{} { + switch t { + case ResultsTable: + return sqlite.Result{} + case RunsTable: + return sqlite.QueryOptions{} + case CredsTable: + return sqlite.Creds{} + case WhoIsTable: + return sqlite.WhoisRecord{} + case SubdomainsTable: + return sqlite.SubdomainRecord{} + case HistoryTable: + return sqlite.HistoryRecord{} + default: + return nil + } +} diff --git a/cmd/query.go b/cmd/query.go index cd9860e..0e8eaaa 100644 --- a/cmd/query.go +++ b/cmd/query.go @@ -39,21 +39,11 @@ var ( 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() - } + key := getStoredApiKey() // 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.") + if key == "" { + fmt.Println("API key is required. Set the key with the \"set-key\" command. [dehasher set-key ]") return } @@ -99,6 +89,9 @@ var ( ) func init() { + // Add query command to root command + rootCmd.AddCommand(queryCmd) + // 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") @@ -131,7 +124,3 @@ func init() { func getStoredApiKey() string { return badger.GetKey() } - -func getStoredApiEmail() string { - return badger.GetEmail() -} diff --git a/cmd/root.go b/cmd/root.go index e651346..a7ba62c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -10,8 +10,7 @@ import ( var ( // Global Flags - apiKey string - apiEmail string + alternativeDatabase string // rootCmd is the base command for the CLI. rootCmd = &cobra.Command{ @@ -62,14 +61,11 @@ 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 global flags + rootCmd.PersistentFlags().StringVar(&alternativeDatabase, "alt-db", "", "Alternative database path") // Add subcommands - rootCmd.AddCommand(dbCmd) - rootCmd.AddCommand(queryCmd) rootCmd.AddCommand(setKeyCmd) - rootCmd.AddCommand(setEmailCmd) } // Command to set API key @@ -89,23 +85,6 @@ var setKeyCmd = &cobra.Command{ }, } -// 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) @@ -115,12 +94,3 @@ func storeApiKey(key string) error { } 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 -} diff --git a/cmd/whois.go b/cmd/whois.go index ef58098..fa0107c 100644 --- a/cmd/whois.go +++ b/cmd/whois.go @@ -29,17 +29,11 @@ var ( 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() - } + key := getStoredApiKey() // Validate credentials if key == "" { - fmt.Println("API key is required. Use --key flag or set it with set-key command.") + fmt.Println("API key is required. Set the key with the \"set-key\" command. [dehasher set-key ]") return } @@ -80,7 +74,7 @@ var ( 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) @@ -297,7 +291,4 @@ func init() { 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") } diff --git a/counseltrust.txt b/counseltrust.txt deleted file mode 100644 index 6430328..0000000 --- a/counseltrust.txt +++ /dev/null @@ -1,235 +0,0 @@ -[*] 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} diff --git a/counseltrust2.txt b/counseltrust2.txt deleted file mode 100644 index 4efe188..0000000 --- a/counseltrust2.txt +++ /dev/null @@ -1,241 +0,0 @@ -[*] 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 diff --git a/dehasher b/dehasher deleted file mode 100755 index 4490642..0000000 Binary files a/dehasher and /dev/null differ diff --git a/go.mod b/go.mod index fa96d9c..76e44e5 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ toolchain go1.24.3 require ( github.com/charmbracelet/lipgloss v1.1.0 github.com/dgraph-io/badger/v4 v4.7.0 + github.com/olekukonko/tablewriter v1.0.5 github.com/spf13/cobra v1.9.1 github.com/winking324/rzap v0.1.0 go.uber.org/zap v1.20.0 @@ -26,6 +27,7 @@ require ( 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/fatih/color v1.15.0 // 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 @@ -34,10 +36,13 @@ require ( 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-colorable v0.1.13 // 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/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 // indirect + github.com/olekukonko/ll v0.0.7 // 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 diff --git a/go.sum b/go.sum index d1c0bf1..4ae6881 100644 --- a/go.sum +++ b/go.sum @@ -32,6 +32,8 @@ github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa5 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/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= 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= @@ -58,6 +60,9 @@ 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-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 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= @@ -66,6 +71,12 @@ github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o 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/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 h1:r3FaAI0NZK3hSmtTDrBVREhKULp8oUeqLT5Eyl2mSPo= +github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y= +github.com/olekukonko/ll v0.0.7 h1:K66xcUlG2qWRhPoLw/cidmbv4pDDJtZuvJGsR5QTzXo= +github.com/olekukonko/ll v0.0.7/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g= +github.com/olekukonko/tablewriter v1.0.5 h1:8+uKJXxYcl29TcpfQdd0vL+l6Kul7Sk7sWolfgErDv0= +github.com/olekukonko/tablewriter v1.0.5/go.mod h1:Z22i2ywMkT9sw64nuWAUaH62kb+umiwucGaQNbFh8Bg= 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= @@ -125,6 +136,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w 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.0.0-20220811171246-fbc7d0a398ab/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= diff --git a/internal/sqlite/result.go b/internal/sqlite/result.go index d31817b..1802c9c 100644 --- a/internal/sqlite/result.go +++ b/internal/sqlite/result.go @@ -38,6 +38,10 @@ type Result struct { DatabaseName string `json:"database_name,omitempty" xml:"database_name,omitempty" yaml:"database_name,omitempty"` } +func (Result) TableName() string { + return "results" +} + type DehashedResults struct { Results []Result `json:"results"` } diff --git a/internal/sqlite/structs.go b/internal/sqlite/structs.go index 4650da2..43e4088 100644 --- a/internal/sqlite/structs.go +++ b/internal/sqlite/structs.go @@ -69,6 +69,10 @@ type QueryOptions struct { CredsOnly bool `json:"creds_only"` } +func (QueryOptions) TableName() string { + return "query_options" +} + 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, @@ -103,6 +107,10 @@ type Creds struct { Password string `json:"password" yaml:"password" xml:"password"` } +func (Creds) TableName() string { + return "creds" +} + func (c Creds) ToString() string { return fmt.Sprintf("%s%s%s", c.Username, "%", c.Password) } diff --git a/internal/sqlite/whois.go b/internal/sqlite/whois.go index 84d6afa..eacb9f6 100644 --- a/internal/sqlite/whois.go +++ b/internal/sqlite/whois.go @@ -38,6 +38,10 @@ type WhoisRecord struct { UpdatedDateNormalized string `json:"updatedDateNormalized"` } +func (WhoisRecord) TableName() string { + return "whois" +} + type Audit struct { CreatedDate string `json:"createdDate"` UpdatedDate string `json:"updatedDate"` @@ -105,6 +109,10 @@ type SubdomainRecord struct { LastSeen int64 `json:"lastSeen"` } +func (SubdomainRecord) TableName() string { + return "subdomains" +} + type WhoIsHistory struct { RemainingCredits int `json:"remaining_credits"` Data HistoryData `json:"data"` @@ -139,6 +147,10 @@ type HistoryRecord struct { ZoneContact ContactInfo `json:"zoneContact" gorm:"serializer:json"` } +func (HistoryRecord) TableName() string { + return "history" +} + type ContactInfo struct { City string `json:"city"` Country string `json:"country"` diff --git a/ondefend.txt b/ondefend.txt deleted file mode 100644 index b065cfe..0000000 --- a/ondefend.txt +++ /dev/null @@ -1,455 +0,0 @@ -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 -