diff --git a/README.md b/README.md index 632df26a..8bfd9ff9 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,19 @@ Interactsh Cli client requires **go1.20+** to install successfully. Run the foll go install -v github.com/projectdiscovery/interactsh/cmd/interactsh-client@latest ``` +### Configure PDCP_API_KEY With Interactsh CLI Client +> Get your free api key by signing up at https://cloud.projectdiscovery.io + +You can configure your PDCP_API_KEY in two ways: +1. To configure the API key interactively, run the following command: + ```sh + ./interactsh-client -auth + ``` +2. If you prefer to pass the API key directly, use the -auth option followed by your API key: + ```sh + ./interactsh-client -auth= + ```` + ### Default Run This will generate a unique payload that can be used for OOB testing with minimal interaction information in the output. diff --git a/cmd/interactsh-client/main.go b/cmd/interactsh-client/main.go index 699e4416..905d017f 100644 --- a/cmd/interactsh-client/main.go +++ b/cmd/interactsh-client/main.go @@ -11,6 +11,7 @@ import ( "time" jsoniter "github.com/json-iterator/go" + asnmap "github.com/projectdiscovery/asnmap/libs" "github.com/projectdiscovery/goflags" "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/gologger/levels" @@ -19,6 +20,8 @@ import ( "github.com/projectdiscovery/interactsh/pkg/options" "github.com/projectdiscovery/interactsh/pkg/server" "github.com/projectdiscovery/interactsh/pkg/settings" + "github.com/projectdiscovery/utils/auth/pdcp" + "github.com/projectdiscovery/utils/env" fileutil "github.com/projectdiscovery/utils/file" folderutil "github.com/projectdiscovery/utils/folder" updateutils "github.com/projectdiscovery/utils/update" @@ -44,6 +47,7 @@ func main() { flagSet.CreateGroup("config", "config", flagSet.StringVar(&cliOptions.Config, "config", defaultConfigLocation, "flag configuration file"), + flagSet.DynamicVar(&cliOptions.PdcpAuth, "auth", "true", "configure projectdiscovery cloud (pdcp) api key"), flagSet.IntVarP(&cliOptions.NumberOfPayloads, "number", "n", 1, "number of interactsh payload to generate"), flagSet.StringVarP(&cliOptions.Token, "token", "t", "", "authentication token to connect protected interactsh server"), flagSet.IntVarP(&cliOptions.PollInterval, "poll-interval", "pi", 5, "poll interval in seconds to pull interaction data"), @@ -86,7 +90,27 @@ func main() { gologger.Fatal().Msgf("Could not parse options: %s\n", err) } - options.ShowBanner() + // If user have passed auth flag without key (ex: interactsh-client -auth) + // then we will prompt user to enter the api key, if already set shows user identity and exit + // If user have passed auth flag with key (ex: interactsh-client -auth=) + // then we will validate the key and save it to file + if cliOptions.PdcpAuth == "true" { + options.AuthWithPDCP() + } else if len(cliOptions.PdcpAuth) == 36 { + ph := pdcp.PDCPCredHandler{} + if _, err := ph.GetCreds(); err == pdcp.ErrNoCreds { + apiServer := env.GetEnvOrDefault("PDCP_API_SERVER", pdcp.DefaultApiServer) + if validatedCreds, err := ph.ValidateAPIKey(cliOptions.PdcpAuth, apiServer, "interactsh"); err == nil { + options.ShowBanner() + asnmap.PDCPApiKey = validatedCreds.APIKey + if err = ph.SaveCreds(validatedCreds); err != nil { + gologger.Warning().Msgf("Could not save credentials to file: %s\n", err) + } + } + } + } else { + options.ShowBanner() + } if healthcheck { cfgFilePath, _ := flagSet.GetConfigFilePath() diff --git a/pkg/options/client_options.go b/pkg/options/client_options.go index 836e94be..835380ec 100644 --- a/pkg/options/client_options.go +++ b/pkg/options/client_options.go @@ -30,4 +30,5 @@ type CLIClientOptions struct { Asn bool DisableUpdateCheck bool KeepAliveInterval time.Duration + PdcpAuth string } diff --git a/pkg/options/utils.go b/pkg/options/utils.go index d28a6743..c82f8b54 100644 --- a/pkg/options/utils.go +++ b/pkg/options/utils.go @@ -2,6 +2,7 @@ package options import ( "github.com/projectdiscovery/gologger" + "github.com/projectdiscovery/utils/auth/pdcp" updateutils "github.com/projectdiscovery/utils/update" ) @@ -27,3 +28,9 @@ func GetUpdateCallback(assetName string) func() { updateutils.GetUpdateToolFromRepoCallback(assetName, Version, "interactsh")() } } + +// AuthWithPDCP is used to authenticate with PDCP +func AuthWithPDCP() { + ShowBanner() + pdcp.CheckNValidateCredentials("interactsh") +}