feat: upload existing scan results (#5603)

* feat: upload existing scan results

* fix lint test

* misc update

---------

Co-authored-by: sandeep <8293321+ehsandeep@users.noreply.github.com>
This commit is contained in:
Ramana Reddy 2024-09-12 16:13:49 +05:30 committed by GitHub
parent 8b1d9aa0d7
commit bd6330f72a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 1 deletions

View File

@ -123,6 +123,13 @@ func main() {
runner.ParseOptions(options) runner.ParseOptions(options)
if options.ScanUploadFile != "" {
if err := runner.UploadResultsToCloud(options); err != nil {
gologger.Fatal().Msgf("could not upload scan results to cloud dashboard: %s\n", err)
}
return
}
nucleiRunner, err := runner.New(options) nucleiRunner, err := runner.New(options)
if err != nil { if err != nil {
gologger.Fatal().Msgf("Could not create runner: %s\n", err) gologger.Fatal().Msgf("Could not create runner: %s\n", err)
@ -420,9 +427,11 @@ on extensive configurability, massive extensibility and ease of use.`)
flagSet.CreateGroup("cloud", "Cloud", flagSet.CreateGroup("cloud", "Cloud",
flagSet.DynamicVar(&pdcpauth, "auth", "true", "configure projectdiscovery cloud (pdcp) api key"), flagSet.DynamicVar(&pdcpauth, "auth", "true", "configure projectdiscovery cloud (pdcp) api key"),
flagSet.StringVarP(&options.TeamID, "team-id", "tid", _pdcp.TeamIDEnv, "upload scan results to given team id (optional)"), flagSet.StringVarP(&options.TeamID, "team-id", "tid", _pdcp.TeamIDEnv, "upload scan results to given team id (optional)"),
flagSet.BoolVarP(&options.EnableCloudUpload, "cloud-upload", "cup", false, "upload scan results to pdcp dashboard"), flagSet.BoolVarP(&options.EnableCloudUpload, "cloud-upload", "cup", false, "upload scan results to pdcp dashboard [DEPRECATED use -dashboard]"),
flagSet.StringVarP(&options.ScanID, "scan-id", "sid", "", "upload scan results to existing scan id (optional)"), flagSet.StringVarP(&options.ScanID, "scan-id", "sid", "", "upload scan results to existing scan id (optional)"),
flagSet.StringVarP(&options.ScanName, "scan-name", "sname", "", "scan name to set (optional)"), flagSet.StringVarP(&options.ScanName, "scan-name", "sname", "", "scan name to set (optional)"),
flagSet.BoolVarP(&options.EnableCloudUpload, "dashboard", "pd", false, "upload / view nuclei results in projectdiscovery cloud (pdcp) UI dashboard"),
flagSet.StringVarP(&options.ScanUploadFile, "dashboard-upload", "pdu", "", "upload / view nuclei results file (jsonl) in projectdiscovery cloud (pdcp) UI dashboard"),
) )
flagSet.CreateGroup("Authentication", "Authentication", flagSet.CreateGroup("Authentication", "Authentication",

View File

@ -784,6 +784,52 @@ func (r *Runner) SaveResumeConfig(path string) error {
return os.WriteFile(path, data, permissionutil.ConfigFilePermission) return os.WriteFile(path, data, permissionutil.ConfigFilePermission)
} }
// upload existing scan results to cloud with progress
func UploadResultsToCloud(options *types.Options) error {
h := &pdcpauth.PDCPCredHandler{}
creds, err := h.GetCreds()
if err != nil {
return errors.Wrap(err, "could not get credentials for cloud upload")
}
ctx := context.TODO()
uploadWriter, err := pdcp.NewUploadWriter(ctx, creds)
if err != nil {
return errors.Wrap(err, "could not create upload writer")
}
if options.ScanID != "" {
_ = uploadWriter.SetScanID(options.ScanID)
}
if options.ScanName != "" {
uploadWriter.SetScanName(options.ScanName)
}
if options.TeamID != "" {
uploadWriter.SetTeamID(options.TeamID)
}
// Open file to count the number of results first
file, err := os.Open(options.ScanUploadFile)
if err != nil {
return errors.Wrap(err, "could not open scan upload file")
}
defer file.Close()
gologger.Info().Msgf("Uploading scan results to cloud dashboard from %s", options.ScanUploadFile)
dec := json.NewDecoder(file)
for dec.More() {
var r output.ResultEvent
err := dec.Decode(&r)
if err != nil {
gologger.Warning().Msgf("Could not decode jsonl: %s\n", err)
continue
}
if err = uploadWriter.Write(&r); err != nil {
gologger.Warning().Msgf("[%s] failed to upload: %s\n", r.TemplateID, err)
}
}
uploadWriter.Close()
return nil
}
type WalkFunc func(reflect.Value, reflect.StructField) type WalkFunc func(reflect.Value, reflect.StructField)
// Walk traverses a struct and executes a callback function on each value in the struct. // Walk traverses a struct and executes a callback function on each value in the struct.

View File

@ -384,6 +384,8 @@ type Options struct {
ScanID string ScanID string
// ScanName is the name of the scan to be uploaded // ScanName is the name of the scan to be uploaded
ScanName string ScanName string
// ScanUploadFile is the jsonl file to upload scan results to cloud
ScanUploadFile string
// TeamID is the team ID to use for cloud upload // TeamID is the team ID to use for cloud upload
TeamID string TeamID string
// JsConcurrency is the number of concurrent js routines to run // JsConcurrency is the number of concurrent js routines to run