mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-17 22:45:28 +00:00
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:
parent
8b1d9aa0d7
commit
bd6330f72a
@ -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",
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user