package cmd import ( "encoding/json" "fmt" "git.db.org.ai/dborg/internal/client" "git.db.org.ai/dborg/internal/config" "git.db.org.ai/dborg/internal/models" "git.db.org.ai/dborg/internal/utils" "github.com/spf13/cobra" ) var usernameCmd = &cobra.Command{ Use: "username [username]", Short: "Check username availability across websites", Long: `Check username availability across hundreds of websites using WhatsMyName dataset`, Args: cobra.ExactArgs(1), RunE: runUsernameCheck, } var bssidCmd = &cobra.Command{ Use: "bssid [bssid]", Short: "Lookup WiFi access point location by BSSID", Long: `Lookup geographic location of a WiFi access point by its BSSID (MAC address) using Apple's location services`, Args: cobra.ExactArgs(1), RunE: runBSSIDLookup, } var breachforumCmd = &cobra.Command{ Use: "breachforum [search]", Short: "Search BreachForum data", Long: `Search breachdetect index for BreachForum messages and detections`, Args: cobra.ExactArgs(1), RunE: runBreachForumSearch, } var filesCmd = &cobra.Command{ Use: "files [url]", Short: "Search open directory files", Long: `Search for files in open directories using various filters (free OSINT endpoint)`, Args: cobra.ExactArgs(1), RunE: runFilesSearch, } var bucketsCmd = &cobra.Command{ Use: "buckets", Short: "List public buckets", Long: `List public S3, Azure, GCP, and DigitalOcean buckets with file counts`, RunE: runBucketsSearch, } var bucketFilesCmd = &cobra.Command{ Use: "bucket-files", Short: "Search public bucket files", Long: `Search public S3, Azure, GCP, and DigitalOcean buckets for exposed files`, RunE: runBucketFilesSearch, } var shortlinksCmd = &cobra.Command{ Use: "shortlinks", Short: "Search brute forced short links", Long: `Search for exposed URLs discovered through brute forcing URL shortener services`, RunE: runShortlinksSearch, } var geoCmd = &cobra.Command{ Use: "geo", Short: "Search for address information", Long: `Returns address information including residents, property details, and demographics (costs 1 credit)`, RunE: runGeoSearch, } var crawlCmd = &cobra.Command{ Use: "crawl [domain]", Short: "Crawl domain", Long: `Resolves a domain using httpx and crawls it using katana. Returns discovered links as plain text, one per line, streamed in real-time. Supports both http:// and https:// URLs.`, Args: cobra.ExactArgs(1), RunE: runCrawl, } func init() { rootCmd.AddCommand(usernameCmd) rootCmd.AddCommand(bssidCmd) rootCmd.AddCommand(breachforumCmd) rootCmd.AddCommand(filesCmd) rootCmd.AddCommand(bucketsCmd) rootCmd.AddCommand(bucketFilesCmd) rootCmd.AddCommand(shortlinksCmd) rootCmd.AddCommand(geoCmd) rootCmd.AddCommand(crawlCmd) usernameCmd.Flags().StringSliceP("sites", "s", []string{}, "Specific sites to check (comma-separated)") usernameCmd.Flags().BoolP("fuzzy", "f", false, "Enable fuzzy validation mode") usernameCmd.Flags().IntP("max_tasks", "m", 50, "Maximum concurrent tasks") bssidCmd.Flags().BoolP("all", "a", false, "Show all related results instead of exact match only") bssidCmd.Flags().BoolP("google", "g", false, "Include Google Maps URL for the location") bssidCmd.Flags().BoolP("osm", "o", false, "Include OpenStreetMap URL for the location") breachforumCmd.Flags().IntP("max_hits", "m", 10, "Maximum number of hits to return") filesCmd.Flags().StringP("filename", "n", "", "Search term to match in filenames") filesCmd.Flags().StringP("extension", "e", "", "Filter by file extension(s) - comma-separated (e.g., pdf,doc,txt)") filesCmd.Flags().StringP("exclude", "x", "html,HTML", "Exclude file extension(s) - comma-separated") filesCmd.Flags().IntP("size", "s", 10, "Number of results to return (max 40)") filesCmd.Flags().IntP("from", "f", 0, "Starting offset for pagination") bucketsCmd.Flags().IntP("limit", "l", 1000, "Number of results to return") bucketsCmd.Flags().IntP("start", "t", 0, "Starting offset for pagination") bucketFilesCmd.Flags().StringP("keywords", "w", "", "Search keywords") bucketFilesCmd.Flags().StringP("extensions", "e", "", "File extensions (comma-separated, e.g. 'sql,db,xlsx')") bucketFilesCmd.Flags().StringP("buckets", "b", "", "Filter by bucket names (comma-separated)") bucketFilesCmd.Flags().IntP("limit", "l", 1000, "Number of results to return") bucketFilesCmd.Flags().IntP("start", "t", 0, "Starting offset for pagination") shortlinksCmd.Flags().StringP("keywords", "w", "", "Search keywords") shortlinksCmd.Flags().StringP("ext", "e", "", "File extensions (comma-separated, e.g. 'pdf,docx,xlsx')") shortlinksCmd.Flags().StringP("order", "o", "", "Sort by property (size, timestamp)") shortlinksCmd.Flags().StringP("direction", "d", "", "Sort direction (asc, desc)") shortlinksCmd.Flags().BoolP("regexp", "r", false, "Treat keywords as regular expression") shortlinksCmd.Flags().IntP("limit", "l", 100, "Number of results to return") shortlinksCmd.Flags().IntP("start", "t", 0, "Starting offset for pagination") geoCmd.Flags().StringP("street", "s", "", "Street address") geoCmd.Flags().StringP("city", "c", "", "City") geoCmd.Flags().StringP("state", "t", "", "State (2-letter code)") geoCmd.Flags().StringP("zip", "z", "", "ZIP code") geoCmd.MarkFlagRequired("street") geoCmd.MarkFlagRequired("city") geoCmd.MarkFlagRequired("state") geoCmd.MarkFlagRequired("zip") } func runUsernameCheck(cmd *cobra.Command, args []string) error { cfg := config.New() c, err := client.NewUnauthenticated(cfg) if err != nil { return err } params := &models.USRSXParams{ Username: args[0], } params.Sites, _ = cmd.Flags().GetStringSlice("sites") params.Fuzzy, _ = cmd.Flags().GetBool("fuzzy") params.MaxTasks, _ = cmd.Flags().GetInt("max_tasks") err = c.CheckUsernameStream(params, func(result json.RawMessage) error { fmt.Println(string(result)) return nil }) if err != nil { return err } return nil } func runBSSIDLookup(cmd *cobra.Command, args []string) error { cfg := config.New() c, err := client.NewUnauthenticated(cfg) if err != nil { return err } params := &models.BSSIDParams{ BSSID: args[0], } params.All, _ = cmd.Flags().GetBool("all") params.Google, _ = cmd.Flags().GetBool("google") params.OSM, _ = cmd.Flags().GetBool("osm") response, err := c.LookupBSSID(params) if err != nil { return err } return utils.PrintJSON(response) } func runBreachForumSearch(cmd *cobra.Command, args []string) error { cfg := config.New() c, err := client.NewUnauthenticated(cfg) if err != nil { return err } params := &models.BreachForumSearchParams{ Search: args[0], } params.MaxHits, _ = cmd.Flags().GetInt("max_hits") response, err := c.SearchBreachForum(params) if err != nil { return err } return utils.PrintJSON(response) } func runFilesSearch(cmd *cobra.Command, args []string) error { cfg := config.New() c, err := client.NewUnauthenticated(cfg) if err != nil { return err } params := &models.OpenDirectorySearchParams{ URL: args[0], } params.Filename, _ = cmd.Flags().GetString("filename") params.Extension, _ = cmd.Flags().GetString("extension") params.Exclude, _ = cmd.Flags().GetString("exclude") params.Size, _ = cmd.Flags().GetInt("size") params.From, _ = cmd.Flags().GetInt("from") response, err := c.SearchOpenDirectoryFiles(params) if err != nil { return err } return utils.PrintJSON(response) } func runBucketsSearch(cmd *cobra.Command, args []string) error { cfg := config.New() c, err := client.New(cfg) if err != nil { return err } params := &models.BucketsSearchParams{} params.Limit, _ = cmd.Flags().GetInt("limit") params.Start, _ = cmd.Flags().GetInt("start") response, err := c.SearchBuckets(params) if err != nil { return err } return utils.PrintJSON(response) } func runBucketFilesSearch(cmd *cobra.Command, args []string) error { cfg := config.New() c, err := client.New(cfg) if err != nil { return err } params := &models.BucketsFilesSearchParams{} params.Keywords, _ = cmd.Flags().GetString("keywords") params.Extensions, _ = cmd.Flags().GetString("extensions") params.Buckets, _ = cmd.Flags().GetString("buckets") params.Limit, _ = cmd.Flags().GetInt("limit") params.Start, _ = cmd.Flags().GetInt("start") response, err := c.SearchBucketFiles(params) if err != nil { return err } return utils.PrintJSON(response) } func runShortlinksSearch(cmd *cobra.Command, args []string) error { cfg := config.New() c, err := client.New(cfg) if err != nil { return err } params := &models.ShortlinksSearchParams{} params.Keywords, _ = cmd.Flags().GetString("keywords") params.Ext, _ = cmd.Flags().GetString("ext") params.Order, _ = cmd.Flags().GetString("order") params.Direction, _ = cmd.Flags().GetString("direction") params.Regexp, _ = cmd.Flags().GetBool("regexp") params.Limit, _ = cmd.Flags().GetInt("limit") params.Start, _ = cmd.Flags().GetInt("start") response, err := c.SearchShortlinks(params) if err != nil { return err } return utils.PrintJSON(response) } func runGeoSearch(cmd *cobra.Command, args []string) error { cfg := config.New() c, err := client.New(cfg) if err != nil { return err } params := &models.GeoSearchParams{} params.Street, _ = cmd.Flags().GetString("street") params.City, _ = cmd.Flags().GetString("city") params.State, _ = cmd.Flags().GetString("state") params.Zip, _ = cmd.Flags().GetString("zip") response, err := c.SearchGeo(params) if err != nil { return err } return utils.PrintJSON(response) } func runCrawl(cmd *cobra.Command, args []string) error { cfg := config.New() c, err := client.NewUnauthenticated(cfg) if err != nil { return err } err = c.CrawlDomain(args[0], func(line string) error { fmt.Println(line) return nil }) if err != nil { return err } return nil }