Path: blob/dev/pkg/protocols/utils/variables.go
2070 views
package utils12import (3"fmt"4"path"5"strings"67"github.com/projectdiscovery/gologger"8"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"9"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"10maputil "github.com/projectdiscovery/utils/maps"11urlutil "github.com/projectdiscovery/utils/url"12"github.com/weppos/publicsuffix-go/publicsuffix"13)1415// KnownVariables are the variables that are known to input requests16var KnownVariables maputil.Map[KnownVariable, string]1718func init() {19KnownVariables = maputil.Map[KnownVariable, string]{20BaseURL: "BaseURL",21RootURL: "RootURL",22Hostname: "Hostname",23Host: "Host",24Port: "Port",25Path: "Path",26Query: "Query",27File: "File",28Scheme: "Scheme",29Input: "Input",30Fqdn: "FQDN",31Rdn: "RDN",32Dn: "DN",33Tld: "TLD",34Sd: "SD",35}36}3738type KnownVariable uint163940const (41BaseURL KnownVariable = iota42RootURL43Hostname44Host45Port46Path47Query48File49Scheme50Input51Fqdn52Rdn53Dn54Tld55Sd56)5758// GenerateVariablesWithContextArgs will create default variables with context args59func GenerateVariablesWithContextArgs(input *contextargs.Context, trailingSlash bool) map[string]interface{} {60parsed, err := urlutil.Parse(input.MetaInput.Input)61if err != nil {62return nil63}64return GenerateVariables(parsed, trailingSlash, contextargs.GenerateVariables(input))65}6667// GenerateDNSVariables from a dns name68// This function is used by dns and ssl protocol to generate variables69func GenerateDNSVariables(domain string) map[string]interface{} {70parsed, err := publicsuffix.Parse(strings.TrimSuffix(domain, "."))71if err != nil {72return map[string]interface{}{"FQDN": domain}73}7475domainName := strings.Join([]string{parsed.SLD, parsed.TLD}, ".")76dnsVariables := make(map[string]interface{})77for k, v := range KnownVariables {78switch k {79case Fqdn:80dnsVariables[v] = domain81case Rdn:82dnsVariables[v] = domainName83case Dn:84dnsVariables[v] = parsed.SLD85case Tld:86dnsVariables[v] = parsed.TLD87case Sd:88dnsVariables[v] = parsed.TRD89}90}91return dnsVariables92}9394// GenerateVariables accepts string or *urlutil.URL object as input95// Returns the map of KnownVariables keys96// This function is used by http, headless, websocket, network and whois protocols to generate protocol variables97func GenerateVariables(input interface{}, removeTrailingSlash bool, additionalVars map[string]interface{}) map[string]interface{} {98var vars = make(map[string]interface{})99switch input := input.(type) {100case string:101parsed, err := urlutil.Parse(input)102if err != nil {103return map[string]interface{}{KnownVariables[Input]: input, KnownVariables[Hostname]: input}104}105vars = generateVariables(parsed, removeTrailingSlash)106case *urlutil.URL:107vars = generateVariables(input, removeTrailingSlash)108case urlutil.URL:109vars = generateVariables(&input, removeTrailingSlash)110default:111// return a non-fatal error112gologger.Error().Msgf("unknown type %T for input %v", input, input)113}114return generators.MergeMaps(vars, additionalVars)115}116117func generateVariables(inputURL *urlutil.URL, removeTrailingSlash bool) map[string]interface{} {118parsed := inputURL.Clone()119parsed.Params = urlutil.NewOrderedParams()120port := parsed.Port()121if port == "" {122switch parsed.Scheme {123case "https":124port = "443"125case "http":126port = "80"127}128}129if removeTrailingSlash {130parsed.Path = strings.TrimSuffix(parsed.Path, "/")131}132escapedPath := parsed.EscapedPath()133requestPath := path.Dir(escapedPath)134if requestPath == "." {135requestPath = ""136}137138base := path.Base(escapedPath)139if base == "." {140base = ""141}142143if parsed.Scheme == "ws" {144if values := urlutil.GetParams(parsed.URL.Query()); len(values) > 0 {145requestPath = escapedPath + "?" + values.Encode()146}147}148knownVariables := make(map[string]interface{})149for k, v := range KnownVariables {150switch k {151case BaseURL:152knownVariables[v] = parsed.String()153case RootURL:154if parsed.Scheme != "" {155knownVariables[v] = fmt.Sprintf("%s://%s", parsed.Scheme, parsed.Host)156} else {157knownVariables[v] = parsed.Host158}159case Hostname:160knownVariables[v] = parsed.Host161case Host:162knownVariables[v] = parsed.Hostname()163case Port:164knownVariables[v] = port165case Path:166knownVariables[v] = requestPath167case Query:168if queryParams := urlutil.GetParams(parsed.URL.Query()); len(queryParams) > 0 {169knownVariables[v] = "?" + queryParams.Encode()170} else {171knownVariables[v] = ""172}173case File:174knownVariables[v] = base175case Scheme:176knownVariables[v] = parsed.Scheme177case Input:178knownVariables[v] = parsed.String()179}180}181return generators.MergeMaps(knownVariables, GenerateDNSVariables(parsed.Hostname()))182}183184185