2020-06-24 22:23:37 +00:00
|
|
|
package runner
|
|
|
|
|
|
|
|
import (
|
2020-08-23 18:46:18 +00:00
|
|
|
"bufio"
|
2020-06-24 22:23:37 +00:00
|
|
|
"os"
|
|
|
|
"path"
|
|
|
|
"regexp"
|
2020-06-25 15:56:44 +00:00
|
|
|
"strings"
|
2020-07-07 12:54:00 +00:00
|
|
|
"time"
|
2020-06-24 22:23:37 +00:00
|
|
|
|
|
|
|
jsoniter "github.com/json-iterator/go"
|
|
|
|
)
|
|
|
|
|
|
|
|
// nucleiConfig contains some configuration options for nuclei
|
|
|
|
type nucleiConfig struct {
|
2020-07-07 12:54:00 +00:00
|
|
|
TemplatesDirectory string `json:"templates-directory,omitempty"`
|
|
|
|
CurrentVersion string `json:"current-version,omitempty"`
|
|
|
|
LastChecked time.Time `json:"last-checked,omitempty"`
|
2020-08-23 18:46:18 +00:00
|
|
|
|
2020-08-25 21:24:31 +00:00
|
|
|
// IgnorePaths ignores all the paths listed unless specified manually
|
|
|
|
IgnorePaths []string `json:"ignore-paths,omitempty"`
|
2020-06-24 22:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// nucleiConfigFilename is the filename of nuclei configuration file.
|
|
|
|
const nucleiConfigFilename = ".nuclei-config.json"
|
|
|
|
|
|
|
|
var reVersion = regexp.MustCompile(`\d+\.\d+\.\d+`)
|
|
|
|
|
|
|
|
// readConfiguration reads the nuclei configuration file from disk.
|
|
|
|
func (r *Runner) readConfiguration() (*nucleiConfig, error) {
|
|
|
|
home, err := os.UserHomeDir()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
templatesConfigFile := path.Join(home, nucleiConfigFilename)
|
|
|
|
file, err := os.Open(templatesConfigFile)
|
2020-08-25 21:24:31 +00:00
|
|
|
|
2020-06-24 22:23:37 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-08-25 21:24:31 +00:00
|
|
|
|
2020-06-24 22:23:37 +00:00
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
config := &nucleiConfig{}
|
2020-08-25 21:24:31 +00:00
|
|
|
err = jsoniter.NewDecoder(file).Decode(config)
|
|
|
|
|
|
|
|
if err != nil {
|
2020-06-24 22:23:37 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2020-08-25 21:24:31 +00:00
|
|
|
|
2020-06-24 22:23:37 +00:00
|
|
|
return config, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// readConfiguration reads the nuclei configuration file from disk.
|
|
|
|
func (r *Runner) writeConfiguration(config *nucleiConfig) error {
|
|
|
|
home, err := os.UserHomeDir()
|
2020-08-25 21:24:31 +00:00
|
|
|
|
2020-06-24 22:23:37 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-07-08 11:55:29 +00:00
|
|
|
config.LastChecked = time.Now()
|
2020-06-24 22:23:37 +00:00
|
|
|
templatesConfigFile := path.Join(home, nucleiConfigFilename)
|
2020-06-25 15:56:44 +00:00
|
|
|
file, err := os.OpenFile(templatesConfigFile, os.O_WRONLY|os.O_CREATE, 0777)
|
2020-08-25 21:24:31 +00:00
|
|
|
|
2020-06-24 22:23:37 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-08-25 21:24:31 +00:00
|
|
|
|
2020-06-24 22:23:37 +00:00
|
|
|
defer file.Close()
|
|
|
|
|
2020-08-25 21:24:31 +00:00
|
|
|
err = jsoniter.NewEncoder(file).Encode(config)
|
|
|
|
if err != nil {
|
2020-06-25 15:56:44 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-08-25 21:24:31 +00:00
|
|
|
|
2020-06-25 15:56:44 +00:00
|
|
|
return nil
|
2020-06-24 22:23:37 +00:00
|
|
|
}
|
|
|
|
|
2020-08-23 18:46:18 +00:00
|
|
|
const nucleiIgnoreFile = ".nuclei-ignore"
|
|
|
|
|
|
|
|
// readNucleiIgnoreFile reads the nuclei ignore file marking it in map
|
|
|
|
func (r *Runner) readNucleiIgnoreFile() {
|
|
|
|
file, err := os.Open(path.Join(r.templatesConfig.TemplatesDirectory, nucleiIgnoreFile))
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
|
|
for scanner.Scan() {
|
|
|
|
text := scanner.Text()
|
|
|
|
if text == "" {
|
|
|
|
continue
|
|
|
|
}
|
2020-08-26 18:05:31 +00:00
|
|
|
|
2020-08-25 21:24:31 +00:00
|
|
|
r.templatesConfig.IgnorePaths = append(r.templatesConfig.IgnorePaths, text)
|
2020-08-23 18:46:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// checkIfInNucleiIgnore checks if a path falls under nuclei-ignore rules.
|
|
|
|
func (r *Runner) checkIfInNucleiIgnore(item string) bool {
|
2020-08-23 19:49:27 +00:00
|
|
|
if r.templatesConfig == nil {
|
|
|
|
return false
|
|
|
|
}
|
2020-08-26 18:05:31 +00:00
|
|
|
|
2020-08-25 21:24:31 +00:00
|
|
|
for _, paths := range r.templatesConfig.IgnorePaths {
|
2020-08-23 18:46:18 +00:00
|
|
|
// If we have a path to ignore, check if it's in the item.
|
2020-08-23 18:58:59 +00:00
|
|
|
if paths[len(paths)-1] == '/' {
|
2020-08-23 18:46:18 +00:00
|
|
|
if strings.Contains(item, paths) {
|
|
|
|
return true
|
|
|
|
}
|
2020-08-26 18:05:31 +00:00
|
|
|
|
2020-08-23 18:46:18 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
// Check for file based extension in ignores
|
|
|
|
if strings.HasSuffix(item, paths) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
2020-08-26 18:05:31 +00:00
|
|
|
|
2020-08-23 18:46:18 +00:00
|
|
|
return false
|
|
|
|
}
|